[PATCH] W1: w1_netlink: New init/fini netlink callbacks.
[linux-2.6/verdex.git] / drivers / scsi / advansys.c
blob37ec5411e325578ff572429e4868efa44884789d
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 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 '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/config.h>
758 #include <linux/module.h>
760 #if defined(CONFIG_X86) && !defined(CONFIG_ISA)
761 #define CONFIG_ISA
762 #endif /* CONFIG_X86 && !CONFIG_ISA */
764 #include <linux/string.h>
765 #include <linux/kernel.h>
766 #include <linux/types.h>
767 #include <linux/ioport.h>
768 #include <linux/interrupt.h>
769 #include <linux/delay.h>
770 #include <linux/slab.h>
771 #include <linux/mm.h>
772 #include <linux/proc_fs.h>
773 #include <linux/init.h>
774 #include <linux/blkdev.h>
775 #include <linux/stat.h>
776 #include <linux/spinlock.h>
777 #include <linux/dma-mapping.h>
779 #include <asm/io.h>
780 #include <asm/system.h>
781 #include <asm/dma.h>
783 /* FIXME: (by jejb@steeleye.com) This warning is present for two
784 * reasons:
786 * 1) This driver badly needs converting to the correct driver model
787 * probing API
789 * 2) Although all of the necessary command mapping places have the
790 * appropriate dma_map.. APIs, the driver still processes its internal
791 * queue using bus_to_virt() and virt_to_bus() which are illegal under
792 * the API. The entire queue processing structure will need to be
793 * altered to fix this.
795 #warning this driver is still not properly converted to the DMA API
797 #include <scsi/scsi_cmnd.h>
798 #include <scsi/scsi_device.h>
799 #include <scsi/scsi_tcq.h>
800 #include <scsi/scsi.h>
801 #include <scsi/scsi_host.h>
802 #include "advansys.h"
803 #ifdef CONFIG_PCI
804 #include <linux/pci.h>
805 #endif /* CONFIG_PCI */
809 * --- Driver Options
812 /* Enable driver assertions. */
813 #define ADVANSYS_ASSERT
815 /* Enable driver /proc statistics. */
816 #define ADVANSYS_STATS
818 /* Enable driver tracing. */
819 /* #define ADVANSYS_DEBUG */
823 * --- Debugging Header
826 #ifdef ADVANSYS_DEBUG
827 #define STATIC
828 #else /* ADVANSYS_DEBUG */
829 #define STATIC static
830 #endif /* ADVANSYS_DEBUG */
834 * --- Asc Library Constants and Macros
837 #define ASC_LIB_VERSION_MAJOR 1
838 #define ASC_LIB_VERSION_MINOR 24
839 #define ASC_LIB_SERIAL_NUMBER 123
842 * Portable Data Types
844 * Any instance where a 32-bit long or pointer type is assumed
845 * for precision or HW defined structures, the following define
846 * types must be used. In Linux the char, short, and int types
847 * are all consistent at 8, 16, and 32 bits respectively. Pointers
848 * and long types are 64 bits on Alpha and UltraSPARC.
850 #define ASC_PADDR __u32 /* Physical/Bus address data type. */
851 #define ASC_VADDR __u32 /* Virtual address data type. */
852 #define ASC_DCNT __u32 /* Unsigned Data count type. */
853 #define ASC_SDCNT __s32 /* Signed Data count type. */
856 * These macros are used to convert a virtual address to a
857 * 32-bit value. This currently can be used on Linux Alpha
858 * which uses 64-bit virtual address but a 32-bit bus address.
859 * This is likely to break in the future, but doing this now
860 * will give us time to change the HW and FW to handle 64-bit
861 * addresses.
863 #define ASC_VADDR_TO_U32 virt_to_bus
864 #define ASC_U32_TO_VADDR bus_to_virt
866 typedef unsigned char uchar;
868 #ifndef TRUE
869 #define TRUE (1)
870 #endif
871 #ifndef FALSE
872 #define FALSE (0)
873 #endif
875 #define EOF (-1)
876 #define ERR (-1)
877 #define UW_ERR (uint)(0xFFFF)
878 #define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
879 #define AscPCIConfigVendorIDRegister 0x0000
880 #define AscPCIConfigDeviceIDRegister 0x0002
881 #define AscPCIConfigCommandRegister 0x0004
882 #define AscPCIConfigStatusRegister 0x0006
883 #define AscPCIConfigRevisionIDRegister 0x0008
884 #define AscPCIConfigCacheSize 0x000C
885 #define AscPCIConfigLatencyTimer 0x000D
886 #define AscPCIIOBaseRegister 0x0010
887 #define AscPCICmdRegBits_IOMemBusMaster 0x0007
888 #define ASC_PCI_ID2BUS(id) ((id) & 0xFF)
889 #define ASC_PCI_ID2DEV(id) (((id) >> 11) & 0x1F)
890 #define ASC_PCI_ID2FUNC(id) (((id) >> 8) & 0x7)
891 #define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
892 #define ASC_PCI_VENDORID 0x10CD
893 #define ASC_PCI_DEVICEID_1200A 0x1100
894 #define ASC_PCI_DEVICEID_1200B 0x1200
895 #define ASC_PCI_DEVICEID_ULTRA 0x1300
896 #define ASC_PCI_REVISION_3150 0x02
897 #define ASC_PCI_REVISION_3050 0x03
899 #define ASC_DVCLIB_CALL_DONE (1)
900 #define ASC_DVCLIB_CALL_FAILED (0)
901 #define ASC_DVCLIB_CALL_ERROR (-1)
904 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
905 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
906 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
907 * SRB structure.
909 #define CC_VERY_LONG_SG_LIST 0
910 #define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
912 #define PortAddr unsigned short /* port address size */
913 #define inp(port) inb(port)
914 #define outp(port, byte) outb((byte), (port))
916 #define inpw(port) inw(port)
917 #define outpw(port, word) outw((word), (port))
919 #define ASC_MAX_SG_QUEUE 7
920 #define ASC_MAX_SG_LIST 255
922 #define ASC_CS_TYPE unsigned short
924 #define ASC_IS_ISA (0x0001)
925 #define ASC_IS_ISAPNP (0x0081)
926 #define ASC_IS_EISA (0x0002)
927 #define ASC_IS_PCI (0x0004)
928 #define ASC_IS_PCI_ULTRA (0x0104)
929 #define ASC_IS_PCMCIA (0x0008)
930 #define ASC_IS_MCA (0x0020)
931 #define ASC_IS_VL (0x0040)
932 #define ASC_ISA_PNP_PORT_ADDR (0x279)
933 #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
934 #define ASC_IS_WIDESCSI_16 (0x0100)
935 #define ASC_IS_WIDESCSI_32 (0x0200)
936 #define ASC_IS_BIG_ENDIAN (0x8000)
937 #define ASC_CHIP_MIN_VER_VL (0x01)
938 #define ASC_CHIP_MAX_VER_VL (0x07)
939 #define ASC_CHIP_MIN_VER_PCI (0x09)
940 #define ASC_CHIP_MAX_VER_PCI (0x0F)
941 #define ASC_CHIP_VER_PCI_BIT (0x08)
942 #define ASC_CHIP_MIN_VER_ISA (0x11)
943 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
944 #define ASC_CHIP_MAX_VER_ISA (0x27)
945 #define ASC_CHIP_VER_ISA_BIT (0x30)
946 #define ASC_CHIP_VER_ISAPNP_BIT (0x20)
947 #define ASC_CHIP_VER_ASYN_BUG (0x21)
948 #define ASC_CHIP_VER_PCI 0x08
949 #define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
950 #define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
951 #define ASC_CHIP_MIN_VER_EISA (0x41)
952 #define ASC_CHIP_MAX_VER_EISA (0x47)
953 #define ASC_CHIP_VER_EISA_BIT (0x40)
954 #define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
955 #define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER 0x21
956 #define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER 0x0A
957 #define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL)
958 #define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
959 #define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL)
960 #define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
961 #define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL)
962 #define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
963 #define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL)
964 #define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL)
966 #define ASC_SCSI_ID_BITS 3
967 #define ASC_SCSI_TIX_TYPE uchar
968 #define ASC_ALL_DEVICE_BIT_SET 0xFF
969 #define ASC_SCSI_BIT_ID_TYPE uchar
970 #define ASC_MAX_TID 7
971 #define ASC_MAX_LUN 7
972 #define ASC_SCSI_WIDTH_BIT_SET 0xFF
973 #define ASC_MAX_SENSE_LEN 32
974 #define ASC_MIN_SENSE_LEN 14
975 #define ASC_MAX_CDB_LEN 12
976 #define ASC_SCSI_RESET_HOLD_TIME_US 60
978 #define ADV_INQ_CLOCKING_ST_ONLY 0x0
979 #define ADV_INQ_CLOCKING_DT_ONLY 0x1
980 #define ADV_INQ_CLOCKING_ST_AND_DT 0x3
983 * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
984 * and CmdDt (Command Support Data) field bit definitions.
986 #define ADV_INQ_RTN_VPD_AND_CMDDT 0x3
987 #define ADV_INQ_RTN_CMDDT_FOR_OP_CODE 0x2
988 #define ADV_INQ_RTN_VPD_FOR_PG_CODE 0x1
989 #define ADV_INQ_RTN_STD_INQUIRY_DATA 0x0
991 #define ASC_SCSIDIR_NOCHK 0x00
992 #define ASC_SCSIDIR_T2H 0x08
993 #define ASC_SCSIDIR_H2T 0x10
994 #define ASC_SCSIDIR_NODATA 0x18
995 #define SCSI_ASC_NOMEDIA 0x3A
996 #define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4))
997 #define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F))
998 #define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13))
999 #define PUT_CDB1(x) ((uchar)((uint)(x) >> 8))
1000 #define MS_CMD_DONE 0x00
1001 #define MS_EXTEND 0x01
1002 #define MS_SDTR_LEN 0x03
1003 #define MS_SDTR_CODE 0x01
1004 #define MS_WDTR_LEN 0x02
1005 #define MS_WDTR_CODE 0x03
1006 #define MS_MDP_LEN 0x05
1007 #define MS_MDP_CODE 0x00
1010 * Inquiry data structure and bitfield macros
1012 * Only quantities of more than 1 bit are shifted, since the others are
1013 * just tested for true or false. C bitfields aren't portable between big
1014 * and little-endian platforms so they are not used.
1017 #define ASC_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f)
1018 #define ASC_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5)
1019 #define ASC_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f)
1020 #define ASC_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80)
1021 #define ASC_INQ_ANSI_VER(inq) ((inq)->ver & 0x07)
1022 #define ASC_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3)
1023 #define ASC_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6)
1024 #define ASC_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f)
1025 #define ASC_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40)
1026 #define ASC_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80)
1027 #define ASC_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01)
1028 #define ASC_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02)
1029 #define ASC_INQ_LINK_CMD(inq) ((inq)->flags & 0x08)
1030 #define ASC_INQ_SYNC(inq) ((inq)->flags & 0x10)
1031 #define ASC_INQ_WIDE16(inq) ((inq)->flags & 0x20)
1032 #define ASC_INQ_WIDE32(inq) ((inq)->flags & 0x40)
1033 #define ASC_INQ_REL_ADDR(inq) ((inq)->flags & 0x80)
1034 #define ASC_INQ_INFO_UNIT(inq) ((inq)->info & 0x01)
1035 #define ASC_INQ_QUICK_ARB(inq) ((inq)->info & 0x02)
1036 #define ASC_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2)
1038 typedef struct {
1039 uchar periph;
1040 uchar devtype;
1041 uchar ver;
1042 uchar byte3;
1043 uchar add_len;
1044 uchar res1;
1045 uchar res2;
1046 uchar flags;
1047 uchar vendor_id[8];
1048 uchar product_id[16];
1049 uchar product_rev_level[4];
1050 } ASC_SCSI_INQUIRY;
1052 #define ASC_SG_LIST_PER_Q 7
1053 #define QS_FREE 0x00
1054 #define QS_READY 0x01
1055 #define QS_DISC1 0x02
1056 #define QS_DISC2 0x04
1057 #define QS_BUSY 0x08
1058 #define QS_ABORTED 0x40
1059 #define QS_DONE 0x80
1060 #define QC_NO_CALLBACK 0x01
1061 #define QC_SG_SWAP_QUEUE 0x02
1062 #define QC_SG_HEAD 0x04
1063 #define QC_DATA_IN 0x08
1064 #define QC_DATA_OUT 0x10
1065 #define QC_URGENT 0x20
1066 #define QC_MSG_OUT 0x40
1067 #define QC_REQ_SENSE 0x80
1068 #define QCSG_SG_XFER_LIST 0x02
1069 #define QCSG_SG_XFER_MORE 0x04
1070 #define QCSG_SG_XFER_END 0x08
1071 #define QD_IN_PROGRESS 0x00
1072 #define QD_NO_ERROR 0x01
1073 #define QD_ABORTED_BY_HOST 0x02
1074 #define QD_WITH_ERROR 0x04
1075 #define QD_INVALID_REQUEST 0x80
1076 #define QD_INVALID_HOST_NUM 0x81
1077 #define QD_INVALID_DEVICE 0x82
1078 #define QD_ERR_INTERNAL 0xFF
1079 #define QHSTA_NO_ERROR 0x00
1080 #define QHSTA_M_SEL_TIMEOUT 0x11
1081 #define QHSTA_M_DATA_OVER_RUN 0x12
1082 #define QHSTA_M_DATA_UNDER_RUN 0x12
1083 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
1084 #define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
1085 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1086 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
1087 #define QHSTA_D_HOST_ABORT_FAILED 0x23
1088 #define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
1089 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1090 #define QHSTA_D_ASPI_NO_BUF_POOL 0x26
1091 #define QHSTA_M_WTM_TIMEOUT 0x41
1092 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
1093 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
1094 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1095 #define QHSTA_M_TARGET_STATUS_BUSY 0x45
1096 #define QHSTA_M_BAD_TAG_CODE 0x46
1097 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
1098 #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1099 #define QHSTA_D_LRAM_CMP_ERROR 0x81
1100 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1101 #define ASC_FLAG_SCSIQ_REQ 0x01
1102 #define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
1103 #define ASC_FLAG_BIOS_ASYNC_IO 0x04
1104 #define ASC_FLAG_SRB_LINEAR_ADDR 0x08
1105 #define ASC_FLAG_WIN16 0x10
1106 #define ASC_FLAG_WIN32 0x20
1107 #define ASC_FLAG_ISA_OVER_16MB 0x40
1108 #define ASC_FLAG_DOS_VM_CALLBACK 0x80
1109 #define ASC_TAG_FLAG_EXTRA_BYTES 0x10
1110 #define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
1111 #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
1112 #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1113 #define ASC_SCSIQ_CPY_BEG 4
1114 #define ASC_SCSIQ_SGHD_CPY_BEG 2
1115 #define ASC_SCSIQ_B_FWD 0
1116 #define ASC_SCSIQ_B_BWD 1
1117 #define ASC_SCSIQ_B_STATUS 2
1118 #define ASC_SCSIQ_B_QNO 3
1119 #define ASC_SCSIQ_B_CNTL 4
1120 #define ASC_SCSIQ_B_SG_QUEUE_CNT 5
1121 #define ASC_SCSIQ_D_DATA_ADDR 8
1122 #define ASC_SCSIQ_D_DATA_CNT 12
1123 #define ASC_SCSIQ_B_SENSE_LEN 20
1124 #define ASC_SCSIQ_DONE_INFO_BEG 22
1125 #define ASC_SCSIQ_D_SRBPTR 22
1126 #define ASC_SCSIQ_B_TARGET_IX 26
1127 #define ASC_SCSIQ_B_CDB_LEN 28
1128 #define ASC_SCSIQ_B_TAG_CODE 29
1129 #define ASC_SCSIQ_W_VM_ID 30
1130 #define ASC_SCSIQ_DONE_STATUS 32
1131 #define ASC_SCSIQ_HOST_STATUS 33
1132 #define ASC_SCSIQ_SCSI_STATUS 34
1133 #define ASC_SCSIQ_CDB_BEG 36
1134 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1135 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
1136 #define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
1137 #define ASC_SCSIQ_B_SG_WK_QP 49
1138 #define ASC_SCSIQ_B_SG_WK_IX 50
1139 #define ASC_SCSIQ_W_ALT_DC1 52
1140 #define ASC_SCSIQ_B_LIST_CNT 6
1141 #define ASC_SCSIQ_B_CUR_LIST_CNT 7
1142 #define ASC_SGQ_B_SG_CNTL 4
1143 #define ASC_SGQ_B_SG_HEAD_QP 5
1144 #define ASC_SGQ_B_SG_LIST_CNT 6
1145 #define ASC_SGQ_B_SG_CUR_LIST_CNT 7
1146 #define ASC_SGQ_LIST_BEG 8
1147 #define ASC_DEF_SCSI1_QNG 4
1148 #define ASC_MAX_SCSI1_QNG 4
1149 #define ASC_DEF_SCSI2_QNG 16
1150 #define ASC_MAX_SCSI2_QNG 32
1151 #define ASC_TAG_CODE_MASK 0x23
1152 #define ASC_STOP_REQ_RISC_STOP 0x01
1153 #define ASC_STOP_ACK_RISC_STOP 0x03
1154 #define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
1155 #define ASC_STOP_CLEAN_UP_DISC_Q 0x20
1156 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1157 #define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1158 #define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1159 #define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
1160 #define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
1161 #define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
1162 #define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1163 #define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
1165 typedef struct asc_scsiq_1 {
1166 uchar status;
1167 uchar q_no;
1168 uchar cntl;
1169 uchar sg_queue_cnt;
1170 uchar target_id;
1171 uchar target_lun;
1172 ASC_PADDR data_addr;
1173 ASC_DCNT data_cnt;
1174 ASC_PADDR sense_addr;
1175 uchar sense_len;
1176 uchar extra_bytes;
1177 } ASC_SCSIQ_1;
1179 typedef struct asc_scsiq_2 {
1180 ASC_VADDR srb_ptr;
1181 uchar target_ix;
1182 uchar flag;
1183 uchar cdb_len;
1184 uchar tag_code;
1185 ushort vm_id;
1186 } ASC_SCSIQ_2;
1188 typedef struct asc_scsiq_3 {
1189 uchar done_stat;
1190 uchar host_stat;
1191 uchar scsi_stat;
1192 uchar scsi_msg;
1193 } ASC_SCSIQ_3;
1195 typedef struct asc_scsiq_4 {
1196 uchar cdb[ASC_MAX_CDB_LEN];
1197 uchar y_first_sg_list_qp;
1198 uchar y_working_sg_qp;
1199 uchar y_working_sg_ix;
1200 uchar y_res;
1201 ushort x_req_count;
1202 ushort x_reconnect_rtn;
1203 ASC_PADDR x_saved_data_addr;
1204 ASC_DCNT x_saved_data_cnt;
1205 } ASC_SCSIQ_4;
1207 typedef struct asc_q_done_info {
1208 ASC_SCSIQ_2 d2;
1209 ASC_SCSIQ_3 d3;
1210 uchar q_status;
1211 uchar q_no;
1212 uchar cntl;
1213 uchar sense_len;
1214 uchar extra_bytes;
1215 uchar res;
1216 ASC_DCNT remain_bytes;
1217 } ASC_QDONE_INFO;
1219 typedef struct asc_sg_list {
1220 ASC_PADDR addr;
1221 ASC_DCNT bytes;
1222 } ASC_SG_LIST;
1224 typedef struct asc_sg_head {
1225 ushort entry_cnt;
1226 ushort queue_cnt;
1227 ushort entry_to_copy;
1228 ushort res;
1229 ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1230 } ASC_SG_HEAD;
1232 #define ASC_MIN_SG_LIST 2
1234 typedef struct asc_min_sg_head {
1235 ushort entry_cnt;
1236 ushort queue_cnt;
1237 ushort entry_to_copy;
1238 ushort res;
1239 ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
1240 } ASC_MIN_SG_HEAD;
1242 #define QCX_SORT (0x0001)
1243 #define QCX_COALEASE (0x0002)
1245 typedef struct asc_scsi_q {
1246 ASC_SCSIQ_1 q1;
1247 ASC_SCSIQ_2 q2;
1248 uchar *cdbptr;
1249 ASC_SG_HEAD *sg_head;
1250 ushort remain_sg_entry_cnt;
1251 ushort next_sg_index;
1252 } ASC_SCSI_Q;
1254 typedef struct asc_scsi_req_q {
1255 ASC_SCSIQ_1 r1;
1256 ASC_SCSIQ_2 r2;
1257 uchar *cdbptr;
1258 ASC_SG_HEAD *sg_head;
1259 uchar *sense_ptr;
1260 ASC_SCSIQ_3 r3;
1261 uchar cdb[ASC_MAX_CDB_LEN];
1262 uchar sense[ASC_MIN_SENSE_LEN];
1263 } ASC_SCSI_REQ_Q;
1265 typedef struct asc_scsi_bios_req_q {
1266 ASC_SCSIQ_1 r1;
1267 ASC_SCSIQ_2 r2;
1268 uchar *cdbptr;
1269 ASC_SG_HEAD *sg_head;
1270 uchar *sense_ptr;
1271 ASC_SCSIQ_3 r3;
1272 uchar cdb[ASC_MAX_CDB_LEN];
1273 uchar sense[ASC_MIN_SENSE_LEN];
1274 } ASC_SCSI_BIOS_REQ_Q;
1276 typedef struct asc_risc_q {
1277 uchar fwd;
1278 uchar bwd;
1279 ASC_SCSIQ_1 i1;
1280 ASC_SCSIQ_2 i2;
1281 ASC_SCSIQ_3 i3;
1282 ASC_SCSIQ_4 i4;
1283 } ASC_RISC_Q;
1285 typedef struct asc_sg_list_q {
1286 uchar seq_no;
1287 uchar q_no;
1288 uchar cntl;
1289 uchar sg_head_qp;
1290 uchar sg_list_cnt;
1291 uchar sg_cur_list_cnt;
1292 } ASC_SG_LIST_Q;
1294 typedef struct asc_risc_sg_list_q {
1295 uchar fwd;
1296 uchar bwd;
1297 ASC_SG_LIST_Q sg;
1298 ASC_SG_LIST sg_list[7];
1299 } ASC_RISC_SG_LIST_Q;
1301 #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL
1302 #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024
1303 #define ASCQ_ERR_NO_ERROR 0
1304 #define ASCQ_ERR_IO_NOT_FOUND 1
1305 #define ASCQ_ERR_LOCAL_MEM 2
1306 #define ASCQ_ERR_CHKSUM 3
1307 #define ASCQ_ERR_START_CHIP 4
1308 #define ASCQ_ERR_INT_TARGET_ID 5
1309 #define ASCQ_ERR_INT_LOCAL_MEM 6
1310 #define ASCQ_ERR_HALT_RISC 7
1311 #define ASCQ_ERR_GET_ASPI_ENTRY 8
1312 #define ASCQ_ERR_CLOSE_ASPI 9
1313 #define ASCQ_ERR_HOST_INQUIRY 0x0A
1314 #define ASCQ_ERR_SAVED_SRB_BAD 0x0B
1315 #define ASCQ_ERR_QCNTL_SG_LIST 0x0C
1316 #define ASCQ_ERR_Q_STATUS 0x0D
1317 #define ASCQ_ERR_WR_SCSIQ 0x0E
1318 #define ASCQ_ERR_PC_ADDR 0x0F
1319 #define ASCQ_ERR_SYN_OFFSET 0x10
1320 #define ASCQ_ERR_SYN_XFER_TIME 0x11
1321 #define ASCQ_ERR_LOCK_DMA 0x12
1322 #define ASCQ_ERR_UNLOCK_DMA 0x13
1323 #define ASCQ_ERR_VDS_CHK_INSTALL 0x14
1324 #define ASCQ_ERR_MICRO_CODE_HALT 0x15
1325 #define ASCQ_ERR_SET_LRAM_ADDR 0x16
1326 #define ASCQ_ERR_CUR_QNG 0x17
1327 #define ASCQ_ERR_SG_Q_LINKS 0x18
1328 #define ASCQ_ERR_SCSIQ_PTR 0x19
1329 #define ASCQ_ERR_ISR_RE_ENTRY 0x1A
1330 #define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
1331 #define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
1332 #define ASCQ_ERR_SG_LIST_ODD_ADDRESS 0x1D
1333 #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1334 #define ASCQ_ERR_SCSIQ_NULL_PTR 0x1F
1335 #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR 0x20
1336 #define ASCQ_ERR_GET_NUM_OF_FREE_Q 0x21
1337 #define ASCQ_ERR_SEND_SCSI_Q 0x22
1338 #define ASCQ_ERR_HOST_REQ_RISC_HALT 0x23
1339 #define ASCQ_ERR_RESET_SDTR 0x24
1342 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
1344 #define ASC_WARN_NO_ERROR 0x0000
1345 #define ASC_WARN_IO_PORT_ROTATE 0x0001
1346 #define ASC_WARN_EEPROM_CHKSUM 0x0002
1347 #define ASC_WARN_IRQ_MODIFIED 0x0004
1348 #define ASC_WARN_AUTO_CONFIG 0x0008
1349 #define ASC_WARN_CMD_QNG_CONFLICT 0x0010
1350 #define ASC_WARN_EEPROM_RECOVER 0x0020
1351 #define ASC_WARN_CFG_MSW_RECOVER 0x0040
1352 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1355 * Error code values are set in ASC_DVC_VAR 'err_code'.
1357 #define ASC_IERR_WRITE_EEPROM 0x0001
1358 #define ASC_IERR_MCODE_CHKSUM 0x0002
1359 #define ASC_IERR_SET_PC_ADDR 0x0004
1360 #define ASC_IERR_START_STOP_CHIP 0x0008
1361 #define ASC_IERR_IRQ_NO 0x0010
1362 #define ASC_IERR_SET_IRQ_NO 0x0020
1363 #define ASC_IERR_CHIP_VERSION 0x0040
1364 #define ASC_IERR_SET_SCSI_ID 0x0080
1365 #define ASC_IERR_GET_PHY_ADDR 0x0100
1366 #define ASC_IERR_BAD_SIGNATURE 0x0200
1367 #define ASC_IERR_NO_BUS_TYPE 0x0400
1368 #define ASC_IERR_SCAM 0x0800
1369 #define ASC_IERR_SET_SDTR 0x1000
1370 #define ASC_IERR_RW_LRAM 0x8000
1372 #define ASC_DEF_IRQ_NO 10
1373 #define ASC_MAX_IRQ_NO 15
1374 #define ASC_MIN_IRQ_NO 10
1375 #define ASC_MIN_REMAIN_Q (0x02)
1376 #define ASC_DEF_MAX_TOTAL_QNG (0xF0)
1377 #define ASC_MIN_TAG_Q_PER_DVC (0x04)
1378 #define ASC_DEF_TAG_Q_PER_DVC (0x04)
1379 #define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q
1380 #define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1381 #define ASC_MAX_TOTAL_QNG 240
1382 #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1383 #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
1384 #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
1385 #define ASC_MAX_INRAM_TAG_QNG 16
1386 #define ASC_IOADR_TABLE_MAX_IX 11
1387 #define ASC_IOADR_GAP 0x10
1388 #define ASC_SEARCH_IOP_GAP 0x10
1389 #define ASC_MIN_IOP_ADDR (PortAddr)0x0100
1390 #define ASC_MAX_IOP_ADDR (PortAddr)0x3F0
1391 #define ASC_IOADR_1 (PortAddr)0x0110
1392 #define ASC_IOADR_2 (PortAddr)0x0130
1393 #define ASC_IOADR_3 (PortAddr)0x0150
1394 #define ASC_IOADR_4 (PortAddr)0x0190
1395 #define ASC_IOADR_5 (PortAddr)0x0210
1396 #define ASC_IOADR_6 (PortAddr)0x0230
1397 #define ASC_IOADR_7 (PortAddr)0x0250
1398 #define ASC_IOADR_8 (PortAddr)0x0330
1399 #define ASC_IOADR_DEF ASC_IOADR_8
1400 #define ASC_LIB_SCSIQ_WK_SP 256
1401 #define ASC_MAX_SYN_XFER_NO 16
1402 #define ASC_SYN_MAX_OFFSET 0x0F
1403 #define ASC_DEF_SDTR_OFFSET 0x0F
1404 #define ASC_DEF_SDTR_INDEX 0x00
1405 #define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
1406 #define SYN_XFER_NS_0 25
1407 #define SYN_XFER_NS_1 30
1408 #define SYN_XFER_NS_2 35
1409 #define SYN_XFER_NS_3 40
1410 #define SYN_XFER_NS_4 50
1411 #define SYN_XFER_NS_5 60
1412 #define SYN_XFER_NS_6 70
1413 #define SYN_XFER_NS_7 85
1414 #define SYN_ULTRA_XFER_NS_0 12
1415 #define SYN_ULTRA_XFER_NS_1 19
1416 #define SYN_ULTRA_XFER_NS_2 25
1417 #define SYN_ULTRA_XFER_NS_3 32
1418 #define SYN_ULTRA_XFER_NS_4 38
1419 #define SYN_ULTRA_XFER_NS_5 44
1420 #define SYN_ULTRA_XFER_NS_6 50
1421 #define SYN_ULTRA_XFER_NS_7 57
1422 #define SYN_ULTRA_XFER_NS_8 63
1423 #define SYN_ULTRA_XFER_NS_9 69
1424 #define SYN_ULTRA_XFER_NS_10 75
1425 #define SYN_ULTRA_XFER_NS_11 82
1426 #define SYN_ULTRA_XFER_NS_12 88
1427 #define SYN_ULTRA_XFER_NS_13 94
1428 #define SYN_ULTRA_XFER_NS_14 100
1429 #define SYN_ULTRA_XFER_NS_15 107
1431 typedef struct ext_msg {
1432 uchar msg_type;
1433 uchar msg_len;
1434 uchar msg_req;
1435 union {
1436 struct {
1437 uchar sdtr_xfer_period;
1438 uchar sdtr_req_ack_offset;
1439 } sdtr;
1440 struct {
1441 uchar wdtr_width;
1442 } wdtr;
1443 struct {
1444 uchar mdp_b3;
1445 uchar mdp_b2;
1446 uchar mdp_b1;
1447 uchar mdp_b0;
1448 } mdp;
1449 } u_ext_msg;
1450 uchar res;
1451 } EXT_MSG;
1453 #define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
1454 #define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
1455 #define wdtr_width u_ext_msg.wdtr.wdtr_width
1456 #define mdp_b3 u_ext_msg.mdp_b3
1457 #define mdp_b2 u_ext_msg.mdp_b2
1458 #define mdp_b1 u_ext_msg.mdp_b1
1459 #define mdp_b0 u_ext_msg.mdp_b0
1461 typedef struct asc_dvc_cfg {
1462 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1463 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1464 ASC_SCSI_BIT_ID_TYPE disc_enable;
1465 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1466 uchar chip_scsi_id;
1467 uchar isa_dma_speed;
1468 uchar isa_dma_channel;
1469 uchar chip_version;
1470 ushort lib_serial_no;
1471 ushort lib_version;
1472 ushort mcode_date;
1473 ushort mcode_version;
1474 uchar max_tag_qng[ASC_MAX_TID + 1];
1475 uchar *overrun_buf;
1476 uchar sdtr_period_offset[ASC_MAX_TID + 1];
1477 ushort pci_slot_info;
1478 uchar adapter_info[6];
1479 struct device *dev;
1480 } ASC_DVC_CFG;
1482 #define ASC_DEF_DVC_CNTL 0xFFFF
1483 #define ASC_DEF_CHIP_SCSI_ID 7
1484 #define ASC_DEF_ISA_DMA_SPEED 4
1485 #define ASC_INIT_STATE_NULL 0x0000
1486 #define ASC_INIT_STATE_BEG_GET_CFG 0x0001
1487 #define ASC_INIT_STATE_END_GET_CFG 0x0002
1488 #define ASC_INIT_STATE_BEG_SET_CFG 0x0004
1489 #define ASC_INIT_STATE_END_SET_CFG 0x0008
1490 #define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
1491 #define ASC_INIT_STATE_END_LOAD_MC 0x0020
1492 #define ASC_INIT_STATE_BEG_INQUIRY 0x0040
1493 #define ASC_INIT_STATE_END_INQUIRY 0x0080
1494 #define ASC_INIT_RESET_SCSI_DONE 0x0100
1495 #define ASC_INIT_STATE_WITHOUT_EEP 0x8000
1496 #define ASC_PCI_DEVICE_ID_REV_A 0x1100
1497 #define ASC_PCI_DEVICE_ID_REV_B 0x1200
1498 #define ASC_BUG_FIX_IF_NOT_DWB 0x0001
1499 #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
1500 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1501 #define ASC_MIN_TAGGED_CMD 7
1502 #define ASC_MAX_SCSI_RESET_WAIT 30
1504 struct asc_dvc_var; /* Forward Declaration. */
1506 typedef void (* ASC_ISR_CALLBACK)(struct asc_dvc_var *, ASC_QDONE_INFO *);
1507 typedef int (* ASC_EXE_CALLBACK)(struct asc_dvc_var *, ASC_SCSI_Q *);
1509 typedef struct asc_dvc_var {
1510 PortAddr iop_base;
1511 ushort err_code;
1512 ushort dvc_cntl;
1513 ushort bug_fix_cntl;
1514 ushort bus_type;
1515 ASC_ISR_CALLBACK isr_callback;
1516 ASC_EXE_CALLBACK exe_callback;
1517 ASC_SCSI_BIT_ID_TYPE init_sdtr;
1518 ASC_SCSI_BIT_ID_TYPE sdtr_done;
1519 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1520 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1521 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1522 ASC_SCSI_BIT_ID_TYPE start_motor;
1523 uchar scsi_reset_wait;
1524 uchar chip_no;
1525 char is_in_int;
1526 uchar max_total_qng;
1527 uchar cur_total_qng;
1528 uchar in_critical_cnt;
1529 uchar irq_no;
1530 uchar last_q_shortage;
1531 ushort init_state;
1532 uchar cur_dvc_qng[ASC_MAX_TID + 1];
1533 uchar max_dvc_qng[ASC_MAX_TID + 1];
1534 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
1535 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
1536 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1537 ASC_DVC_CFG *cfg;
1538 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1539 char redo_scam;
1540 ushort res2;
1541 uchar dos_int13_table[ASC_MAX_TID + 1];
1542 ASC_DCNT max_dma_count;
1543 ASC_SCSI_BIT_ID_TYPE no_scam;
1544 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1545 uchar max_sdtr_index;
1546 uchar host_init_sdtr_index;
1547 struct asc_board *drv_ptr;
1548 ASC_DCNT uc_break;
1549 } ASC_DVC_VAR;
1551 typedef struct asc_dvc_inq_info {
1552 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1553 } ASC_DVC_INQ_INFO;
1555 typedef struct asc_cap_info {
1556 ASC_DCNT lba;
1557 ASC_DCNT blk_size;
1558 } ASC_CAP_INFO;
1560 typedef struct asc_cap_info_array {
1561 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1562 } ASC_CAP_INFO_ARRAY;
1564 #define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
1565 #define ASC_MCNTL_NULL_TARGET (ushort)0x0002
1566 #define ASC_CNTL_INITIATOR (ushort)0x0001
1567 #define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
1568 #define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
1569 #define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
1570 #define ASC_CNTL_NO_SCAM (ushort)0x0010
1571 #define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
1572 #define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
1573 #define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
1574 #define ASC_CNTL_RESET_SCSI (ushort)0x0200
1575 #define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
1576 #define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
1577 #define ASC_CNTL_SCSI_PARITY (ushort)0x1000
1578 #define ASC_CNTL_BURST_MODE (ushort)0x2000
1579 #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1580 #define ASC_EEP_DVC_CFG_BEG_VL 2
1581 #define ASC_EEP_MAX_DVC_ADDR_VL 15
1582 #define ASC_EEP_DVC_CFG_BEG 32
1583 #define ASC_EEP_MAX_DVC_ADDR 45
1584 #define ASC_EEP_DEFINED_WORDS 10
1585 #define ASC_EEP_MAX_ADDR 63
1586 #define ASC_EEP_RES_WORDS 0
1587 #define ASC_EEP_MAX_RETRY 20
1588 #define ASC_MAX_INIT_BUSY_RETRY 8
1589 #define ASC_EEP_ISA_PNP_WSIZE 16
1592 * These macros keep the chip SCSI id and ISA DMA speed
1593 * bitfields in board order. C bitfields aren't portable
1594 * between big and little-endian platforms so they are
1595 * not used.
1598 #define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
1599 #define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
1600 #define ASC_EEP_SET_CHIP_ID(cfg, sid) \
1601 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
1602 #define ASC_EEP_SET_DMA_SPD(cfg, spd) \
1603 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
1605 typedef struct asceep_config {
1606 ushort cfg_lsw;
1607 ushort cfg_msw;
1608 uchar init_sdtr;
1609 uchar disc_enable;
1610 uchar use_cmd_qng;
1611 uchar start_motor;
1612 uchar max_total_qng;
1613 uchar max_tag_qng;
1614 uchar bios_scan;
1615 uchar power_up_wait;
1616 uchar no_scam;
1617 uchar id_speed; /* low order 4 bits is chip scsi id */
1618 /* high order 4 bits is isa dma speed */
1619 uchar dos_int13_table[ASC_MAX_TID + 1];
1620 uchar adapter_info[6];
1621 ushort cntl;
1622 ushort chksum;
1623 } ASCEEP_CONFIG;
1625 #define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800
1626 #define ASC_PCI_CFG_LSW_BURST_MODE 0x0080
1627 #define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020
1629 #define ASC_EEP_CMD_READ 0x80
1630 #define ASC_EEP_CMD_WRITE 0x40
1631 #define ASC_EEP_CMD_WRITE_ABLE 0x30
1632 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
1633 #define ASC_OVERRUN_BSIZE 0x00000048UL
1634 #define ASC_CTRL_BREAK_ONCE 0x0001
1635 #define ASC_CTRL_BREAK_STAY_IDLE 0x0002
1636 #define ASCV_MSGOUT_BEG 0x0000
1637 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1638 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1639 #define ASCV_BREAK_SAVED_CODE (ushort)0x0006
1640 #define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
1641 #define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
1642 #define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
1643 #define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
1644 #define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
1645 #define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
1646 #define ASCV_BREAK_ADDR (ushort)0x0028
1647 #define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
1648 #define ASCV_BREAK_CONTROL (ushort)0x002C
1649 #define ASCV_BREAK_HIT_COUNT (ushort)0x002E
1651 #define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
1652 #define ASCV_MCODE_CHKSUM_W (ushort)0x0032
1653 #define ASCV_MCODE_SIZE_W (ushort)0x0034
1654 #define ASCV_STOP_CODE_B (ushort)0x0036
1655 #define ASCV_DVC_ERR_CODE_B (ushort)0x0037
1656 #define ASCV_OVERRUN_PADDR_D (ushort)0x0038
1657 #define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
1658 #define ASCV_HALTCODE_W (ushort)0x0040
1659 #define ASCV_CHKSUM_W (ushort)0x0042
1660 #define ASCV_MC_DATE_W (ushort)0x0044
1661 #define ASCV_MC_VER_W (ushort)0x0046
1662 #define ASCV_NEXTRDY_B (ushort)0x0048
1663 #define ASCV_DONENEXT_B (ushort)0x0049
1664 #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1665 #define ASCV_SCSIBUSY_B (ushort)0x004B
1666 #define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
1667 #define ASCV_CURCDB_B (ushort)0x004D
1668 #define ASCV_RCLUN_B (ushort)0x004E
1669 #define ASCV_BUSY_QHEAD_B (ushort)0x004F
1670 #define ASCV_DISC1_QHEAD_B (ushort)0x0050
1671 #define ASCV_DISC_ENABLE_B (ushort)0x0052
1672 #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1673 #define ASCV_HOSTSCSI_ID_B (ushort)0x0055
1674 #define ASCV_MCODE_CNTL_B (ushort)0x0056
1675 #define ASCV_NULL_TARGET_B (ushort)0x0057
1676 #define ASCV_FREE_Q_HEAD_W (ushort)0x0058
1677 #define ASCV_DONE_Q_TAIL_W (ushort)0x005A
1678 #define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
1679 #define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
1680 #define ASCV_HOST_FLAG_B (ushort)0x005D
1681 #define ASCV_TOTAL_READY_Q_B (ushort)0x0064
1682 #define ASCV_VER_SERIAL_B (ushort)0x0065
1683 #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1684 #define ASCV_WTM_FLAG_B (ushort)0x0068
1685 #define ASCV_RISC_FLAG_B (ushort)0x006A
1686 #define ASCV_REQ_SG_LIST_QP (ushort)0x006B
1687 #define ASC_HOST_FLAG_IN_ISR 0x01
1688 #define ASC_HOST_FLAG_ACK_INT 0x02
1689 #define ASC_RISC_FLAG_GEN_INT 0x01
1690 #define ASC_RISC_FLAG_REQ_SG_LIST 0x02
1691 #define IOP_CTRL (0x0F)
1692 #define IOP_STATUS (0x0E)
1693 #define IOP_INT_ACK IOP_STATUS
1694 #define IOP_REG_IFC (0x0D)
1695 #define IOP_SYN_OFFSET (0x0B)
1696 #define IOP_EXTRA_CONTROL (0x0D)
1697 #define IOP_REG_PC (0x0C)
1698 #define IOP_RAM_ADDR (0x0A)
1699 #define IOP_RAM_DATA (0x08)
1700 #define IOP_EEP_DATA (0x06)
1701 #define IOP_EEP_CMD (0x07)
1702 #define IOP_VERSION (0x03)
1703 #define IOP_CONFIG_HIGH (0x04)
1704 #define IOP_CONFIG_LOW (0x02)
1705 #define IOP_SIG_BYTE (0x01)
1706 #define IOP_SIG_WORD (0x00)
1707 #define IOP_REG_DC1 (0x0E)
1708 #define IOP_REG_DC0 (0x0C)
1709 #define IOP_REG_SB (0x0B)
1710 #define IOP_REG_DA1 (0x0A)
1711 #define IOP_REG_DA0 (0x08)
1712 #define IOP_REG_SC (0x09)
1713 #define IOP_DMA_SPEED (0x07)
1714 #define IOP_REG_FLAG (0x07)
1715 #define IOP_FIFO_H (0x06)
1716 #define IOP_FIFO_L (0x04)
1717 #define IOP_REG_ID (0x05)
1718 #define IOP_REG_QP (0x03)
1719 #define IOP_REG_IH (0x02)
1720 #define IOP_REG_IX (0x01)
1721 #define IOP_REG_AX (0x00)
1722 #define IFC_REG_LOCK (0x00)
1723 #define IFC_REG_UNLOCK (0x09)
1724 #define IFC_WR_EN_FILTER (0x10)
1725 #define IFC_RD_NO_EEPROM (0x10)
1726 #define IFC_SLEW_RATE (0x20)
1727 #define IFC_ACT_NEG (0x40)
1728 #define IFC_INP_FILTER (0x80)
1729 #define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
1730 #define SC_SEL (uchar)(0x80)
1731 #define SC_BSY (uchar)(0x40)
1732 #define SC_ACK (uchar)(0x20)
1733 #define SC_REQ (uchar)(0x10)
1734 #define SC_ATN (uchar)(0x08)
1735 #define SC_IO (uchar)(0x04)
1736 #define SC_CD (uchar)(0x02)
1737 #define SC_MSG (uchar)(0x01)
1738 #define SEC_SCSI_CTL (uchar)(0x80)
1739 #define SEC_ACTIVE_NEGATE (uchar)(0x40)
1740 #define SEC_SLEW_RATE (uchar)(0x20)
1741 #define SEC_ENABLE_FILTER (uchar)(0x10)
1742 #define ASC_HALT_EXTMSG_IN (ushort)0x8000
1743 #define ASC_HALT_CHK_CONDITION (ushort)0x8100
1744 #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1745 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
1746 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
1747 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1748 #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1749 #define ASC_MAX_QNO 0xF8
1750 #define ASC_DATA_SEC_BEG (ushort)0x0080
1751 #define ASC_DATA_SEC_END (ushort)0x0080
1752 #define ASC_CODE_SEC_BEG (ushort)0x0080
1753 #define ASC_CODE_SEC_END (ushort)0x0080
1754 #define ASC_QADR_BEG (0x4000)
1755 #define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
1756 #define ASC_QADR_END (ushort)0x7FFF
1757 #define ASC_QLAST_ADR (ushort)0x7FC0
1758 #define ASC_QBLK_SIZE 0x40
1759 #define ASC_BIOS_DATA_QBEG 0xF8
1760 #define ASC_MIN_ACTIVE_QNO 0x01
1761 #define ASC_QLINK_END 0xFF
1762 #define ASC_EEPROM_WORDS 0x10
1763 #define ASC_MAX_MGS_LEN 0x10
1764 #define ASC_BIOS_ADDR_DEF 0xDC00
1765 #define ASC_BIOS_SIZE 0x3800
1766 #define ASC_BIOS_RAM_OFF 0x3800
1767 #define ASC_BIOS_RAM_SIZE 0x800
1768 #define ASC_BIOS_MIN_ADDR 0xC000
1769 #define ASC_BIOS_MAX_ADDR 0xEC00
1770 #define ASC_BIOS_BANK_SIZE 0x0400
1771 #define ASC_MCODE_START_ADDR 0x0080
1772 #define ASC_CFG0_HOST_INT_ON 0x0020
1773 #define ASC_CFG0_BIOS_ON 0x0040
1774 #define ASC_CFG0_VERA_BURST_ON 0x0080
1775 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
1776 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
1777 #define ASC_CFG1_LRAM_8BITS_ON 0x0800
1778 #define ASC_CFG_MSW_CLR_MASK 0x3080
1779 #define CSW_TEST1 (ASC_CS_TYPE)0x8000
1780 #define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
1781 #define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
1782 #define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
1783 #define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
1784 #define CSW_TEST2 (ASC_CS_TYPE)0x0400
1785 #define CSW_TEST3 (ASC_CS_TYPE)0x0200
1786 #define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
1787 #define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
1788 #define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
1789 #define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
1790 #define CSW_HALTED (ASC_CS_TYPE)0x0010
1791 #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1792 #define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
1793 #define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
1794 #define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
1795 #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1796 #define CIW_INT_ACK (ASC_CS_TYPE)0x0100
1797 #define CIW_TEST1 (ASC_CS_TYPE)0x0200
1798 #define CIW_TEST2 (ASC_CS_TYPE)0x0400
1799 #define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
1800 #define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
1801 #define CC_CHIP_RESET (uchar)0x80
1802 #define CC_SCSI_RESET (uchar)0x40
1803 #define CC_HALT (uchar)0x20
1804 #define CC_SINGLE_STEP (uchar)0x10
1805 #define CC_DMA_ABLE (uchar)0x08
1806 #define CC_TEST (uchar)0x04
1807 #define CC_BANK_ONE (uchar)0x02
1808 #define CC_DIAG (uchar)0x01
1809 #define ASC_1000_ID0W 0x04C1
1810 #define ASC_1000_ID0W_FIX 0x00C1
1811 #define ASC_1000_ID1B 0x25
1812 #define ASC_EISA_BIG_IOP_GAP (0x1C30-0x0C50)
1813 #define ASC_EISA_SMALL_IOP_GAP (0x0020)
1814 #define ASC_EISA_MIN_IOP_ADDR (0x0C30)
1815 #define ASC_EISA_MAX_IOP_ADDR (0xFC50)
1816 #define ASC_EISA_REV_IOP_MASK (0x0C83)
1817 #define ASC_EISA_PID_IOP_MASK (0x0C80)
1818 #define ASC_EISA_CFG_IOP_MASK (0x0C86)
1819 #define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
1820 #define ASC_EISA_ID_740 0x01745004UL
1821 #define ASC_EISA_ID_750 0x01755004UL
1822 #define INS_HALTINT (ushort)0x6281
1823 #define INS_HALT (ushort)0x6280
1824 #define INS_SINT (ushort)0x6200
1825 #define INS_RFLAG_WTM (ushort)0x7380
1826 #define ASC_MC_SAVE_CODE_WSIZE 0x500
1827 #define ASC_MC_SAVE_DATA_WSIZE 0x40
1829 typedef struct asc_mc_saved {
1830 ushort data[ASC_MC_SAVE_DATA_WSIZE];
1831 ushort code[ASC_MC_SAVE_CODE_WSIZE];
1832 } ASC_MC_SAVED;
1834 #define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1835 #define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1836 #define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1837 #define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1838 #define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1839 #define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1840 #define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
1841 #define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
1842 #define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1843 #define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1844 #define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1845 #define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1846 #define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1847 #define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1848 #define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1849 #define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
1850 #define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
1851 #define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
1852 #define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
1853 #define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
1854 #define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
1855 #define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
1856 #define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
1857 #define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
1858 #define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
1859 #define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
1860 #define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1861 #define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1862 #define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
1863 #define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
1864 #define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
1865 #define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
1866 #define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1867 #define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
1868 #define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
1869 #define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
1870 #define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
1871 #define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
1872 #define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
1873 #define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
1874 #define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1875 #define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1876 #define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
1877 #define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
1878 #define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
1879 #define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
1880 #define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
1881 #define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
1882 #define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
1883 #define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
1884 #define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
1885 #define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
1886 #define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
1887 #define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
1888 #define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
1889 #define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
1890 #define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
1891 #define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
1892 #define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
1893 #define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
1894 #define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
1895 #define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
1896 #define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
1897 #define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
1898 #define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
1899 #define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
1900 #define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
1901 #define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
1903 STATIC int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1904 STATIC int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1905 STATIC void AscWaitEEPRead(void);
1906 STATIC void AscWaitEEPWrite(void);
1907 STATIC ushort AscReadEEPWord(PortAddr, uchar);
1908 STATIC ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1909 STATIC ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1910 STATIC int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1911 STATIC int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1912 STATIC int AscStartChip(PortAddr);
1913 STATIC int AscStopChip(PortAddr);
1914 STATIC void AscSetChipIH(PortAddr, ushort);
1915 STATIC int AscIsChipHalted(PortAddr);
1916 STATIC void AscAckInterrupt(PortAddr);
1917 STATIC void AscDisableInterrupt(PortAddr);
1918 STATIC void AscEnableInterrupt(PortAddr);
1919 STATIC void AscSetBank(PortAddr, uchar);
1920 STATIC int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1921 #ifdef CONFIG_ISA
1922 STATIC ushort AscGetIsaDmaChannel(PortAddr);
1923 STATIC ushort AscSetIsaDmaChannel(PortAddr, ushort);
1924 STATIC uchar AscSetIsaDmaSpeed(PortAddr, uchar);
1925 STATIC uchar AscGetIsaDmaSpeed(PortAddr);
1926 #endif /* CONFIG_ISA */
1927 STATIC uchar AscReadLramByte(PortAddr, ushort);
1928 STATIC ushort AscReadLramWord(PortAddr, ushort);
1929 #if CC_VERY_LONG_SG_LIST
1930 STATIC ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1931 #endif /* CC_VERY_LONG_SG_LIST */
1932 STATIC void AscWriteLramWord(PortAddr, ushort, ushort);
1933 STATIC void AscWriteLramByte(PortAddr, ushort, uchar);
1934 STATIC ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
1935 STATIC void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1936 STATIC void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1937 STATIC void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1938 STATIC void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
1939 STATIC ushort AscInitAscDvcVar(ASC_DVC_VAR *);
1940 STATIC ushort AscInitFromEEP(ASC_DVC_VAR *);
1941 STATIC ushort AscInitFromAscDvcVar(ASC_DVC_VAR *);
1942 STATIC ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1943 STATIC int AscTestExternalLram(ASC_DVC_VAR *);
1944 STATIC uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1945 STATIC uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1946 STATIC void AscSetChipSDTR(PortAddr, uchar, uchar);
1947 STATIC uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1948 STATIC uchar AscAllocFreeQueue(PortAddr, uchar);
1949 STATIC uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1950 STATIC int AscHostReqRiscHalt(PortAddr);
1951 STATIC int AscStopQueueExe(PortAddr);
1952 STATIC int AscSendScsiQueue(ASC_DVC_VAR *,
1953 ASC_SCSI_Q * scsiq,
1954 uchar n_q_required);
1955 STATIC int AscPutReadyQueue(ASC_DVC_VAR *,
1956 ASC_SCSI_Q *, uchar);
1957 STATIC int AscPutReadySgListQueue(ASC_DVC_VAR *,
1958 ASC_SCSI_Q *, uchar);
1959 STATIC int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1960 STATIC int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1961 STATIC ushort AscInitLram(ASC_DVC_VAR *);
1962 STATIC ushort AscInitQLinkVar(ASC_DVC_VAR *);
1963 STATIC int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1964 STATIC int AscIsrChipHalted(ASC_DVC_VAR *);
1965 STATIC uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1966 ASC_QDONE_INFO *, ASC_DCNT);
1967 STATIC int AscIsrQDone(ASC_DVC_VAR *);
1968 STATIC int AscCompareString(uchar *, uchar *, int);
1969 #ifdef CONFIG_ISA
1970 STATIC ushort AscGetEisaChipCfg(PortAddr);
1971 STATIC ASC_DCNT AscGetEisaProductID(PortAddr);
1972 STATIC PortAddr AscSearchIOPortAddrEISA(PortAddr);
1973 STATIC PortAddr AscSearchIOPortAddr11(PortAddr);
1974 STATIC PortAddr AscSearchIOPortAddr(PortAddr, ushort);
1975 STATIC void AscSetISAPNPWaitForKey(void);
1976 #endif /* CONFIG_ISA */
1977 STATIC uchar AscGetChipScsiCtrl(PortAddr);
1978 STATIC uchar AscSetChipScsiID(PortAddr, uchar);
1979 STATIC uchar AscGetChipVersion(PortAddr, ushort);
1980 STATIC ushort AscGetChipBusType(PortAddr);
1981 STATIC ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
1982 STATIC int AscFindSignature(PortAddr);
1983 STATIC void AscToggleIRQAct(PortAddr);
1984 STATIC uchar AscGetChipIRQ(PortAddr, ushort);
1985 STATIC uchar AscSetChipIRQ(PortAddr, uchar, ushort);
1986 STATIC ushort AscGetChipBiosAddress(PortAddr, ushort);
1987 STATIC inline ulong DvcEnterCritical(void);
1988 STATIC inline void DvcLeaveCritical(ulong);
1989 #ifdef CONFIG_PCI
1990 STATIC uchar DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort);
1991 STATIC void DvcWritePCIConfigByte(ASC_DVC_VAR *,
1992 ushort, uchar);
1993 #endif /* CONFIG_PCI */
1994 STATIC ushort AscGetChipBiosAddress(PortAddr, ushort);
1995 STATIC void DvcSleepMilliSecond(ASC_DCNT);
1996 STATIC void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
1997 STATIC void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1998 STATIC void DvcGetQinfo(PortAddr, ushort, uchar *, int);
1999 STATIC ushort AscInitGetConfig(ASC_DVC_VAR *);
2000 STATIC ushort AscInitSetConfig(ASC_DVC_VAR *);
2001 STATIC ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
2002 STATIC void AscAsyncFix(ASC_DVC_VAR *, uchar,
2003 ASC_SCSI_INQUIRY *);
2004 STATIC int AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
2005 STATIC void AscInquiryHandling(ASC_DVC_VAR *,
2006 uchar, ASC_SCSI_INQUIRY *);
2007 STATIC int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
2008 STATIC int AscISR(ASC_DVC_VAR *);
2009 STATIC uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar,
2010 uchar);
2011 STATIC int AscSgListToQueue(int);
2012 #ifdef CONFIG_ISA
2013 STATIC void AscEnableIsaDma(uchar);
2014 #endif /* CONFIG_ISA */
2015 STATIC ASC_DCNT AscGetMaxDmaCount(ushort);
2019 * --- Adv Library Constants and Macros
2022 #define ADV_LIB_VERSION_MAJOR 5
2023 #define ADV_LIB_VERSION_MINOR 14
2026 * Define Adv Library required special types.
2030 * Portable Data Types
2032 * Any instance where a 32-bit long or pointer type is assumed
2033 * for precision or HW defined structures, the following define
2034 * types must be used. In Linux the char, short, and int types
2035 * are all consistent at 8, 16, and 32 bits respectively. Pointers
2036 * and long types are 64 bits on Alpha and UltraSPARC.
2038 #define ADV_PADDR __u32 /* Physical address data type. */
2039 #define ADV_VADDR __u32 /* Virtual address data type. */
2040 #define ADV_DCNT __u32 /* Unsigned Data count type. */
2041 #define ADV_SDCNT __s32 /* Signed Data count type. */
2044 * These macros are used to convert a virtual address to a
2045 * 32-bit value. This currently can be used on Linux Alpha
2046 * which uses 64-bit virtual address but a 32-bit bus address.
2047 * This is likely to break in the future, but doing this now
2048 * will give us time to change the HW and FW to handle 64-bit
2049 * addresses.
2051 #define ADV_VADDR_TO_U32 virt_to_bus
2052 #define ADV_U32_TO_VADDR bus_to_virt
2054 #define AdvPortAddr ulong /* Virtual memory address size */
2057 * Define Adv Library required memory access macros.
2059 #define ADV_MEM_READB(addr) readb(addr)
2060 #define ADV_MEM_READW(addr) readw(addr)
2061 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
2062 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
2063 #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
2065 #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
2068 * For wide boards a CDB length maximum of 16 bytes
2069 * is supported.
2071 #define ADV_MAX_CDB_LEN 16
2074 * Define total number of simultaneous maximum element scatter-gather
2075 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
2076 * maximum number of outstanding commands per wide host adapter. Each
2077 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
2078 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
2079 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
2080 * structures or 255 scatter-gather elements.
2083 #define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
2086 * Define Adv Library required maximum number of scatter-gather
2087 * elements per request.
2089 #define ADV_MAX_SG_LIST 255
2091 /* Number of SG blocks needed. */
2092 #define ADV_NUM_SG_BLOCK \
2093 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
2095 /* Total contiguous memory needed for SG blocks. */
2096 #define ADV_SG_TOTAL_MEM_SIZE \
2097 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
2099 #define ADV_PAGE_SIZE PAGE_SIZE
2101 #define ADV_NUM_PAGE_CROSSING \
2102 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2104 /* a_condor.h */
2105 #define ADV_PCI_VENDOR_ID 0x10CD
2106 #define ADV_PCI_DEVICE_ID_REV_A 0x2300
2107 #define ADV_PCI_DEVID_38C0800_REV1 0x2500
2108 #define ADV_PCI_DEVID_38C1600_REV1 0x2700
2110 #define ADV_EEP_DVC_CFG_BEGIN (0x00)
2111 #define ADV_EEP_DVC_CFG_END (0x15)
2112 #define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
2113 #define ADV_EEP_MAX_WORD_ADDR (0x1E)
2115 #define ADV_EEP_DELAY_MS 100
2117 #define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
2118 #define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
2120 * For the ASC3550 Bit 13 is Termination Polarity control bit.
2121 * For later ICs Bit 13 controls whether the CIS (Card Information
2122 * Service Section) is loaded from EEPROM.
2124 #define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
2125 #define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
2127 * ASC38C1600 Bit 11
2129 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
2130 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
2131 * Function 0 will specify INT B.
2133 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
2134 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
2135 * Function 1 will specify INT A.
2137 #define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
2139 typedef struct adveep_3550_config
2141 /* Word Offset, Description */
2143 ushort cfg_lsw; /* 00 power up initialization */
2144 /* bit 13 set - Term Polarity Control */
2145 /* bit 14 set - BIOS Enable */
2146 /* bit 15 set - Big Endian Mode */
2147 ushort cfg_msw; /* 01 unused */
2148 ushort disc_enable; /* 02 disconnect enable */
2149 ushort wdtr_able; /* 03 Wide DTR able */
2150 ushort sdtr_able; /* 04 Synchronous DTR able */
2151 ushort start_motor; /* 05 send start up motor */
2152 ushort tagqng_able; /* 06 tag queuing able */
2153 ushort bios_scan; /* 07 BIOS device control */
2154 ushort scam_tolerant; /* 08 no scam */
2156 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2157 uchar bios_boot_delay; /* power up wait */
2159 uchar scsi_reset_delay; /* 10 reset delay */
2160 uchar bios_id_lun; /* first boot device scsi id & lun */
2161 /* high nibble is lun */
2162 /* low nibble is scsi id */
2164 uchar termination; /* 11 0 - automatic */
2165 /* 1 - low off / high off */
2166 /* 2 - low off / high on */
2167 /* 3 - low on / high on */
2168 /* There is no low on / high off */
2170 uchar reserved1; /* reserved byte (not used) */
2172 ushort bios_ctrl; /* 12 BIOS control bits */
2173 /* bit 0 BIOS don't act as initiator. */
2174 /* bit 1 BIOS > 1 GB support */
2175 /* bit 2 BIOS > 2 Disk Support */
2176 /* bit 3 BIOS don't support removables */
2177 /* bit 4 BIOS support bootable CD */
2178 /* bit 5 BIOS scan enabled */
2179 /* bit 6 BIOS support multiple LUNs */
2180 /* bit 7 BIOS display of message */
2181 /* bit 8 SCAM disabled */
2182 /* bit 9 Reset SCSI bus during init. */
2183 /* bit 10 */
2184 /* bit 11 No verbose initialization. */
2185 /* bit 12 SCSI parity enabled */
2186 /* bit 13 */
2187 /* bit 14 */
2188 /* bit 15 */
2189 ushort ultra_able; /* 13 ULTRA speed able */
2190 ushort reserved2; /* 14 reserved */
2191 uchar max_host_qng; /* 15 maximum host queuing */
2192 uchar max_dvc_qng; /* maximum per device queuing */
2193 ushort dvc_cntl; /* 16 control bit for driver */
2194 ushort bug_fix; /* 17 control bit for bug fix */
2195 ushort serial_number_word1; /* 18 Board serial number word 1 */
2196 ushort serial_number_word2; /* 19 Board serial number word 2 */
2197 ushort serial_number_word3; /* 20 Board serial number word 3 */
2198 ushort check_sum; /* 21 EEP check sum */
2199 uchar oem_name[16]; /* 22 OEM name */
2200 ushort dvc_err_code; /* 30 last device driver error code */
2201 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2202 ushort adv_err_addr; /* 32 last uc error address */
2203 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2204 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2205 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2206 ushort num_of_err; /* 36 number of error */
2207 } ADVEEP_3550_CONFIG;
2209 typedef struct adveep_38C0800_config
2211 /* Word Offset, Description */
2213 ushort cfg_lsw; /* 00 power up initialization */
2214 /* bit 13 set - Load CIS */
2215 /* bit 14 set - BIOS Enable */
2216 /* bit 15 set - Big Endian Mode */
2217 ushort cfg_msw; /* 01 unused */
2218 ushort disc_enable; /* 02 disconnect enable */
2219 ushort wdtr_able; /* 03 Wide DTR able */
2220 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2221 ushort start_motor; /* 05 send start up motor */
2222 ushort tagqng_able; /* 06 tag queuing able */
2223 ushort bios_scan; /* 07 BIOS device control */
2224 ushort scam_tolerant; /* 08 no scam */
2226 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2227 uchar bios_boot_delay; /* power up wait */
2229 uchar scsi_reset_delay; /* 10 reset delay */
2230 uchar bios_id_lun; /* first boot device scsi id & lun */
2231 /* high nibble is lun */
2232 /* low nibble is scsi id */
2234 uchar termination_se; /* 11 0 - automatic */
2235 /* 1 - low off / high off */
2236 /* 2 - low off / high on */
2237 /* 3 - low on / high on */
2238 /* There is no low on / high off */
2240 uchar termination_lvd; /* 11 0 - automatic */
2241 /* 1 - low off / high off */
2242 /* 2 - low off / high on */
2243 /* 3 - low on / high on */
2244 /* There is no low on / high off */
2246 ushort bios_ctrl; /* 12 BIOS control bits */
2247 /* bit 0 BIOS don't act as initiator. */
2248 /* bit 1 BIOS > 1 GB support */
2249 /* bit 2 BIOS > 2 Disk Support */
2250 /* bit 3 BIOS don't support removables */
2251 /* bit 4 BIOS support bootable CD */
2252 /* bit 5 BIOS scan enabled */
2253 /* bit 6 BIOS support multiple LUNs */
2254 /* bit 7 BIOS display of message */
2255 /* bit 8 SCAM disabled */
2256 /* bit 9 Reset SCSI bus during init. */
2257 /* bit 10 */
2258 /* bit 11 No verbose initialization. */
2259 /* bit 12 SCSI parity enabled */
2260 /* bit 13 */
2261 /* bit 14 */
2262 /* bit 15 */
2263 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2264 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2265 uchar max_host_qng; /* 15 maximum host queueing */
2266 uchar max_dvc_qng; /* maximum per device queuing */
2267 ushort dvc_cntl; /* 16 control bit for driver */
2268 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2269 ushort serial_number_word1; /* 18 Board serial number word 1 */
2270 ushort serial_number_word2; /* 19 Board serial number word 2 */
2271 ushort serial_number_word3; /* 20 Board serial number word 3 */
2272 ushort check_sum; /* 21 EEP check sum */
2273 uchar oem_name[16]; /* 22 OEM name */
2274 ushort dvc_err_code; /* 30 last device driver error code */
2275 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2276 ushort adv_err_addr; /* 32 last uc error address */
2277 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2278 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2279 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2280 ushort reserved36; /* 36 reserved */
2281 ushort reserved37; /* 37 reserved */
2282 ushort reserved38; /* 38 reserved */
2283 ushort reserved39; /* 39 reserved */
2284 ushort reserved40; /* 40 reserved */
2285 ushort reserved41; /* 41 reserved */
2286 ushort reserved42; /* 42 reserved */
2287 ushort reserved43; /* 43 reserved */
2288 ushort reserved44; /* 44 reserved */
2289 ushort reserved45; /* 45 reserved */
2290 ushort reserved46; /* 46 reserved */
2291 ushort reserved47; /* 47 reserved */
2292 ushort reserved48; /* 48 reserved */
2293 ushort reserved49; /* 49 reserved */
2294 ushort reserved50; /* 50 reserved */
2295 ushort reserved51; /* 51 reserved */
2296 ushort reserved52; /* 52 reserved */
2297 ushort reserved53; /* 53 reserved */
2298 ushort reserved54; /* 54 reserved */
2299 ushort reserved55; /* 55 reserved */
2300 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2301 ushort cisprt_msw; /* 57 CIS PTR MSW */
2302 ushort subsysvid; /* 58 SubSystem Vendor ID */
2303 ushort subsysid; /* 59 SubSystem ID */
2304 ushort reserved60; /* 60 reserved */
2305 ushort reserved61; /* 61 reserved */
2306 ushort reserved62; /* 62 reserved */
2307 ushort reserved63; /* 63 reserved */
2308 } ADVEEP_38C0800_CONFIG;
2310 typedef struct adveep_38C1600_config
2312 /* Word Offset, Description */
2314 ushort cfg_lsw; /* 00 power up initialization */
2315 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
2316 /* clear - Func. 0 INTA, Func. 1 INTB */
2317 /* bit 13 set - Load CIS */
2318 /* bit 14 set - BIOS Enable */
2319 /* bit 15 set - Big Endian Mode */
2320 ushort cfg_msw; /* 01 unused */
2321 ushort disc_enable; /* 02 disconnect enable */
2322 ushort wdtr_able; /* 03 Wide DTR able */
2323 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2324 ushort start_motor; /* 05 send start up motor */
2325 ushort tagqng_able; /* 06 tag queuing able */
2326 ushort bios_scan; /* 07 BIOS device control */
2327 ushort scam_tolerant; /* 08 no scam */
2329 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2330 uchar bios_boot_delay; /* power up wait */
2332 uchar scsi_reset_delay; /* 10 reset delay */
2333 uchar bios_id_lun; /* first boot device scsi id & lun */
2334 /* high nibble is lun */
2335 /* low nibble is scsi id */
2337 uchar termination_se; /* 11 0 - automatic */
2338 /* 1 - low off / high off */
2339 /* 2 - low off / high on */
2340 /* 3 - low on / high on */
2341 /* There is no low on / high off */
2343 uchar termination_lvd; /* 11 0 - automatic */
2344 /* 1 - low off / high off */
2345 /* 2 - low off / high on */
2346 /* 3 - low on / high on */
2347 /* There is no low on / high off */
2349 ushort bios_ctrl; /* 12 BIOS control bits */
2350 /* bit 0 BIOS don't act as initiator. */
2351 /* bit 1 BIOS > 1 GB support */
2352 /* bit 2 BIOS > 2 Disk Support */
2353 /* bit 3 BIOS don't support removables */
2354 /* bit 4 BIOS support bootable CD */
2355 /* bit 5 BIOS scan enabled */
2356 /* bit 6 BIOS support multiple LUNs */
2357 /* bit 7 BIOS display of message */
2358 /* bit 8 SCAM disabled */
2359 /* bit 9 Reset SCSI bus during init. */
2360 /* bit 10 Basic Integrity Checking disabled */
2361 /* bit 11 No verbose initialization. */
2362 /* bit 12 SCSI parity enabled */
2363 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
2364 /* bit 14 */
2365 /* bit 15 */
2366 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2367 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2368 uchar max_host_qng; /* 15 maximum host queueing */
2369 uchar max_dvc_qng; /* maximum per device queuing */
2370 ushort dvc_cntl; /* 16 control bit for driver */
2371 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2372 ushort serial_number_word1; /* 18 Board serial number word 1 */
2373 ushort serial_number_word2; /* 19 Board serial number word 2 */
2374 ushort serial_number_word3; /* 20 Board serial number word 3 */
2375 ushort check_sum; /* 21 EEP check sum */
2376 uchar oem_name[16]; /* 22 OEM name */
2377 ushort dvc_err_code; /* 30 last device driver error code */
2378 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2379 ushort adv_err_addr; /* 32 last uc error address */
2380 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2381 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2382 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2383 ushort reserved36; /* 36 reserved */
2384 ushort reserved37; /* 37 reserved */
2385 ushort reserved38; /* 38 reserved */
2386 ushort reserved39; /* 39 reserved */
2387 ushort reserved40; /* 40 reserved */
2388 ushort reserved41; /* 41 reserved */
2389 ushort reserved42; /* 42 reserved */
2390 ushort reserved43; /* 43 reserved */
2391 ushort reserved44; /* 44 reserved */
2392 ushort reserved45; /* 45 reserved */
2393 ushort reserved46; /* 46 reserved */
2394 ushort reserved47; /* 47 reserved */
2395 ushort reserved48; /* 48 reserved */
2396 ushort reserved49; /* 49 reserved */
2397 ushort reserved50; /* 50 reserved */
2398 ushort reserved51; /* 51 reserved */
2399 ushort reserved52; /* 52 reserved */
2400 ushort reserved53; /* 53 reserved */
2401 ushort reserved54; /* 54 reserved */
2402 ushort reserved55; /* 55 reserved */
2403 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2404 ushort cisprt_msw; /* 57 CIS PTR MSW */
2405 ushort subsysvid; /* 58 SubSystem Vendor ID */
2406 ushort subsysid; /* 59 SubSystem ID */
2407 ushort reserved60; /* 60 reserved */
2408 ushort reserved61; /* 61 reserved */
2409 ushort reserved62; /* 62 reserved */
2410 ushort reserved63; /* 63 reserved */
2411 } ADVEEP_38C1600_CONFIG;
2414 * EEPROM Commands
2416 #define ASC_EEP_CMD_DONE 0x0200
2417 #define ASC_EEP_CMD_DONE_ERR 0x0001
2419 /* cfg_word */
2420 #define EEP_CFG_WORD_BIG_ENDIAN 0x8000
2422 /* bios_ctrl */
2423 #define BIOS_CTRL_BIOS 0x0001
2424 #define BIOS_CTRL_EXTENDED_XLAT 0x0002
2425 #define BIOS_CTRL_GT_2_DISK 0x0004
2426 #define BIOS_CTRL_BIOS_REMOVABLE 0x0008
2427 #define BIOS_CTRL_BOOTABLE_CD 0x0010
2428 #define BIOS_CTRL_MULTIPLE_LUN 0x0040
2429 #define BIOS_CTRL_DISPLAY_MSG 0x0080
2430 #define BIOS_CTRL_NO_SCAM 0x0100
2431 #define BIOS_CTRL_RESET_SCSI_BUS 0x0200
2432 #define BIOS_CTRL_INIT_VERBOSE 0x0800
2433 #define BIOS_CTRL_SCSI_PARITY 0x1000
2434 #define BIOS_CTRL_AIPP_DIS 0x2000
2436 #define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
2437 #define ADV_3550_IOLEN 0x40 /* I/O Port Range in bytes */
2439 #define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2440 #define ADV_38C0800_IOLEN 0x100 /* I/O Port Range in bytes */
2443 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
2444 * a special 16K Adv Library and Microcode version. After the issue is
2445 * resolved, should restore 32K support.
2447 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
2449 #define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2450 #define ADV_38C1600_IOLEN 0x100 /* I/O Port Range 256 bytes */
2451 #define ADV_38C1600_MEMLEN 0x1000 /* Memory Range 4KB bytes */
2454 * Byte I/O register address from base of 'iop_base'.
2456 #define IOPB_INTR_STATUS_REG 0x00
2457 #define IOPB_CHIP_ID_1 0x01
2458 #define IOPB_INTR_ENABLES 0x02
2459 #define IOPB_CHIP_TYPE_REV 0x03
2460 #define IOPB_RES_ADDR_4 0x04
2461 #define IOPB_RES_ADDR_5 0x05
2462 #define IOPB_RAM_DATA 0x06
2463 #define IOPB_RES_ADDR_7 0x07
2464 #define IOPB_FLAG_REG 0x08
2465 #define IOPB_RES_ADDR_9 0x09
2466 #define IOPB_RISC_CSR 0x0A
2467 #define IOPB_RES_ADDR_B 0x0B
2468 #define IOPB_RES_ADDR_C 0x0C
2469 #define IOPB_RES_ADDR_D 0x0D
2470 #define IOPB_SOFT_OVER_WR 0x0E
2471 #define IOPB_RES_ADDR_F 0x0F
2472 #define IOPB_MEM_CFG 0x10
2473 #define IOPB_RES_ADDR_11 0x11
2474 #define IOPB_GPIO_DATA 0x12
2475 #define IOPB_RES_ADDR_13 0x13
2476 #define IOPB_FLASH_PAGE 0x14
2477 #define IOPB_RES_ADDR_15 0x15
2478 #define IOPB_GPIO_CNTL 0x16
2479 #define IOPB_RES_ADDR_17 0x17
2480 #define IOPB_FLASH_DATA 0x18
2481 #define IOPB_RES_ADDR_19 0x19
2482 #define IOPB_RES_ADDR_1A 0x1A
2483 #define IOPB_RES_ADDR_1B 0x1B
2484 #define IOPB_RES_ADDR_1C 0x1C
2485 #define IOPB_RES_ADDR_1D 0x1D
2486 #define IOPB_RES_ADDR_1E 0x1E
2487 #define IOPB_RES_ADDR_1F 0x1F
2488 #define IOPB_DMA_CFG0 0x20
2489 #define IOPB_DMA_CFG1 0x21
2490 #define IOPB_TICKLE 0x22
2491 #define IOPB_DMA_REG_WR 0x23
2492 #define IOPB_SDMA_STATUS 0x24
2493 #define IOPB_SCSI_BYTE_CNT 0x25
2494 #define IOPB_HOST_BYTE_CNT 0x26
2495 #define IOPB_BYTE_LEFT_TO_XFER 0x27
2496 #define IOPB_BYTE_TO_XFER_0 0x28
2497 #define IOPB_BYTE_TO_XFER_1 0x29
2498 #define IOPB_BYTE_TO_XFER_2 0x2A
2499 #define IOPB_BYTE_TO_XFER_3 0x2B
2500 #define IOPB_ACC_GRP 0x2C
2501 #define IOPB_RES_ADDR_2D 0x2D
2502 #define IOPB_DEV_ID 0x2E
2503 #define IOPB_RES_ADDR_2F 0x2F
2504 #define IOPB_SCSI_DATA 0x30
2505 #define IOPB_RES_ADDR_31 0x31
2506 #define IOPB_RES_ADDR_32 0x32
2507 #define IOPB_SCSI_DATA_HSHK 0x33
2508 #define IOPB_SCSI_CTRL 0x34
2509 #define IOPB_RES_ADDR_35 0x35
2510 #define IOPB_RES_ADDR_36 0x36
2511 #define IOPB_RES_ADDR_37 0x37
2512 #define IOPB_RAM_BIST 0x38
2513 #define IOPB_PLL_TEST 0x39
2514 #define IOPB_PCI_INT_CFG 0x3A
2515 #define IOPB_RES_ADDR_3B 0x3B
2516 #define IOPB_RFIFO_CNT 0x3C
2517 #define IOPB_RES_ADDR_3D 0x3D
2518 #define IOPB_RES_ADDR_3E 0x3E
2519 #define IOPB_RES_ADDR_3F 0x3F
2522 * Word I/O register address from base of 'iop_base'.
2524 #define IOPW_CHIP_ID_0 0x00 /* CID0 */
2525 #define IOPW_CTRL_REG 0x02 /* CC */
2526 #define IOPW_RAM_ADDR 0x04 /* LA */
2527 #define IOPW_RAM_DATA 0x06 /* LD */
2528 #define IOPW_RES_ADDR_08 0x08
2529 #define IOPW_RISC_CSR 0x0A /* CSR */
2530 #define IOPW_SCSI_CFG0 0x0C /* CFG0 */
2531 #define IOPW_SCSI_CFG1 0x0E /* CFG1 */
2532 #define IOPW_RES_ADDR_10 0x10
2533 #define IOPW_SEL_MASK 0x12 /* SM */
2534 #define IOPW_RES_ADDR_14 0x14
2535 #define IOPW_FLASH_ADDR 0x16 /* FA */
2536 #define IOPW_RES_ADDR_18 0x18
2537 #define IOPW_EE_CMD 0x1A /* EC */
2538 #define IOPW_EE_DATA 0x1C /* ED */
2539 #define IOPW_SFIFO_CNT 0x1E /* SFC */
2540 #define IOPW_RES_ADDR_20 0x20
2541 #define IOPW_Q_BASE 0x22 /* QB */
2542 #define IOPW_QP 0x24 /* QP */
2543 #define IOPW_IX 0x26 /* IX */
2544 #define IOPW_SP 0x28 /* SP */
2545 #define IOPW_PC 0x2A /* PC */
2546 #define IOPW_RES_ADDR_2C 0x2C
2547 #define IOPW_RES_ADDR_2E 0x2E
2548 #define IOPW_SCSI_DATA 0x30 /* SD */
2549 #define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
2550 #define IOPW_SCSI_CTRL 0x34 /* SC */
2551 #define IOPW_HSHK_CFG 0x36 /* HCFG */
2552 #define IOPW_SXFR_STATUS 0x36 /* SXS */
2553 #define IOPW_SXFR_CNTL 0x38 /* SXL */
2554 #define IOPW_SXFR_CNTH 0x3A /* SXH */
2555 #define IOPW_RES_ADDR_3C 0x3C
2556 #define IOPW_RFIFO_DATA 0x3E /* RFD */
2559 * Doubleword I/O register address from base of 'iop_base'.
2561 #define IOPDW_RES_ADDR_0 0x00
2562 #define IOPDW_RAM_DATA 0x04
2563 #define IOPDW_RES_ADDR_8 0x08
2564 #define IOPDW_RES_ADDR_C 0x0C
2565 #define IOPDW_RES_ADDR_10 0x10
2566 #define IOPDW_COMMA 0x14
2567 #define IOPDW_COMMB 0x18
2568 #define IOPDW_RES_ADDR_1C 0x1C
2569 #define IOPDW_SDMA_ADDR0 0x20
2570 #define IOPDW_SDMA_ADDR1 0x24
2571 #define IOPDW_SDMA_COUNT 0x28
2572 #define IOPDW_SDMA_ERROR 0x2C
2573 #define IOPDW_RDMA_ADDR0 0x30
2574 #define IOPDW_RDMA_ADDR1 0x34
2575 #define IOPDW_RDMA_COUNT 0x38
2576 #define IOPDW_RDMA_ERROR 0x3C
2578 #define ADV_CHIP_ID_BYTE 0x25
2579 #define ADV_CHIP_ID_WORD 0x04C1
2581 #define ADV_SC_SCSI_BUS_RESET 0x2000
2583 #define ADV_INTR_ENABLE_HOST_INTR 0x01
2584 #define ADV_INTR_ENABLE_SEL_INTR 0x02
2585 #define ADV_INTR_ENABLE_DPR_INTR 0x04
2586 #define ADV_INTR_ENABLE_RTA_INTR 0x08
2587 #define ADV_INTR_ENABLE_RMA_INTR 0x10
2588 #define ADV_INTR_ENABLE_RST_INTR 0x20
2589 #define ADV_INTR_ENABLE_DPE_INTR 0x40
2590 #define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
2592 #define ADV_INTR_STATUS_INTRA 0x01
2593 #define ADV_INTR_STATUS_INTRB 0x02
2594 #define ADV_INTR_STATUS_INTRC 0x04
2596 #define ADV_RISC_CSR_STOP (0x0000)
2597 #define ADV_RISC_TEST_COND (0x2000)
2598 #define ADV_RISC_CSR_RUN (0x4000)
2599 #define ADV_RISC_CSR_SINGLE_STEP (0x8000)
2601 #define ADV_CTRL_REG_HOST_INTR 0x0100
2602 #define ADV_CTRL_REG_SEL_INTR 0x0200
2603 #define ADV_CTRL_REG_DPR_INTR 0x0400
2604 #define ADV_CTRL_REG_RTA_INTR 0x0800
2605 #define ADV_CTRL_REG_RMA_INTR 0x1000
2606 #define ADV_CTRL_REG_RES_BIT14 0x2000
2607 #define ADV_CTRL_REG_DPE_INTR 0x4000
2608 #define ADV_CTRL_REG_POWER_DONE 0x8000
2609 #define ADV_CTRL_REG_ANY_INTR 0xFF00
2611 #define ADV_CTRL_REG_CMD_RESET 0x00C6
2612 #define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
2613 #define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
2614 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
2615 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
2617 #define ADV_TICKLE_NOP 0x00
2618 #define ADV_TICKLE_A 0x01
2619 #define ADV_TICKLE_B 0x02
2620 #define ADV_TICKLE_C 0x03
2622 #define ADV_SCSI_CTRL_RSTOUT 0x2000
2624 #define AdvIsIntPending(port) \
2625 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2628 * SCSI_CFG0 Register bit definitions
2630 #define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
2631 #define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
2632 #define EVEN_PARITY 0x1000 /* Select Even Parity */
2633 #define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2634 #define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
2635 #define PRIM_MODE 0x0100 /* Primitive SCSI mode */
2636 #define SCAM_EN 0x0080 /* Enable SCAM selection */
2637 #define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2638 #define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2639 #define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
2640 #define OUR_ID 0x000F /* SCSI ID */
2643 * SCSI_CFG1 Register bit definitions
2645 #define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
2646 #define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2647 #define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
2648 #define FILTER_SEL 0x0C00 /* Filter Period Selection */
2649 #define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
2650 #define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
2651 #define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
2652 #define ACTIVE_DBL 0x0200 /* Disable Active Negation */
2653 #define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
2654 #define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
2655 #define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
2656 #define TERM_CTL 0x0030 /* External SCSI Termination Bits */
2657 #define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
2658 #define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
2659 #define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
2662 * Addendum for ASC-38C0800 Chip
2664 * The ASC-38C1600 Chip uses the same definitions except that the
2665 * bus mode override bits [12:10] have been moved to byte register
2666 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
2667 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
2668 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
2669 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
2670 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
2672 #define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
2673 #define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
2674 #define HVD 0x1000 /* HVD Device Detect */
2675 #define LVD 0x0800 /* LVD Device Detect */
2676 #define SE 0x0400 /* SE Device Detect */
2677 #define TERM_LVD 0x00C0 /* LVD Termination Bits */
2678 #define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
2679 #define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
2680 #define TERM_SE 0x0030 /* SE Termination Bits */
2681 #define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
2682 #define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
2683 #define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
2684 #define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
2685 #define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
2686 #define C_DET_SE 0x0003 /* SE Cable Detect Bits */
2687 #define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
2688 #define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
2691 #define CABLE_ILLEGAL_A 0x7
2692 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
2694 #define CABLE_ILLEGAL_B 0xB
2695 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
2698 * MEM_CFG Register bit definitions
2700 #define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
2701 #define FAST_EE_CLK 0x20 /* Diagnostic Bit */
2702 #define RAM_SZ 0x1C /* Specify size of RAM to RISC */
2703 #define RAM_SZ_2KB 0x00 /* 2 KB */
2704 #define RAM_SZ_4KB 0x04 /* 4 KB */
2705 #define RAM_SZ_8KB 0x08 /* 8 KB */
2706 #define RAM_SZ_16KB 0x0C /* 16 KB */
2707 #define RAM_SZ_32KB 0x10 /* 32 KB */
2708 #define RAM_SZ_64KB 0x14 /* 64 KB */
2711 * DMA_CFG0 Register bit definitions
2713 * This register is only accessible to the host.
2715 #define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
2716 #define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
2717 #define FIFO_THRESH_16B 0x00 /* 16 bytes */
2718 #define FIFO_THRESH_32B 0x20 /* 32 bytes */
2719 #define FIFO_THRESH_48B 0x30 /* 48 bytes */
2720 #define FIFO_THRESH_64B 0x40 /* 64 bytes */
2721 #define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
2722 #define FIFO_THRESH_96B 0x60 /* 96 bytes */
2723 #define FIFO_THRESH_112B 0x70 /* 112 bytes */
2724 #define START_CTL 0x0C /* DMA start conditions */
2725 #define START_CTL_TH 0x00 /* Wait threshold level (default) */
2726 #define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
2727 #define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
2728 #define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
2729 #define READ_CMD 0x03 /* Memory Read Method */
2730 #define READ_CMD_MR 0x00 /* Memory Read */
2731 #define READ_CMD_MRL 0x02 /* Memory Read Long */
2732 #define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
2735 * ASC-38C0800 RAM BIST Register bit definitions
2737 #define RAM_TEST_MODE 0x80
2738 #define PRE_TEST_MODE 0x40
2739 #define NORMAL_MODE 0x00
2740 #define RAM_TEST_DONE 0x10
2741 #define RAM_TEST_STATUS 0x0F
2742 #define RAM_TEST_HOST_ERROR 0x08
2743 #define RAM_TEST_INTRAM_ERROR 0x04
2744 #define RAM_TEST_RISC_ERROR 0x02
2745 #define RAM_TEST_SCSI_ERROR 0x01
2746 #define RAM_TEST_SUCCESS 0x00
2747 #define PRE_TEST_VALUE 0x05
2748 #define NORMAL_VALUE 0x00
2751 * ASC38C1600 Definitions
2753 * IOPB_PCI_INT_CFG Bit Field Definitions
2756 #define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
2759 * Bit 1 can be set to change the interrupt for the Function to operate in
2760 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
2761 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
2762 * mode, otherwise the operating mode is undefined.
2764 #define TOTEMPOLE 0x02
2767 * Bit 0 can be used to change the Int Pin for the Function. The value is
2768 * 0 by default for both Functions with Function 0 using INT A and Function
2769 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
2770 * INT A is used.
2772 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
2773 * value specified in the PCI Configuration Space.
2775 #define INTAB 0x01
2777 /* a_advlib.h */
2780 * Adv Library Status Definitions
2782 #define ADV_TRUE 1
2783 #define ADV_FALSE 0
2784 #define ADV_NOERROR 1
2785 #define ADV_SUCCESS 1
2786 #define ADV_BUSY 0
2787 #define ADV_ERROR (-1)
2791 * ADV_DVC_VAR 'warn_code' values
2793 #define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
2794 #define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
2795 #define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
2796 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */
2797 #define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
2799 #define ADV_MAX_TID 15 /* max. target identifier */
2800 #define ADV_MAX_LUN 7 /* max. logical unit number */
2803 * Error code values are set in ADV_DVC_VAR 'err_code'.
2805 #define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */
2806 #define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
2807 #define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */
2808 #define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
2809 #define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */
2810 #define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
2811 #define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */
2812 #define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
2813 #define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
2814 #define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */
2815 #define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */
2816 #define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */
2817 #define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */
2818 #define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */
2821 * Fixed locations of microcode operating variables.
2823 #define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
2824 #define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
2825 #define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
2826 #define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
2827 #define ASC_MC_VERSION_NUM 0x003A /* microcode number */
2828 #define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
2829 #define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
2830 #define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
2831 #define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
2832 #define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
2833 #define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
2834 #define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
2835 #define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
2836 #define ASC_MC_CHIP_TYPE 0x009A
2837 #define ASC_MC_INTRB_CODE 0x009B
2838 #define ASC_MC_WDTR_ABLE 0x009C
2839 #define ASC_MC_SDTR_ABLE 0x009E
2840 #define ASC_MC_TAGQNG_ABLE 0x00A0
2841 #define ASC_MC_DISC_ENABLE 0x00A2
2842 #define ASC_MC_IDLE_CMD_STATUS 0x00A4
2843 #define ASC_MC_IDLE_CMD 0x00A6
2844 #define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
2845 #define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
2846 #define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
2847 #define ASC_MC_DEFAULT_MEM_CFG 0x00B0
2848 #define ASC_MC_DEFAULT_SEL_MASK 0x00B2
2849 #define ASC_MC_SDTR_DONE 0x00B6
2850 #define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
2851 #define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
2852 #define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
2853 #define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
2854 #define ASC_MC_WDTR_DONE 0x0124
2855 #define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
2856 #define ASC_MC_ICQ 0x0160
2857 #define ASC_MC_IRQ 0x0164
2858 #define ASC_MC_PPR_ABLE 0x017A
2861 * BIOS LRAM variable absolute offsets.
2863 #define BIOS_CODESEG 0x54
2864 #define BIOS_CODELEN 0x56
2865 #define BIOS_SIGNATURE 0x58
2866 #define BIOS_VERSION 0x5A
2869 * Microcode Control Flags
2871 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2872 * and handled by the microcode.
2874 #define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
2875 #define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
2878 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2880 #define HSHK_CFG_WIDE_XFR 0x8000
2881 #define HSHK_CFG_RATE 0x0F00
2882 #define HSHK_CFG_OFFSET 0x001F
2884 #define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
2885 #define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
2886 #define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
2887 #define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
2889 #define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2890 #define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
2891 #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2892 #define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
2893 #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2895 #define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
2896 #define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
2897 #define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
2898 #define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
2899 #define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
2901 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
2902 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
2904 #define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
2905 #define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
2908 * All fields here are accessed by the board microcode and need to be
2909 * little-endian.
2911 typedef struct adv_carr_t
2913 ADV_VADDR carr_va; /* Carrier Virtual Address */
2914 ADV_PADDR carr_pa; /* Carrier Physical Address */
2915 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
2917 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
2919 * next_vpa [3:1] Reserved Bits
2920 * next_vpa [0] Done Flag set in Response Queue.
2922 ADV_VADDR next_vpa;
2923 } ADV_CARR_T;
2926 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2928 #define ASC_NEXT_VPA_MASK 0xFFFFFFF0
2930 #define ASC_RQ_DONE 0x00000001
2931 #define ASC_RQ_GOOD 0x00000002
2932 #define ASC_CQ_STOPPER 0x00000000
2934 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2936 #define ADV_CARRIER_NUM_PAGE_CROSSING \
2937 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2938 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2940 #define ADV_CARRIER_BUFSIZE \
2941 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2944 * ASC_SCSI_REQ_Q 'a_flag' definitions
2946 * The Adv Library should limit use to the lower nibble (4 bits) of
2947 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2949 #define ADV_POLL_REQUEST 0x01 /* poll for request completion */
2950 #define ADV_SCSIQ_DONE 0x02 /* request done */
2951 #define ADV_DONT_RETRY 0x08 /* don't do retry */
2953 #define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
2954 #define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
2955 #define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
2958 * Adapter temporary configuration structure
2960 * This structure can be discarded after initialization. Don't add
2961 * fields here needed after initialization.
2963 * Field naming convention:
2965 * *_enable indicates the field enables or disables a feature. The
2966 * value of the field is never reset.
2968 typedef struct adv_dvc_cfg {
2969 ushort disc_enable; /* enable disconnection */
2970 uchar chip_version; /* chip version */
2971 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2972 ushort lib_version; /* Adv Library version number */
2973 ushort control_flag; /* Microcode Control Flag */
2974 ushort mcode_date; /* Microcode date */
2975 ushort mcode_version; /* Microcode version */
2976 ushort pci_slot_info; /* high byte device/function number */
2977 /* bits 7-3 device num., bits 2-0 function num. */
2978 /* low byte bus num. */
2979 ushort serial1; /* EEPROM serial number word 1 */
2980 ushort serial2; /* EEPROM serial number word 2 */
2981 ushort serial3; /* EEPROM serial number word 3 */
2982 struct device *dev; /* pointer to the pci dev structure for this board */
2983 } ADV_DVC_CFG;
2985 struct adv_dvc_var;
2986 struct adv_scsi_req_q;
2988 typedef void (* ADV_ISR_CALLBACK)
2989 (struct adv_dvc_var *, struct adv_scsi_req_q *);
2991 typedef void (* ADV_ASYNC_CALLBACK)
2992 (struct adv_dvc_var *, uchar);
2995 * Adapter operation variable structure.
2997 * One structure is required per host adapter.
2999 * Field naming convention:
3001 * *_able indicates both whether a feature should be enabled or disabled
3002 * and whether a device isi capable of the feature. At initialization
3003 * this field may be set, but later if a device is found to be incapable
3004 * of the feature, the field is cleared.
3006 typedef struct adv_dvc_var {
3007 AdvPortAddr iop_base; /* I/O port address */
3008 ushort err_code; /* fatal error code */
3009 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
3010 ADV_ISR_CALLBACK isr_callback;
3011 ADV_ASYNC_CALLBACK async_callback;
3012 ushort wdtr_able; /* try WDTR for a device */
3013 ushort sdtr_able; /* try SDTR for a device */
3014 ushort ultra_able; /* try SDTR Ultra speed for a device */
3015 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
3016 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
3017 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
3018 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
3019 ushort tagqng_able; /* try tagged queuing with a device */
3020 ushort ppr_able; /* PPR message capable per TID bitmask. */
3021 uchar max_dvc_qng; /* maximum number of tagged commands per device */
3022 ushort start_motor; /* start motor command allowed */
3023 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
3024 uchar chip_no; /* should be assigned by caller */
3025 uchar max_host_qng; /* maximum number of Q'ed command allowed */
3026 uchar irq_no; /* IRQ number */
3027 ushort no_scam; /* scam_tolerant of EEPROM */
3028 struct asc_board *drv_ptr; /* driver pointer to private structure */
3029 uchar chip_scsi_id; /* chip SCSI target ID */
3030 uchar chip_type;
3031 uchar bist_err_code;
3032 ADV_CARR_T *carrier_buf;
3033 ADV_CARR_T *carr_freelist; /* Carrier free list. */
3034 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
3035 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
3036 ushort carr_pending_cnt; /* Count of pending carriers. */
3038 * Note: The following fields will not be used after initialization. The
3039 * driver may discard the buffer after initialization is done.
3041 ADV_DVC_CFG *cfg; /* temporary configuration structure */
3042 } ADV_DVC_VAR;
3044 #define NO_OF_SG_PER_BLOCK 15
3046 typedef struct asc_sg_block {
3047 uchar reserved1;
3048 uchar reserved2;
3049 uchar reserved3;
3050 uchar sg_cnt; /* Valid entries in block. */
3051 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
3052 struct {
3053 ADV_PADDR sg_addr; /* SG element address. */
3054 ADV_DCNT sg_count; /* SG element count. */
3055 } sg_list[NO_OF_SG_PER_BLOCK];
3056 } ADV_SG_BLOCK;
3059 * ADV_SCSI_REQ_Q - microcode request structure
3061 * All fields in this structure up to byte 60 are used by the microcode.
3062 * The microcode makes assumptions about the size and ordering of fields
3063 * in this structure. Do not change the structure definition here without
3064 * coordinating the change with the microcode.
3066 * All fields accessed by microcode must be maintained in little_endian
3067 * order.
3069 typedef struct adv_scsi_req_q {
3070 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
3071 uchar target_cmd;
3072 uchar target_id; /* Device target identifier. */
3073 uchar target_lun; /* Device target logical unit number. */
3074 ADV_PADDR data_addr; /* Data buffer physical address. */
3075 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
3076 ADV_PADDR sense_addr;
3077 ADV_PADDR carr_pa;
3078 uchar mflag;
3079 uchar sense_len;
3080 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
3081 uchar scsi_cntl;
3082 uchar done_status; /* Completion status. */
3083 uchar scsi_status; /* SCSI status byte. */
3084 uchar host_status; /* Ucode host status. */
3085 uchar sg_working_ix;
3086 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
3087 ADV_PADDR sg_real_addr; /* SG list physical address. */
3088 ADV_PADDR scsiq_rptr;
3089 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
3090 ADV_VADDR scsiq_ptr;
3091 ADV_VADDR carr_va;
3093 * End of microcode structure - 60 bytes. The rest of the structure
3094 * is used by the Adv Library and ignored by the microcode.
3096 ADV_VADDR srb_ptr;
3097 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
3098 char *vdata_addr; /* Data buffer virtual address. */
3099 uchar a_flag;
3100 uchar pad[2]; /* Pad out to a word boundary. */
3101 } ADV_SCSI_REQ_Q;
3104 * Microcode idle loop commands
3106 #define IDLE_CMD_COMPLETED 0
3107 #define IDLE_CMD_STOP_CHIP 0x0001
3108 #define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
3109 #define IDLE_CMD_SEND_INT 0x0004
3110 #define IDLE_CMD_ABORT 0x0008
3111 #define IDLE_CMD_DEVICE_RESET 0x0010
3112 #define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
3113 #define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
3114 #define IDLE_CMD_SCSIREQ 0x0080
3116 #define IDLE_CMD_STATUS_SUCCESS 0x0001
3117 #define IDLE_CMD_STATUS_FAILURE 0x0002
3120 * AdvSendIdleCmd() flag definitions.
3122 #define ADV_NOWAIT 0x01
3125 * Wait loop time out values.
3127 #define SCSI_WAIT_10_SEC 10UL /* 10 seconds */
3128 #define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
3129 #define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
3130 #define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */
3131 #define SCSI_MAX_RETRY 10 /* retry count */
3133 #define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
3134 #define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
3135 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
3136 #define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
3139 #define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
3142 * Device drivers must define the following functions.
3144 STATIC inline ulong DvcEnterCritical(void);
3145 STATIC inline void DvcLeaveCritical(ulong);
3146 STATIC void DvcSleepMilliSecond(ADV_DCNT);
3147 STATIC uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
3148 STATIC void DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
3149 STATIC ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
3150 uchar *, ASC_SDCNT *, int);
3151 STATIC void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
3154 * Adv Library functions available to drivers.
3156 STATIC int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3157 STATIC int AdvISR(ADV_DVC_VAR *);
3158 STATIC int AdvInitGetConfig(ADV_DVC_VAR *);
3159 STATIC int AdvInitAsc3550Driver(ADV_DVC_VAR *);
3160 STATIC int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
3161 STATIC int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
3162 STATIC int AdvResetChipAndSB(ADV_DVC_VAR *);
3163 STATIC int AdvResetSB(ADV_DVC_VAR *asc_dvc);
3166 * Internal Adv Library functions.
3168 STATIC int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
3169 STATIC void AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3170 STATIC int AdvInitFrom3550EEP(ADV_DVC_VAR *);
3171 STATIC int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
3172 STATIC int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
3173 STATIC ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3174 STATIC void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3175 STATIC ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3176 STATIC void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3177 STATIC ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3178 STATIC void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3179 STATIC void AdvWaitEEPCmd(AdvPortAddr);
3180 STATIC ushort AdvReadEEPWord(AdvPortAddr, int);
3183 * PCI Bus Definitions
3185 #define AscPCICmdRegBits_BusMastering 0x0007
3186 #define AscPCICmdRegBits_ParErrRespCtrl 0x0040
3188 /* Read byte from a register. */
3189 #define AdvReadByteRegister(iop_base, reg_off) \
3190 (ADV_MEM_READB((iop_base) + (reg_off)))
3192 /* Write byte to a register. */
3193 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
3194 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3196 /* Read word (2 bytes) from a register. */
3197 #define AdvReadWordRegister(iop_base, reg_off) \
3198 (ADV_MEM_READW((iop_base) + (reg_off)))
3200 /* Write word (2 bytes) to a register. */
3201 #define AdvWriteWordRegister(iop_base, reg_off, word) \
3202 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
3204 /* Write dword (4 bytes) to a register. */
3205 #define AdvWriteDWordRegister(iop_base, reg_off, dword) \
3206 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
3208 /* Read byte from LRAM. */
3209 #define AdvReadByteLram(iop_base, addr, byte) \
3210 do { \
3211 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3212 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3213 } while (0)
3215 /* Write byte to LRAM. */
3216 #define AdvWriteByteLram(iop_base, addr, byte) \
3217 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3218 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3220 /* Read word (2 bytes) from LRAM. */
3221 #define AdvReadWordLram(iop_base, addr, word) \
3222 do { \
3223 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3224 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3225 } while (0)
3227 /* Write word (2 bytes) to LRAM. */
3228 #define AdvWriteWordLram(iop_base, addr, word) \
3229 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3230 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3232 /* Write little-endian double word (4 bytes) to LRAM */
3233 /* Because of unspecified C language ordering don't use auto-increment. */
3234 #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
3235 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3236 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3237 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3238 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3239 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3240 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3242 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
3243 #define AdvReadWordAutoIncLram(iop_base) \
3244 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3246 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
3247 #define AdvWriteWordAutoIncLram(iop_base, word) \
3248 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3252 * Define macro to check for Condor signature.
3254 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3255 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3257 #define AdvFindSignature(iop_base) \
3258 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3259 ADV_CHIP_ID_BYTE) && \
3260 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3261 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
3264 * Define macro to Return the version number of the chip at 'iop_base'.
3266 * The second parameter 'bus_type' is currently unused.
3268 #define AdvGetChipVersion(iop_base, bus_type) \
3269 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3272 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3273 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3275 * If the request has not yet been sent to the device it will simply be
3276 * aborted from RISC memory. If the request is disconnected it will be
3277 * aborted on reselection by sending an Abort Message to the target ID.
3279 * Return value:
3280 * ADV_TRUE(1) - Queue was successfully aborted.
3281 * ADV_FALSE(0) - Queue was not found on the active queue list.
3283 #define AdvAbortQueue(asc_dvc, scsiq) \
3284 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3285 (ADV_DCNT) (scsiq))
3288 * Send a Bus Device Reset Message to the specified target ID.
3290 * All outstanding commands will be purged if sending the
3291 * Bus Device Reset Message is successful.
3293 * Return Value:
3294 * ADV_TRUE(1) - All requests on the target are purged.
3295 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3296 * are not purged.
3298 #define AdvResetDevice(asc_dvc, target_id) \
3299 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3300 (ADV_DCNT) (target_id))
3303 * SCSI Wide Type definition.
3305 #define ADV_SCSI_BIT_ID_TYPE ushort
3308 * AdvInitScsiTarget() 'cntl_flag' options.
3310 #define ADV_SCAN_LUN 0x01
3311 #define ADV_CAPINFO_NOLUN 0x02
3314 * Convert target id to target id bit mask.
3316 #define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
3319 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3322 #define QD_NO_STATUS 0x00 /* Request not completed yet. */
3323 #define QD_NO_ERROR 0x01
3324 #define QD_ABORTED_BY_HOST 0x02
3325 #define QD_WITH_ERROR 0x04
3327 #define QHSTA_NO_ERROR 0x00
3328 #define QHSTA_M_SEL_TIMEOUT 0x11
3329 #define QHSTA_M_DATA_OVER_RUN 0x12
3330 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3331 #define QHSTA_M_QUEUE_ABORTED 0x15
3332 #define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
3333 #define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
3334 #define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
3335 #define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
3336 #define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
3337 #define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
3338 #define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
3339 /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
3340 #define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
3341 #define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
3342 #define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
3343 #define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
3344 #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
3345 #define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
3346 #define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
3347 #define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
3348 #define QHSTA_M_WTM_TIMEOUT 0x41
3349 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
3350 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
3351 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
3352 #define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
3353 #define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
3354 #define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
3358 * Default EEPROM Configuration structure defined in a_init.c.
3360 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
3361 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
3362 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
3365 * DvcGetPhyAddr() flag arguments
3367 #define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
3368 #define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
3369 #define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
3370 #define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
3371 #define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
3372 #define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
3374 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
3375 #define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
3376 #define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
3377 #define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
3380 * Total contiguous memory needed for driver SG blocks.
3382 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3383 * number of scatter-gather elements the driver supports in a
3384 * single request.
3387 #define ADV_SG_LIST_MAX_BYTE_SIZE \
3388 (sizeof(ADV_SG_BLOCK) * \
3389 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3392 * Inquiry data structure and bitfield macros
3394 * Using bitfields to access the subchar data isn't portable across
3395 * endianness, so instead mask and shift. Only quantities of more
3396 * than 1 bit are shifted, since the others are just tested for true
3397 * or false.
3400 #define ADV_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f)
3401 #define ADV_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5)
3402 #define ADV_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f)
3403 #define ADV_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80)
3404 #define ADV_INQ_ANSI_VER(inq) ((inq)->ver & 0x07)
3405 #define ADV_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3)
3406 #define ADV_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6)
3407 #define ADV_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f)
3408 #define ADV_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40)
3409 #define ADV_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80)
3410 #define ADV_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01)
3411 #define ADV_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02)
3412 #define ADV_INQ_LINK_CMD(inq) ((inq)->flags & 0x08)
3413 #define ADV_INQ_SYNC(inq) ((inq)->flags & 0x10)
3414 #define ADV_INQ_WIDE16(inq) ((inq)->flags & 0x20)
3415 #define ADV_INQ_WIDE32(inq) ((inq)->flags & 0x40)
3416 #define ADV_INQ_REL_ADDR(inq) ((inq)->flags & 0x80)
3417 #define ADV_INQ_INFO_UNIT(inq) ((inq)->info & 0x01)
3418 #define ADV_INQ_QUICK_ARB(inq) ((inq)->info & 0x02)
3419 #define ADV_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2)
3421 typedef struct {
3422 uchar periph; /* peripheral device type [0:4] */
3423 /* peripheral qualifier [5:7] */
3424 uchar devtype; /* device type modifier (for SCSI I) [0:6] */
3425 /* RMB - removable medium bit [7] */
3426 uchar ver; /* ANSI approved version [0:2] */
3427 /* ECMA version [3:5] */
3428 /* ISO version [6:7] */
3429 uchar byte3; /* response data format [0:3] */
3430 /* 0 SCSI 1 */
3431 /* 1 CCS */
3432 /* 2 SCSI-2 */
3433 /* 3-F reserved */
3434 /* reserved [4:5] */
3435 /* terminate I/O process bit (see 5.6.22) [6] */
3436 /* asynch. event notification (processor) [7] */
3437 uchar add_len; /* additional length */
3438 uchar res1; /* reserved */
3439 uchar res2; /* reserved */
3440 uchar flags; /* soft reset implemented [0] */
3441 /* command queuing [1] */
3442 /* reserved [2] */
3443 /* linked command for this logical unit [3] */
3444 /* synchronous data transfer [4] */
3445 /* wide bus 16 bit data transfer [5] */
3446 /* wide bus 32 bit data transfer [6] */
3447 /* relative addressing mode [7] */
3448 uchar vendor_id[8]; /* vendor identification */
3449 uchar product_id[16]; /* product identification */
3450 uchar product_rev_level[4]; /* product revision level */
3451 uchar vendor_specific[20]; /* vendor specific */
3452 uchar info; /* information unit supported [0] */
3453 /* quick arbitrate supported [1] */
3454 /* clocking field [2:3] */
3455 /* reserved [4:7] */
3456 uchar res3; /* reserved */
3457 } ADV_SCSI_INQUIRY; /* 58 bytes */
3461 * --- Driver Constants and Macros
3464 #define ASC_NUM_BOARD_SUPPORTED 16
3465 #define ASC_NUM_IOPORT_PROBE 4
3466 #define ASC_NUM_BUS 4
3468 /* Reference Scsi_Host hostdata */
3469 #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3471 /* asc_board_t flags */
3472 #define ASC_HOST_IN_RESET 0x01
3473 #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
3474 #define ASC_SELECT_QUEUE_DEPTHS 0x08
3476 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3477 #define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD)
3479 #define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
3481 #define ASC_INFO_SIZE 128 /* advansys_info() line size */
3483 #ifdef CONFIG_PROC_FS
3484 /* /proc/scsi/advansys/[0...] related definitions */
3485 #define ASC_PRTBUF_SIZE 2048
3486 #define ASC_PRTLINE_SIZE 160
3488 #define ASC_PRT_NEXT() \
3489 if (cp) { \
3490 totlen += len; \
3491 leftlen -= len; \
3492 if (leftlen == 0) { \
3493 return totlen; \
3495 cp += len; \
3497 #endif /* CONFIG_PROC_FS */
3499 /* Asc Library return codes */
3500 #define ASC_TRUE 1
3501 #define ASC_FALSE 0
3502 #define ASC_NOERROR 1
3503 #define ASC_BUSY 0
3504 #define ASC_ERROR (-1)
3506 /* struct scsi_cmnd function return codes */
3507 #define STATUS_BYTE(byte) (byte)
3508 #define MSG_BYTE(byte) ((byte) << 8)
3509 #define HOST_BYTE(byte) ((byte) << 16)
3510 #define DRIVER_BYTE(byte) ((byte) << 24)
3513 * The following definitions and macros are OS independent interfaces to
3514 * the queue functions:
3515 * REQ - SCSI request structure
3516 * REQP - pointer to SCSI request structure
3517 * REQPTID(reqp) - reqp's target id
3518 * REQPNEXT(reqp) - reqp's next pointer
3519 * REQPNEXTP(reqp) - pointer to reqp's next pointer
3520 * REQPTIME(reqp) - reqp's time stamp value
3521 * REQTIMESTAMP() - system time stamp value
3523 typedef struct scsi_cmnd REQ, *REQP;
3524 #define REQPNEXT(reqp) ((REQP) ((reqp)->host_scribble))
3525 #define REQPNEXTP(reqp) ((REQP *) &((reqp)->host_scribble))
3526 #define REQPTID(reqp) ((reqp)->device->id)
3527 #define REQPTIME(reqp) ((reqp)->SCp.this_residual)
3528 #define REQTIMESTAMP() (jiffies)
3530 #define REQTIMESTAT(function, ascq, reqp, tid) \
3533 * If the request time stamp is less than the system time stamp, then \
3534 * maybe the system time stamp wrapped. Set the request time to zero.\
3535 */ \
3536 if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3537 REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3538 } else { \
3539 /* Indicate an error occurred with the assertion. */ \
3540 ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3541 REQPTIME(reqp) = 0; \
3543 /* Handle first minimum time case without external initialization. */ \
3544 if (((ascq)->q_tot_cnt[tid] == 1) || \
3545 (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3546 (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3547 ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3548 (function), (tid), (ascq)->q_min_tim[tid]); \
3550 if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3551 (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3552 ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3553 (function), tid, (ascq)->q_max_tim[tid]); \
3555 (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3556 /* Reset the time stamp field. */ \
3557 REQPTIME(reqp) = 0; \
3560 /* asc_enqueue() flags */
3561 #define ASC_FRONT 1
3562 #define ASC_BACK 2
3564 /* asc_dequeue_list() argument */
3565 #define ASC_TID_ALL (-1)
3567 /* Return non-zero, if the queue is empty. */
3568 #define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0)
3570 #define PCI_MAX_SLOT 0x1F
3571 #define PCI_MAX_BUS 0xFF
3572 #define PCI_IOADDRESS_MASK 0xFFFE
3573 #define ASC_PCI_VENDORID 0x10CD
3574 #define ASC_PCI_DEVICE_ID_CNT 6 /* PCI Device ID count. */
3575 #define ASC_PCI_DEVICE_ID_1100 0x1100
3576 #define ASC_PCI_DEVICE_ID_1200 0x1200
3577 #define ASC_PCI_DEVICE_ID_1300 0x1300
3578 #define ASC_PCI_DEVICE_ID_2300 0x2300 /* ASC-3550 */
3579 #define ASC_PCI_DEVICE_ID_2500 0x2500 /* ASC-38C0800 */
3580 #define ASC_PCI_DEVICE_ID_2700 0x2700 /* ASC-38C1600 */
3582 #ifndef ADVANSYS_STATS
3583 #define ASC_STATS(shp, counter)
3584 #define ASC_STATS_ADD(shp, counter, count)
3585 #else /* ADVANSYS_STATS */
3586 #define ASC_STATS(shp, counter) \
3587 (ASC_BOARDP(shp)->asc_stats.counter++)
3589 #define ASC_STATS_ADD(shp, counter, count) \
3590 (ASC_BOARDP(shp)->asc_stats.counter += (count))
3591 #endif /* ADVANSYS_STATS */
3593 #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3595 /* If the result wraps when calculating tenths, return 0. */
3596 #define ASC_TENTHS(num, den) \
3597 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3598 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3601 * Display a message to the console.
3603 #define ASC_PRINT(s) \
3605 printk("advansys: "); \
3606 printk(s); \
3609 #define ASC_PRINT1(s, a1) \
3611 printk("advansys: "); \
3612 printk((s), (a1)); \
3615 #define ASC_PRINT2(s, a1, a2) \
3617 printk("advansys: "); \
3618 printk((s), (a1), (a2)); \
3621 #define ASC_PRINT3(s, a1, a2, a3) \
3623 printk("advansys: "); \
3624 printk((s), (a1), (a2), (a3)); \
3627 #define ASC_PRINT4(s, a1, a2, a3, a4) \
3629 printk("advansys: "); \
3630 printk((s), (a1), (a2), (a3), (a4)); \
3634 #ifndef ADVANSYS_DEBUG
3636 #define ASC_DBG(lvl, s)
3637 #define ASC_DBG1(lvl, s, a1)
3638 #define ASC_DBG2(lvl, s, a1, a2)
3639 #define ASC_DBG3(lvl, s, a1, a2, a3)
3640 #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3641 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3642 #define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3643 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3644 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3645 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3646 #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3647 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
3648 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
3649 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
3650 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3652 #else /* ADVANSYS_DEBUG */
3655 * Debugging Message Levels:
3656 * 0: Errors Only
3657 * 1: High-Level Tracing
3658 * 2-N: Verbose Tracing
3661 #define ASC_DBG(lvl, s) \
3663 if (asc_dbglvl >= (lvl)) { \
3664 printk(s); \
3668 #define ASC_DBG1(lvl, s, a1) \
3670 if (asc_dbglvl >= (lvl)) { \
3671 printk((s), (a1)); \
3675 #define ASC_DBG2(lvl, s, a1, a2) \
3677 if (asc_dbglvl >= (lvl)) { \
3678 printk((s), (a1), (a2)); \
3682 #define ASC_DBG3(lvl, s, a1, a2, a3) \
3684 if (asc_dbglvl >= (lvl)) { \
3685 printk((s), (a1), (a2), (a3)); \
3689 #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3691 if (asc_dbglvl >= (lvl)) { \
3692 printk((s), (a1), (a2), (a3), (a4)); \
3696 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3698 if (asc_dbglvl >= (lvl)) { \
3699 asc_prt_scsi_host(s); \
3703 #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3705 if (asc_dbglvl >= (lvl)) { \
3706 asc_prt_scsi_cmnd(s); \
3710 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3712 if (asc_dbglvl >= (lvl)) { \
3713 asc_prt_asc_scsi_q(scsiqp); \
3717 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3719 if (asc_dbglvl >= (lvl)) { \
3720 asc_prt_asc_qdone_info(qdone); \
3724 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3726 if (asc_dbglvl >= (lvl)) { \
3727 asc_prt_adv_scsi_req_q(scsiqp); \
3731 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3733 if (asc_dbglvl >= (lvl)) { \
3734 asc_prt_hex((name), (start), (length)); \
3738 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3739 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3741 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3742 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3744 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3745 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3746 #endif /* ADVANSYS_DEBUG */
3748 #ifndef ADVANSYS_ASSERT
3749 #define ASC_ASSERT(a)
3750 #else /* ADVANSYS_ASSERT */
3752 #define ASC_ASSERT(a) \
3754 if (!(a)) { \
3755 printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3756 __FILE__, __LINE__); \
3760 #endif /* ADVANSYS_ASSERT */
3764 * --- Driver Structures
3767 #ifdef ADVANSYS_STATS
3769 /* Per board statistics structure */
3770 struct asc_stats {
3771 /* Driver Entrypoint Statistics */
3772 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
3773 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
3774 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
3775 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
3776 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
3777 ADV_DCNT done; /* # calls to request's scsi_done function */
3778 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
3779 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
3780 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
3781 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3782 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
3783 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
3784 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
3785 ADV_DCNT exe_unknown; /* # unknown returns. */
3786 /* Data Transfer Statistics */
3787 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
3788 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
3789 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
3790 ADV_DCNT sg_elem; /* # scatter-gather elements */
3791 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
3793 #endif /* ADVANSYS_STATS */
3796 * Request queuing structure
3798 typedef struct asc_queue {
3799 ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */
3800 REQP q_first[ADV_MAX_TID+1]; /* first queued request */
3801 REQP q_last[ADV_MAX_TID+1]; /* last queued request */
3802 #ifdef ADVANSYS_STATS
3803 short q_cur_cnt[ADV_MAX_TID+1]; /* current queue count */
3804 short q_max_cnt[ADV_MAX_TID+1]; /* maximum queue count */
3805 ADV_DCNT q_tot_cnt[ADV_MAX_TID+1]; /* total enqueue count */
3806 ADV_DCNT q_tot_tim[ADV_MAX_TID+1]; /* total time queued */
3807 ushort q_max_tim[ADV_MAX_TID+1]; /* maximum time queued */
3808 ushort q_min_tim[ADV_MAX_TID+1]; /* minimum time queued */
3809 #endif /* ADVANSYS_STATS */
3810 } asc_queue_t;
3813 * Adv Library Request Structures
3815 * The following two structures are used to process Wide Board requests.
3817 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
3818 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
3819 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
3820 * Mid-Level SCSI request structure.
3822 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
3823 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
3824 * up to 255 scatter-gather elements may be used per request or
3825 * ADV_SCSI_REQ_Q.
3827 * Both structures must be 32 byte aligned.
3829 typedef struct adv_sgblk {
3830 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
3831 uchar align[32]; /* Sgblock structure padding. */
3832 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
3833 } adv_sgblk_t;
3835 typedef struct adv_req {
3836 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
3837 uchar align[32]; /* Request structure padding. */
3838 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
3839 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
3840 struct adv_req *next_reqp; /* Next Request Structure. */
3841 } adv_req_t;
3844 * Structure allocated for each board.
3846 * This structure is allocated by scsi_register() at the end
3847 * of the 'Scsi_Host' structure starting at the 'hostdata'
3848 * field. It is guaranteed to be allocated from DMA-able memory.
3850 typedef struct asc_board {
3851 int id; /* Board Id */
3852 uint flags; /* Board flags */
3853 union {
3854 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
3855 ADV_DVC_VAR adv_dvc_var; /* Wide board */
3856 } dvc_var;
3857 union {
3858 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
3859 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
3860 } dvc_cfg;
3861 ushort asc_n_io_port; /* Number I/O ports. */
3862 asc_queue_t active; /* Active command queue */
3863 asc_queue_t waiting; /* Waiting command queue */
3864 asc_queue_t done; /* Done command queue */
3865 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
3866 struct scsi_device *device[ADV_MAX_TID+1]; /* Mid-Level Scsi Device */
3867 ushort reqcnt[ADV_MAX_TID+1]; /* Starvation request count */
3868 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
3869 ushort queue_full_cnt[ADV_MAX_TID+1]; /* Queue full count */
3870 union {
3871 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
3872 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
3873 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
3874 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
3875 } eep_config;
3876 ulong last_reset; /* Saved last reset time */
3877 spinlock_t lock; /* Board spinlock */
3878 #ifdef CONFIG_PROC_FS
3879 /* /proc/scsi/advansys/[0...] */
3880 char *prtbuf; /* /proc print buffer */
3881 #endif /* CONFIG_PROC_FS */
3882 #ifdef ADVANSYS_STATS
3883 struct asc_stats asc_stats; /* Board statistics */
3884 #endif /* ADVANSYS_STATS */
3886 * The following fields are used only for Narrow Boards.
3888 /* The following three structures must be in DMA-able memory. */
3889 ASC_SCSI_REQ_Q scsireqq;
3890 ASC_CAP_INFO cap_info;
3891 ASC_SCSI_INQUIRY inquiry;
3892 uchar sdtr_data[ASC_MAX_TID+1]; /* SDTR information */
3894 * The following fields are used only for Wide Boards.
3896 void *ioremap_addr; /* I/O Memory remap address. */
3897 ushort ioport; /* I/O Port address. */
3898 ADV_CARR_T *orig_carrp; /* ADV_CARR_T memory block. */
3899 adv_req_t *orig_reqp; /* adv_req_t memory block. */
3900 adv_req_t *adv_reqp; /* Request structures. */
3901 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
3902 ushort bios_signature; /* BIOS Signature. */
3903 ushort bios_version; /* BIOS Version. */
3904 ushort bios_codeseg; /* BIOS Code Segment. */
3905 ushort bios_codelen; /* BIOS Code Segment Length. */
3906 } asc_board_t;
3909 * PCI configuration structures
3911 typedef struct _PCI_DATA_
3913 uchar type;
3914 uchar bus;
3915 uchar slot;
3916 uchar func;
3917 uchar offset;
3918 } PCI_DATA;
3920 typedef struct _PCI_DEVICE_
3922 ushort vendorID;
3923 ushort deviceID;
3924 ushort slotNumber;
3925 ushort slotFound;
3926 uchar busNumber;
3927 uchar maxBusNumber;
3928 uchar devFunc;
3929 ushort startSlot;
3930 ushort endSlot;
3931 uchar bridge;
3932 uchar type;
3933 } PCI_DEVICE;
3935 typedef struct _PCI_CONFIG_SPACE_
3937 ushort vendorID;
3938 ushort deviceID;
3939 ushort command;
3940 ushort status;
3941 uchar revision;
3942 uchar classCode[3];
3943 uchar cacheSize;
3944 uchar latencyTimer;
3945 uchar headerType;
3946 uchar bist;
3947 ADV_PADDR baseAddress[6];
3948 ushort reserved[4];
3949 ADV_PADDR optionRomAddr;
3950 ushort reserved2[4];
3951 uchar irqLine;
3952 uchar irqPin;
3953 uchar minGnt;
3954 uchar maxLatency;
3955 } PCI_CONFIG_SPACE;
3959 * --- Driver Data
3962 /* Note: All driver global data should be initialized. */
3964 /* Number of boards detected in system. */
3965 STATIC int asc_board_count = 0;
3966 STATIC struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { 0 };
3968 /* Overrun buffer used by all narrow boards. */
3969 STATIC uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
3972 * Global structures required to issue a command.
3974 STATIC ASC_SCSI_Q asc_scsi_q = { { 0 } };
3975 STATIC ASC_SG_HEAD asc_sg_head = { 0 };
3977 /* List of supported bus types. */
3978 STATIC ushort asc_bus[ASC_NUM_BUS] __initdata = {
3979 ASC_IS_ISA,
3980 ASC_IS_VL,
3981 ASC_IS_EISA,
3982 ASC_IS_PCI,
3986 * Used with the LILO 'advansys' option to eliminate or
3987 * limit I/O port probing at boot time, cf. advansys_setup().
3989 STATIC int asc_iopflag = ASC_FALSE;
3990 STATIC int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
3992 #ifdef ADVANSYS_DEBUG
3993 STATIC char *
3994 asc_bus_name[ASC_NUM_BUS] = {
3995 "ASC_IS_ISA",
3996 "ASC_IS_VL",
3997 "ASC_IS_EISA",
3998 "ASC_IS_PCI",
4001 STATIC int asc_dbglvl = 3;
4002 #endif /* ADVANSYS_DEBUG */
4004 /* Declaration for Asc Library internal data referenced by driver. */
4005 STATIC PortAddr _asc_def_iop_base[];
4009 * --- Driver Function Prototypes
4011 * advansys.h contains function prototypes for functions global to Linux.
4014 STATIC irqreturn_t advansys_interrupt(int, void *, struct pt_regs *);
4015 STATIC int advansys_slave_configure(struct scsi_device *);
4016 STATIC void asc_scsi_done_list(struct scsi_cmnd *);
4017 STATIC int asc_execute_scsi_cmnd(struct scsi_cmnd *);
4018 STATIC int asc_build_req(asc_board_t *, struct scsi_cmnd *);
4019 STATIC int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
4020 STATIC int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
4021 STATIC void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
4022 STATIC void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
4023 STATIC void adv_async_callback(ADV_DVC_VAR *, uchar);
4024 STATIC void asc_enqueue(asc_queue_t *, REQP, int);
4025 STATIC REQP asc_dequeue(asc_queue_t *, int);
4026 STATIC REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
4027 STATIC int asc_rmqueue(asc_queue_t *, REQP);
4028 STATIC void asc_execute_queue(asc_queue_t *);
4029 #ifdef CONFIG_PROC_FS
4030 STATIC int asc_proc_copy(off_t, off_t, char *, int , char *, int);
4031 STATIC int asc_prt_board_devices(struct Scsi_Host *, char *, int);
4032 STATIC int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
4033 STATIC int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
4034 STATIC int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
4035 STATIC int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
4036 STATIC int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
4037 STATIC int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
4038 STATIC int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
4039 STATIC int asc_prt_line(char *, int, char *fmt, ...);
4040 #endif /* CONFIG_PROC_FS */
4042 /* Declaration for Asc Library internal functions referenced by driver. */
4043 STATIC int AscFindSignature(PortAddr);
4044 STATIC ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
4046 /* Statistics function prototypes. */
4047 #ifdef ADVANSYS_STATS
4048 #ifdef CONFIG_PROC_FS
4049 STATIC int asc_prt_board_stats(struct Scsi_Host *, char *, int);
4050 STATIC int asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
4051 #endif /* CONFIG_PROC_FS */
4052 #endif /* ADVANSYS_STATS */
4054 /* Debug function prototypes. */
4055 #ifdef ADVANSYS_DEBUG
4056 STATIC void asc_prt_scsi_host(struct Scsi_Host *);
4057 STATIC void asc_prt_scsi_cmnd(struct scsi_cmnd *);
4058 STATIC void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
4059 STATIC void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
4060 STATIC void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
4061 STATIC void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
4062 STATIC void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
4063 STATIC void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
4064 STATIC void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
4065 STATIC void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
4066 STATIC void asc_prt_hex(char *f, uchar *, int);
4067 #endif /* ADVANSYS_DEBUG */
4071 * --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
4074 #ifdef CONFIG_PROC_FS
4076 * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
4078 * *buffer: I/O buffer
4079 * **start: if inout == FALSE pointer into buffer where user read should start
4080 * offset: current offset into a /proc/scsi/advansys/[0...] file
4081 * length: length of buffer
4082 * hostno: Scsi_Host host_no
4083 * inout: TRUE - user is writing; FALSE - user is reading
4085 * Return the number of bytes read from or written to a
4086 * /proc/scsi/advansys/[0...] file.
4088 * Note: This function uses the per board buffer 'prtbuf' which is
4089 * allocated when the board is initialized in advansys_detect(). The
4090 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
4091 * used to write to the buffer. The way asc_proc_copy() is written
4092 * if 'prtbuf' is too small it will not be overwritten. Instead the
4093 * user just won't get all the available statistics.
4096 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
4097 off_t offset, int length, int inout)
4099 struct Scsi_Host *shp;
4100 asc_board_t *boardp;
4101 int i;
4102 char *cp;
4103 int cplen;
4104 int cnt;
4105 int totcnt;
4106 int leftlen;
4107 char *curbuf;
4108 off_t advoffset;
4109 #ifdef ADVANSYS_STATS
4110 int tgt_id;
4111 #endif /* ADVANSYS_STATS */
4113 ASC_DBG(1, "advansys_proc_info: begin\n");
4116 * User write not supported.
4118 if (inout == TRUE) {
4119 return(-ENOSYS);
4123 * User read of /proc/scsi/advansys/[0...] file.
4126 /* Find the specified board. */
4127 for (i = 0; i < asc_board_count; i++) {
4128 if (asc_host[i]->host_no == shost->host_no) {
4129 break;
4132 if (i == asc_board_count) {
4133 return(-ENOENT);
4136 shp = asc_host[i];
4137 boardp = ASC_BOARDP(shp);
4139 /* Copy read data starting at the beginning of the buffer. */
4140 *start = buffer;
4141 curbuf = buffer;
4142 advoffset = 0;
4143 totcnt = 0;
4144 leftlen = length;
4147 * Get board configuration information.
4149 * advansys_info() returns the board string from its own static buffer.
4151 cp = (char *) advansys_info(shp);
4152 strcat(cp, "\n");
4153 cplen = strlen(cp);
4154 /* Copy board information. */
4155 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4156 totcnt += cnt;
4157 leftlen -= cnt;
4158 if (leftlen == 0) {
4159 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4160 return totcnt;
4162 advoffset += cplen;
4163 curbuf += cnt;
4166 * Display Wide Board BIOS Information.
4168 if (ASC_WIDE_BOARD(boardp)) {
4169 cp = boardp->prtbuf;
4170 cplen = asc_prt_adv_bios(shp, cp, ASC_PRTBUF_SIZE);
4171 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4172 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4173 totcnt += cnt;
4174 leftlen -= cnt;
4175 if (leftlen == 0) {
4176 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4177 return totcnt;
4179 advoffset += cplen;
4180 curbuf += cnt;
4184 * Display driver information for each device attached to the board.
4186 cp = boardp->prtbuf;
4187 cplen = asc_prt_board_devices(shp, cp, ASC_PRTBUF_SIZE);
4188 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4189 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4190 totcnt += cnt;
4191 leftlen -= cnt;
4192 if (leftlen == 0) {
4193 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4194 return totcnt;
4196 advoffset += cplen;
4197 curbuf += cnt;
4200 * Display EEPROM configuration for the board.
4202 cp = boardp->prtbuf;
4203 if (ASC_NARROW_BOARD(boardp)) {
4204 cplen = asc_prt_asc_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4205 } else {
4206 cplen = asc_prt_adv_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4208 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4209 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4210 totcnt += cnt;
4211 leftlen -= cnt;
4212 if (leftlen == 0) {
4213 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4214 return totcnt;
4216 advoffset += cplen;
4217 curbuf += cnt;
4220 * Display driver configuration and information for the board.
4222 cp = boardp->prtbuf;
4223 cplen = asc_prt_driver_conf(shp, cp, ASC_PRTBUF_SIZE);
4224 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4225 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4226 totcnt += cnt;
4227 leftlen -= cnt;
4228 if (leftlen == 0) {
4229 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4230 return totcnt;
4232 advoffset += cplen;
4233 curbuf += cnt;
4235 #ifdef ADVANSYS_STATS
4237 * Display driver statistics for the board.
4239 cp = boardp->prtbuf;
4240 cplen = asc_prt_board_stats(shp, cp, ASC_PRTBUF_SIZE);
4241 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4242 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4243 totcnt += cnt;
4244 leftlen -= cnt;
4245 if (leftlen == 0) {
4246 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4247 return totcnt;
4249 advoffset += cplen;
4250 curbuf += cnt;
4253 * Display driver statistics for each target.
4255 for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
4256 cp = boardp->prtbuf;
4257 cplen = asc_prt_target_stats(shp, tgt_id, cp, ASC_PRTBUF_SIZE);
4258 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4259 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4260 totcnt += cnt;
4261 leftlen -= cnt;
4262 if (leftlen == 0) {
4263 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4264 return totcnt;
4266 advoffset += cplen;
4267 curbuf += cnt;
4269 #endif /* ADVANSYS_STATS */
4272 * Display Asc Library dynamic configuration information
4273 * for the board.
4275 cp = boardp->prtbuf;
4276 if (ASC_NARROW_BOARD(boardp)) {
4277 cplen = asc_prt_asc_board_info(shp, cp, ASC_PRTBUF_SIZE);
4278 } else {
4279 cplen = asc_prt_adv_board_info(shp, cp, ASC_PRTBUF_SIZE);
4281 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4282 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4283 totcnt += cnt;
4284 leftlen -= cnt;
4285 if (leftlen == 0) {
4286 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4287 return totcnt;
4289 advoffset += cplen;
4290 curbuf += cnt;
4292 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4294 return totcnt;
4296 #endif /* CONFIG_PROC_FS */
4299 * advansys_detect()
4301 * Detect function for AdvanSys adapters.
4303 * Argument is a pointer to the host driver's scsi_hosts entry.
4305 * Return number of adapters found.
4307 * Note: Because this function is called during system initialization
4308 * it must not call SCSI mid-level functions including scsi_malloc()
4309 * and scsi_free().
4311 int __init
4312 advansys_detect(struct scsi_host_template *tpnt)
4314 static int detect_called = ASC_FALSE;
4315 int iop;
4316 int bus;
4317 struct Scsi_Host *shp = NULL;
4318 asc_board_t *boardp = NULL;
4319 ASC_DVC_VAR *asc_dvc_varp = NULL;
4320 ADV_DVC_VAR *adv_dvc_varp = NULL;
4321 adv_sgblk_t *sgp = NULL;
4322 int ioport = 0;
4323 int share_irq = FALSE;
4324 int iolen = 0;
4325 struct device *dev = NULL;
4326 #ifdef CONFIG_PCI
4327 int pci_init_search = 0;
4328 struct pci_dev *pci_devicep[ASC_NUM_BOARD_SUPPORTED];
4329 int pci_card_cnt_max = 0;
4330 int pci_card_cnt = 0;
4331 struct pci_dev *pci_devp = NULL;
4332 int pci_device_id_cnt = 0;
4333 unsigned int pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
4334 ASC_PCI_DEVICE_ID_1100,
4335 ASC_PCI_DEVICE_ID_1200,
4336 ASC_PCI_DEVICE_ID_1300,
4337 ASC_PCI_DEVICE_ID_2300,
4338 ASC_PCI_DEVICE_ID_2500,
4339 ASC_PCI_DEVICE_ID_2700
4341 ADV_PADDR pci_memory_address;
4342 #endif /* CONFIG_PCI */
4343 int warn_code, err_code;
4344 int ret;
4346 if (detect_called == ASC_FALSE) {
4347 detect_called = ASC_TRUE;
4348 } else {
4349 printk("AdvanSys SCSI: advansys_detect() multiple calls ignored\n");
4350 return 0;
4353 ASC_DBG(1, "advansys_detect: begin\n");
4355 asc_board_count = 0;
4358 * If I/O port probing has been modified, then verify and
4359 * clean-up the 'asc_ioport' list.
4361 if (asc_iopflag == ASC_TRUE) {
4362 for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
4363 ASC_DBG2(1, "advansys_detect: asc_ioport[%d] 0x%x\n",
4364 ioport, asc_ioport[ioport]);
4365 if (asc_ioport[ioport] != 0) {
4366 for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX; iop++) {
4367 if (_asc_def_iop_base[iop] == asc_ioport[ioport]) {
4368 break;
4371 if (iop == ASC_IOADR_TABLE_MAX_IX) {
4372 printk(
4373 "AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
4374 asc_ioport[ioport]);
4375 asc_ioport[ioport] = 0;
4379 ioport = 0;
4382 for (bus = 0; bus < ASC_NUM_BUS; bus++) {
4384 ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
4385 bus, asc_bus_name[bus]);
4386 iop = 0;
4388 while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) {
4390 ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
4391 asc_board_count);
4393 switch (asc_bus[bus]) {
4394 case ASC_IS_ISA:
4395 case ASC_IS_VL:
4396 #ifdef CONFIG_ISA
4397 if (asc_iopflag == ASC_FALSE) {
4398 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4399 } else {
4401 * ISA and VL I/O port scanning has either been
4402 * eliminated or limited to selected ports on
4403 * the LILO command line, /etc/lilo.conf, or
4404 * by setting variables when the module was loaded.
4406 ASC_DBG(1, "advansys_detect: I/O port scanning modified\n");
4407 ioport_try_again:
4408 iop = 0;
4409 for (; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
4410 if ((iop = asc_ioport[ioport]) != 0) {
4411 break;
4414 if (iop) {
4415 ASC_DBG1(1,
4416 "advansys_detect: probing I/O port 0x%x...\n",
4417 iop);
4418 if (check_region(iop, ASC_IOADR_GAP) != 0) {
4419 printk(
4420 "AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop);
4421 /* Don't try this I/O port twice. */
4422 asc_ioport[ioport] = 0;
4423 goto ioport_try_again;
4424 } else if (AscFindSignature(iop) == ASC_FALSE) {
4425 printk(
4426 "AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop);
4427 /* Don't try this I/O port twice. */
4428 asc_ioport[ioport] = 0;
4429 goto ioport_try_again;
4430 } else {
4432 * If this isn't an ISA board, then it must be
4433 * a VL board. If currently looking an ISA
4434 * board is being looked for then try for
4435 * another ISA board in 'asc_ioport'.
4437 if (asc_bus[bus] == ASC_IS_ISA &&
4438 (AscGetChipVersion(iop, ASC_IS_ISA) &
4439 ASC_CHIP_VER_ISA_BIT) == 0) {
4441 * Don't clear 'asc_ioport[ioport]'. Try
4442 * this board again for VL. Increment
4443 * 'ioport' past this board.
4445 ioport++;
4446 goto ioport_try_again;
4450 * This board appears good, don't try the I/O port
4451 * again by clearing its value. Increment 'ioport'
4452 * for the next iteration.
4454 asc_ioport[ioport++] = 0;
4457 #endif /* CONFIG_ISA */
4458 break;
4460 case ASC_IS_EISA:
4461 #ifdef CONFIG_ISA
4462 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4463 #endif /* CONFIG_ISA */
4464 break;
4466 case ASC_IS_PCI:
4467 #ifdef CONFIG_PCI
4468 if (pci_init_search == 0) {
4469 int i, j;
4471 pci_init_search = 1;
4473 /* Find all PCI cards. */
4474 while (pci_device_id_cnt < ASC_PCI_DEVICE_ID_CNT) {
4475 if ((pci_devp = pci_find_device(ASC_PCI_VENDORID,
4476 pci_device_id[pci_device_id_cnt], pci_devp)) ==
4477 NULL) {
4478 pci_device_id_cnt++;
4479 } else {
4480 if (pci_enable_device(pci_devp) == 0) {
4481 pci_devicep[pci_card_cnt_max++] = pci_devp;
4487 * Sort PCI cards in ascending order by PCI Bus, Slot,
4488 * and Device Number.
4490 for (i = 0; i < pci_card_cnt_max - 1; i++)
4492 for (j = i + 1; j < pci_card_cnt_max; j++) {
4493 if ((pci_devicep[j]->bus->number <
4494 pci_devicep[i]->bus->number) ||
4495 ((pci_devicep[j]->bus->number ==
4496 pci_devicep[i]->bus->number) &&
4497 (pci_devicep[j]->devfn <
4498 pci_devicep[i]->devfn))) {
4499 pci_devp = pci_devicep[i];
4500 pci_devicep[i] = pci_devicep[j];
4501 pci_devicep[j] = pci_devp;
4506 pci_card_cnt = 0;
4507 } else {
4508 pci_card_cnt++;
4511 if (pci_card_cnt == pci_card_cnt_max) {
4512 iop = 0;
4513 } else {
4514 pci_devp = pci_devicep[pci_card_cnt];
4516 ASC_DBG2(2,
4517 "advansys_detect: devfn %d, bus number %d\n",
4518 pci_devp->devfn, pci_devp->bus->number);
4519 iop = pci_resource_start(pci_devp, 0);
4520 ASC_DBG2(1,
4521 "advansys_detect: vendorID %X, deviceID %X\n",
4522 pci_devp->vendor, pci_devp->device);
4523 ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
4524 iop, pci_devp->irq);
4526 if(pci_devp)
4527 dev = &pci_devp->dev;
4529 #endif /* CONFIG_PCI */
4530 break;
4532 default:
4533 ASC_PRINT1("advansys_detect: unknown bus type: %d\n",
4534 asc_bus[bus]);
4535 break;
4537 ASC_DBG1(1, "advansys_detect: iop 0x%x\n", iop);
4540 * Adapter not found, try next bus type.
4542 if (iop == 0) {
4543 break;
4547 * Adapter found.
4549 * Register the adapter, get its configuration, and
4550 * initialize it.
4552 ASC_DBG(2, "advansys_detect: scsi_register()\n");
4553 shp = scsi_register(tpnt, sizeof(asc_board_t));
4555 if (shp == NULL) {
4556 continue;
4559 /* Save a pointer to the Scsi_Host of each board found. */
4560 asc_host[asc_board_count++] = shp;
4562 /* Initialize private per board data */
4563 boardp = ASC_BOARDP(shp);
4564 memset(boardp, 0, sizeof(asc_board_t));
4565 boardp->id = asc_board_count - 1;
4567 /* Initialize spinlock. */
4568 spin_lock_init(&boardp->lock);
4571 * Handle both narrow and wide boards.
4573 * If a Wide board was detected, set the board structure
4574 * wide board flag. Set-up the board structure based on
4575 * the board type.
4577 #ifdef CONFIG_PCI
4578 if (asc_bus[bus] == ASC_IS_PCI &&
4579 (pci_devp->device == ASC_PCI_DEVICE_ID_2300 ||
4580 pci_devp->device == ASC_PCI_DEVICE_ID_2500 ||
4581 pci_devp->device == ASC_PCI_DEVICE_ID_2700))
4583 boardp->flags |= ASC_IS_WIDE_BOARD;
4585 #endif /* CONFIG_PCI */
4587 if (ASC_NARROW_BOARD(boardp)) {
4588 ASC_DBG(1, "advansys_detect: narrow board\n");
4589 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4590 asc_dvc_varp->bus_type = asc_bus[bus];
4591 asc_dvc_varp->drv_ptr = boardp;
4592 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
4593 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
4594 asc_dvc_varp->iop_base = iop;
4595 asc_dvc_varp->isr_callback = asc_isr_callback;
4596 } else {
4597 ASC_DBG(1, "advansys_detect: wide board\n");
4598 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4599 adv_dvc_varp->drv_ptr = boardp;
4600 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
4601 adv_dvc_varp->isr_callback = adv_isr_callback;
4602 adv_dvc_varp->async_callback = adv_async_callback;
4603 #ifdef CONFIG_PCI
4604 if (pci_devp->device == ASC_PCI_DEVICE_ID_2300)
4606 ASC_DBG(1, "advansys_detect: ASC-3550\n");
4607 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
4608 } else if (pci_devp->device == ASC_PCI_DEVICE_ID_2500)
4610 ASC_DBG(1, "advansys_detect: ASC-38C0800\n");
4611 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
4612 } else
4614 ASC_DBG(1, "advansys_detect: ASC-38C1600\n");
4615 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
4617 #endif /* CONFIG_PCI */
4620 * Map the board's registers into virtual memory for
4621 * PCI slave access. Only memory accesses are used to
4622 * access the board's registers.
4624 * Note: The PCI register base address is not always
4625 * page aligned, but the address passed to ioremap()
4626 * must be page aligned. It is guaranteed that the
4627 * PCI register base address will not cross a page
4628 * boundary.
4630 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
4632 iolen = ADV_3550_IOLEN;
4633 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
4635 iolen = ADV_38C0800_IOLEN;
4636 } else
4638 iolen = ADV_38C1600_IOLEN;
4640 #ifdef CONFIG_PCI
4641 pci_memory_address = pci_resource_start(pci_devp, 1);
4642 ASC_DBG1(1, "advansys_detect: pci_memory_address: 0x%lx\n",
4643 (ulong) pci_memory_address);
4644 if ((boardp->ioremap_addr =
4645 ioremap(pci_memory_address & PAGE_MASK,
4646 PAGE_SIZE)) == 0) {
4647 ASC_PRINT3(
4648 "advansys_detect: board %d: ioremap(%x, %d) returned NULL\n",
4649 boardp->id, pci_memory_address, iolen);
4650 scsi_unregister(shp);
4651 asc_board_count--;
4652 continue;
4654 ASC_DBG1(1, "advansys_detect: ioremap_addr: 0x%lx\n",
4655 (ulong) boardp->ioremap_addr);
4656 adv_dvc_varp->iop_base = (AdvPortAddr)
4657 (boardp->ioremap_addr +
4658 (pci_memory_address - (pci_memory_address & PAGE_MASK)));
4659 ASC_DBG1(1, "advansys_detect: iop_base: 0x%lx\n",
4660 adv_dvc_varp->iop_base);
4661 #endif /* CONFIG_PCI */
4664 * Even though it isn't used to access wide boards, other
4665 * than for the debug line below, save I/O Port address so
4666 * that it can be reported.
4668 boardp->ioport = iop;
4670 ASC_DBG2(1,
4671 "advansys_detect: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
4672 (ushort) inp(iop + 1), (ushort) inpw(iop));
4675 #ifdef CONFIG_PROC_FS
4677 * Allocate buffer for printing information from
4678 * /proc/scsi/advansys/[0...].
4680 if ((boardp->prtbuf =
4681 kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) {
4682 ASC_PRINT3(
4683 "advansys_detect: board %d: kmalloc(%d, %d) returned NULL\n",
4684 boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC);
4685 scsi_unregister(shp);
4686 asc_board_count--;
4687 continue;
4689 #endif /* CONFIG_PROC_FS */
4691 if (ASC_NARROW_BOARD(boardp)) {
4692 asc_dvc_varp->cfg->dev = dev;
4694 * Set the board bus type and PCI IRQ before
4695 * calling AscInitGetConfig().
4697 switch (asc_dvc_varp->bus_type) {
4698 #ifdef CONFIG_ISA
4699 case ASC_IS_ISA:
4700 shp->unchecked_isa_dma = TRUE;
4701 share_irq = FALSE;
4702 break;
4703 case ASC_IS_VL:
4704 shp->unchecked_isa_dma = FALSE;
4705 share_irq = FALSE;
4706 break;
4707 case ASC_IS_EISA:
4708 shp->unchecked_isa_dma = FALSE;
4709 share_irq = TRUE;
4710 break;
4711 #endif /* CONFIG_ISA */
4712 #ifdef CONFIG_PCI
4713 case ASC_IS_PCI:
4714 shp->irq = asc_dvc_varp->irq_no = pci_devp->irq;
4715 asc_dvc_varp->cfg->pci_slot_info =
4716 ASC_PCI_MKID(pci_devp->bus->number,
4717 PCI_SLOT(pci_devp->devfn),
4718 PCI_FUNC(pci_devp->devfn));
4719 shp->unchecked_isa_dma = FALSE;
4720 share_irq = TRUE;
4721 break;
4722 #endif /* CONFIG_PCI */
4723 default:
4724 ASC_PRINT2(
4725 "advansys_detect: board %d: unknown adapter type: %d\n",
4726 boardp->id, asc_dvc_varp->bus_type);
4727 shp->unchecked_isa_dma = TRUE;
4728 share_irq = FALSE;
4729 break;
4731 } else {
4732 adv_dvc_varp->cfg->dev = dev;
4734 * For Wide boards set PCI information before calling
4735 * AdvInitGetConfig().
4737 #ifdef CONFIG_PCI
4738 shp->irq = adv_dvc_varp->irq_no = pci_devp->irq;
4739 adv_dvc_varp->cfg->pci_slot_info =
4740 ASC_PCI_MKID(pci_devp->bus->number,
4741 PCI_SLOT(pci_devp->devfn),
4742 PCI_FUNC(pci_devp->devfn));
4743 shp->unchecked_isa_dma = FALSE;
4744 share_irq = TRUE;
4745 #endif /* CONFIG_PCI */
4749 * Read the board configuration.
4751 if (ASC_NARROW_BOARD(boardp)) {
4753 * NOTE: AscInitGetConfig() may change the board's
4754 * bus_type value. The asc_bus[bus] value should no
4755 * longer be used. If the bus_type field must be
4756 * referenced only use the bit-wise AND operator "&".
4758 ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
4759 switch(ret = AscInitGetConfig(asc_dvc_varp)) {
4760 case 0: /* No error */
4761 break;
4762 case ASC_WARN_IO_PORT_ROTATE:
4763 ASC_PRINT1(
4764 "AscInitGetConfig: board %d: I/O port address modified\n",
4765 boardp->id);
4766 break;
4767 case ASC_WARN_AUTO_CONFIG:
4768 ASC_PRINT1(
4769 "AscInitGetConfig: board %d: I/O port increment switch enabled\n",
4770 boardp->id);
4771 break;
4772 case ASC_WARN_EEPROM_CHKSUM:
4773 ASC_PRINT1(
4774 "AscInitGetConfig: board %d: EEPROM checksum error\n",
4775 boardp->id);
4776 break;
4777 case ASC_WARN_IRQ_MODIFIED:
4778 ASC_PRINT1(
4779 "AscInitGetConfig: board %d: IRQ modified\n",
4780 boardp->id);
4781 break;
4782 case ASC_WARN_CMD_QNG_CONFLICT:
4783 ASC_PRINT1(
4784 "AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
4785 boardp->id);
4786 break;
4787 default:
4788 ASC_PRINT2(
4789 "AscInitGetConfig: board %d: unknown warning: 0x%x\n",
4790 boardp->id, ret);
4791 break;
4793 if ((err_code = asc_dvc_varp->err_code) != 0) {
4794 ASC_PRINT3(
4795 "AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
4796 boardp->id, asc_dvc_varp->init_state,
4797 asc_dvc_varp->err_code);
4799 } else {
4800 ASC_DBG(2, "advansys_detect: AdvInitGetConfig()\n");
4801 if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
4802 ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n",
4803 boardp->id, ret);
4805 if ((err_code = adv_dvc_varp->err_code) != 0) {
4806 ASC_PRINT2(
4807 "AdvInitGetConfig: board %d error: err_code 0x%x\n",
4808 boardp->id, adv_dvc_varp->err_code);
4812 if (err_code != 0) {
4813 #ifdef CONFIG_PROC_FS
4814 kfree(boardp->prtbuf);
4815 #endif /* CONFIG_PROC_FS */
4816 scsi_unregister(shp);
4817 asc_board_count--;
4818 continue;
4822 * Save the EEPROM configuration so that it can be displayed
4823 * from /proc/scsi/advansys/[0...].
4825 if (ASC_NARROW_BOARD(boardp)) {
4827 ASCEEP_CONFIG *ep;
4830 * Set the adapter's target id bit in the 'init_tidmask' field.
4832 boardp->init_tidmask |=
4833 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
4836 * Save EEPROM settings for the board.
4838 ep = &boardp->eep_config.asc_eep;
4840 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
4841 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
4842 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
4843 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
4844 ep->start_motor = asc_dvc_varp->start_motor;
4845 ep->cntl = asc_dvc_varp->dvc_cntl;
4846 ep->no_scam = asc_dvc_varp->no_scam;
4847 ep->max_total_qng = asc_dvc_varp->max_total_qng;
4848 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
4849 /* 'max_tag_qng' is set to the same value for every device. */
4850 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
4851 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
4852 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
4853 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
4854 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
4855 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
4856 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
4859 * Modify board configuration.
4861 ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n");
4862 switch (ret = AscInitSetConfig(asc_dvc_varp)) {
4863 case 0: /* No error. */
4864 break;
4865 case ASC_WARN_IO_PORT_ROTATE:
4866 ASC_PRINT1(
4867 "AscInitSetConfig: board %d: I/O port address modified\n",
4868 boardp->id);
4869 break;
4870 case ASC_WARN_AUTO_CONFIG:
4871 ASC_PRINT1(
4872 "AscInitSetConfig: board %d: I/O port increment switch enabled\n",
4873 boardp->id);
4874 break;
4875 case ASC_WARN_EEPROM_CHKSUM:
4876 ASC_PRINT1(
4877 "AscInitSetConfig: board %d: EEPROM checksum error\n",
4878 boardp->id);
4879 break;
4880 case ASC_WARN_IRQ_MODIFIED:
4881 ASC_PRINT1(
4882 "AscInitSetConfig: board %d: IRQ modified\n",
4883 boardp->id);
4884 break;
4885 case ASC_WARN_CMD_QNG_CONFLICT:
4886 ASC_PRINT1(
4887 "AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
4888 boardp->id);
4889 break;
4890 default:
4891 ASC_PRINT2(
4892 "AscInitSetConfig: board %d: unknown warning: 0x%x\n",
4893 boardp->id, ret);
4894 break;
4896 if (asc_dvc_varp->err_code != 0) {
4897 ASC_PRINT3(
4898 "AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
4899 boardp->id, asc_dvc_varp->init_state,
4900 asc_dvc_varp->err_code);
4901 #ifdef CONFIG_PROC_FS
4902 kfree(boardp->prtbuf);
4903 #endif /* CONFIG_PROC_FS */
4904 scsi_unregister(shp);
4905 asc_board_count--;
4906 continue;
4910 * Finish initializing the 'Scsi_Host' structure.
4912 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
4913 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
4914 shp->irq = asc_dvc_varp->irq_no;
4916 } else {
4917 ADVEEP_3550_CONFIG *ep_3550;
4918 ADVEEP_38C0800_CONFIG *ep_38C0800;
4919 ADVEEP_38C1600_CONFIG *ep_38C1600;
4922 * Save Wide EEP Configuration Information.
4924 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
4926 ep_3550 = &boardp->eep_config.adv_3550_eep;
4928 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
4929 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
4930 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
4931 ep_3550->termination = adv_dvc_varp->cfg->termination;
4932 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
4933 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
4934 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
4935 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
4936 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
4937 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
4938 ep_3550->start_motor = adv_dvc_varp->start_motor;
4939 ep_3550->scsi_reset_delay = adv_dvc_varp->scsi_reset_wait;
4940 ep_3550->serial_number_word1 =
4941 adv_dvc_varp->cfg->serial1;
4942 ep_3550->serial_number_word2 =
4943 adv_dvc_varp->cfg->serial2;
4944 ep_3550->serial_number_word3 =
4945 adv_dvc_varp->cfg->serial3;
4946 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
4948 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
4950 ep_38C0800->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
4951 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
4952 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
4953 ep_38C0800->termination_lvd =
4954 adv_dvc_varp->cfg->termination;
4955 ep_38C0800->disc_enable = adv_dvc_varp->cfg->disc_enable;
4956 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
4957 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
4958 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
4959 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
4960 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
4961 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
4962 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
4963 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
4964 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
4965 ep_38C0800->scsi_reset_delay =
4966 adv_dvc_varp->scsi_reset_wait;
4967 ep_38C0800->serial_number_word1 =
4968 adv_dvc_varp->cfg->serial1;
4969 ep_38C0800->serial_number_word2 =
4970 adv_dvc_varp->cfg->serial2;
4971 ep_38C0800->serial_number_word3 =
4972 adv_dvc_varp->cfg->serial3;
4973 } else
4975 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
4977 ep_38C1600->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
4978 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
4979 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
4980 ep_38C1600->termination_lvd =
4981 adv_dvc_varp->cfg->termination;
4982 ep_38C1600->disc_enable = adv_dvc_varp->cfg->disc_enable;
4983 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
4984 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
4985 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
4986 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
4987 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
4988 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
4989 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
4990 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
4991 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
4992 ep_38C1600->scsi_reset_delay =
4993 adv_dvc_varp->scsi_reset_wait;
4994 ep_38C1600->serial_number_word1 =
4995 adv_dvc_varp->cfg->serial1;
4996 ep_38C1600->serial_number_word2 =
4997 adv_dvc_varp->cfg->serial2;
4998 ep_38C1600->serial_number_word3 =
4999 adv_dvc_varp->cfg->serial3;
5003 * Set the adapter's target id bit in the 'init_tidmask' field.
5005 boardp->init_tidmask |=
5006 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
5009 * Finish initializing the 'Scsi_Host' structure.
5011 shp->irq = adv_dvc_varp->irq_no;
5015 * Channels are numbered beginning with 0. For AdvanSys one host
5016 * structure supports one channel. Multi-channel boards have a
5017 * separate host structure for each channel.
5019 shp->max_channel = 0;
5020 if (ASC_NARROW_BOARD(boardp)) {
5021 shp->max_id = ASC_MAX_TID + 1;
5022 shp->max_lun = ASC_MAX_LUN + 1;
5024 shp->io_port = asc_dvc_varp->iop_base;
5025 boardp->asc_n_io_port = ASC_IOADR_GAP;
5026 shp->this_id = asc_dvc_varp->cfg->chip_scsi_id;
5028 /* Set maximum number of queues the adapter can handle. */
5029 shp->can_queue = asc_dvc_varp->max_total_qng;
5030 } else {
5031 shp->max_id = ADV_MAX_TID + 1;
5032 shp->max_lun = ADV_MAX_LUN + 1;
5035 * Save the I/O Port address and length even though
5036 * I/O ports are not used to access Wide boards.
5037 * Instead the Wide boards are accessed with
5038 * PCI Memory Mapped I/O.
5040 shp->io_port = iop;
5041 boardp->asc_n_io_port = iolen;
5043 shp->this_id = adv_dvc_varp->chip_scsi_id;
5045 /* Set maximum number of queues the adapter can handle. */
5046 shp->can_queue = adv_dvc_varp->max_host_qng;
5050 * 'n_io_port' currently is one byte.
5052 * Set a value to 'n_io_port', but never referenced it because
5053 * it may be truncated.
5055 shp->n_io_port = boardp->asc_n_io_port <= 255 ?
5056 boardp->asc_n_io_port : 255;
5059 * Following v1.3.89, 'cmd_per_lun' is no longer needed
5060 * and should be set to zero.
5062 * But because of a bug introduced in v1.3.89 if the driver is
5063 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
5064 * SCSI function 'allocate_device' will panic. To allow the driver
5065 * to work as a module in these kernels set 'cmd_per_lun' to 1.
5067 * Note: This is wrong. cmd_per_lun should be set to the depth
5068 * you want on untagged devices always.
5069 #ifdef MODULE
5071 shp->cmd_per_lun = 1;
5072 /* #else
5073 shp->cmd_per_lun = 0;
5074 #endif */
5077 * Set the maximum number of scatter-gather elements the
5078 * adapter can handle.
5080 if (ASC_NARROW_BOARD(boardp)) {
5082 * Allow two commands with 'sg_tablesize' scatter-gather
5083 * elements to be executed simultaneously. This value is
5084 * the theoretical hardware limit. It may be decreased
5085 * below.
5087 shp->sg_tablesize =
5088 (((asc_dvc_varp->max_total_qng - 2) / 2) *
5089 ASC_SG_LIST_PER_Q) + 1;
5090 } else {
5091 shp->sg_tablesize = ADV_MAX_SG_LIST;
5095 * The value of 'sg_tablesize' can not exceed the SCSI
5096 * mid-level driver definition of SG_ALL. SG_ALL also
5097 * must not be exceeded, because it is used to define the
5098 * size of the scatter-gather table in 'struct asc_sg_head'.
5100 if (shp->sg_tablesize > SG_ALL) {
5101 shp->sg_tablesize = SG_ALL;
5104 ASC_DBG1(1, "advansys_detect: sg_tablesize: %d\n",
5105 shp->sg_tablesize);
5107 /* BIOS start address. */
5108 if (ASC_NARROW_BOARD(boardp)) {
5109 shp->base =
5110 ((ulong) AscGetChipBiosAddress(
5111 asc_dvc_varp->iop_base,
5112 asc_dvc_varp->bus_type));
5113 } else {
5115 * Fill-in BIOS board variables. The Wide BIOS saves
5116 * information in LRAM that is used by the driver.
5118 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_SIGNATURE,
5119 boardp->bios_signature);
5120 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_VERSION,
5121 boardp->bios_version);
5122 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODESEG,
5123 boardp->bios_codeseg);
5124 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODELEN,
5125 boardp->bios_codelen);
5127 ASC_DBG2(1,
5128 "advansys_detect: bios_signature 0x%x, bios_version 0x%x\n",
5129 boardp->bios_signature, boardp->bios_version);
5131 ASC_DBG2(1,
5132 "advansys_detect: bios_codeseg 0x%x, bios_codelen 0x%x\n",
5133 boardp->bios_codeseg, boardp->bios_codelen);
5136 * If the BIOS saved a valid signature, then fill in
5137 * the BIOS code segment base address.
5139 if (boardp->bios_signature == 0x55AA) {
5141 * Convert x86 realmode code segment to a linear
5142 * address by shifting left 4.
5144 shp->base = ((ulong) boardp->bios_codeseg << 4);
5145 } else {
5146 shp->base = 0;
5151 * Register Board Resources - I/O Port, DMA, IRQ
5155 * Register I/O port range.
5157 * For Wide boards the I/O ports are not used to access
5158 * the board, but request the region anyway.
5160 * 'shp->n_io_port' is not referenced, because it may be truncated.
5162 ASC_DBG2(2,
5163 "advansys_detect: request_region port 0x%lx, len 0x%x\n",
5164 (ulong) shp->io_port, boardp->asc_n_io_port);
5165 if (request_region(shp->io_port, boardp->asc_n_io_port,
5166 "advansys") == NULL) {
5167 ASC_PRINT3(
5168 "advansys_detect: board %d: request_region() failed, port 0x%lx, len 0x%x\n",
5169 boardp->id, (ulong) shp->io_port, boardp->asc_n_io_port);
5170 #ifdef CONFIG_PROC_FS
5171 kfree(boardp->prtbuf);
5172 #endif /* CONFIG_PROC_FS */
5173 scsi_unregister(shp);
5174 asc_board_count--;
5175 continue;
5178 /* Register DMA Channel for Narrow boards. */
5179 shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
5180 #ifdef CONFIG_ISA
5181 if (ASC_NARROW_BOARD(boardp)) {
5182 /* Register DMA channel for ISA bus. */
5183 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5184 shp->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
5185 if ((ret =
5186 request_dma(shp->dma_channel, "advansys")) != 0) {
5187 ASC_PRINT3(
5188 "advansys_detect: board %d: request_dma() %d failed %d\n",
5189 boardp->id, shp->dma_channel, ret);
5190 release_region(shp->io_port, boardp->asc_n_io_port);
5191 #ifdef CONFIG_PROC_FS
5192 kfree(boardp->prtbuf);
5193 #endif /* CONFIG_PROC_FS */
5194 scsi_unregister(shp);
5195 asc_board_count--;
5196 continue;
5198 AscEnableIsaDma(shp->dma_channel);
5201 #endif /* CONFIG_ISA */
5203 /* Register IRQ Number. */
5204 ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
5206 * If request_irq() fails with the SA_INTERRUPT flag set,
5207 * then try again without the SA_INTERRUPT flag set. This
5208 * allows IRQ sharing to work even with other drivers that
5209 * do not set the SA_INTERRUPT flag.
5211 * If SA_INTERRUPT is not set, then interrupts are enabled
5212 * before the driver interrupt function is called.
5214 if (((ret = request_irq(shp->irq, advansys_interrupt,
5215 SA_INTERRUPT | (share_irq == TRUE ? SA_SHIRQ : 0),
5216 "advansys", boardp)) != 0) &&
5217 ((ret = request_irq(shp->irq, advansys_interrupt,
5218 (share_irq == TRUE ? SA_SHIRQ : 0),
5219 "advansys", boardp)) != 0))
5221 if (ret == -EBUSY) {
5222 ASC_PRINT2(
5223 "advansys_detect: board %d: request_irq(): IRQ 0x%x already in use.\n",
5224 boardp->id, shp->irq);
5225 } else if (ret == -EINVAL) {
5226 ASC_PRINT2(
5227 "advansys_detect: board %d: request_irq(): IRQ 0x%x not valid.\n",
5228 boardp->id, shp->irq);
5229 } else {
5230 ASC_PRINT3(
5231 "advansys_detect: board %d: request_irq(): IRQ 0x%x failed with %d\n",
5232 boardp->id, shp->irq, ret);
5234 release_region(shp->io_port, boardp->asc_n_io_port);
5235 iounmap(boardp->ioremap_addr);
5236 if (shp->dma_channel != NO_ISA_DMA) {
5237 free_dma(shp->dma_channel);
5239 #ifdef CONFIG_PROC_FS
5240 kfree(boardp->prtbuf);
5241 #endif /* CONFIG_PROC_FS */
5242 scsi_unregister(shp);
5243 asc_board_count--;
5244 continue;
5248 * Initialize board RISC chip and enable interrupts.
5250 if (ASC_NARROW_BOARD(boardp)) {
5251 ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n");
5252 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
5253 err_code = asc_dvc_varp->err_code;
5255 if (warn_code || err_code) {
5256 ASC_PRINT4(
5257 "advansys_detect: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
5258 boardp->id, asc_dvc_varp->init_state,
5259 warn_code, err_code);
5261 } else {
5262 ADV_CARR_T *carrp;
5263 int req_cnt = 0;
5264 adv_req_t *reqp = NULL;
5265 int sg_cnt = 0;
5268 * Allocate buffer carrier structures. The total size
5269 * is about 4 KB, so allocate all at once.
5271 carrp =
5272 (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC);
5273 ASC_DBG1(1, "advansys_detect: carrp 0x%lx\n", (ulong) carrp);
5275 if (carrp == NULL) {
5276 goto kmalloc_error;
5280 * Allocate up to 'max_host_qng' request structures for
5281 * the Wide board. The total size is about 16 KB, so
5282 * allocate all at once. If the allocation fails decrement
5283 * and try again.
5285 for (req_cnt = adv_dvc_varp->max_host_qng;
5286 req_cnt > 0; req_cnt--) {
5288 reqp = (adv_req_t *)
5289 kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC);
5291 ASC_DBG3(1,
5292 "advansys_detect: reqp 0x%lx, req_cnt %d, bytes %lu\n",
5293 (ulong) reqp, req_cnt,
5294 (ulong) sizeof(adv_req_t) * req_cnt);
5296 if (reqp != NULL) {
5297 break;
5300 if (reqp == NULL)
5302 goto kmalloc_error;
5306 * Allocate up to ADV_TOT_SG_BLOCK request structures for
5307 * the Wide board. Each structure is about 136 bytes.
5309 boardp->adv_sgblkp = NULL;
5310 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
5312 sgp = (adv_sgblk_t *)
5313 kmalloc(sizeof(adv_sgblk_t), GFP_ATOMIC);
5315 if (sgp == NULL) {
5316 break;
5319 sgp->next_sgblkp = boardp->adv_sgblkp;
5320 boardp->adv_sgblkp = sgp;
5323 ASC_DBG3(1,
5324 "advansys_detect: sg_cnt %d * %u = %u bytes\n",
5325 sg_cnt, sizeof(adv_sgblk_t),
5326 (unsigned) (sizeof(adv_sgblk_t) * sg_cnt));
5329 * If no request structures or scatter-gather structures could
5330 * be allocated, then return an error. Otherwise continue with
5331 * initialization.
5333 kmalloc_error:
5334 if (carrp == NULL)
5336 ASC_PRINT1(
5337 "advansys_detect: board %d error: failed to kmalloc() carrier buffer.\n",
5338 boardp->id);
5339 err_code = ADV_ERROR;
5340 } else if (reqp == NULL) {
5341 kfree(carrp);
5342 ASC_PRINT1(
5343 "advansys_detect: board %d error: failed to kmalloc() adv_req_t buffer.\n",
5344 boardp->id);
5345 err_code = ADV_ERROR;
5346 } else if (boardp->adv_sgblkp == NULL) {
5347 kfree(carrp);
5348 kfree(reqp);
5349 ASC_PRINT1(
5350 "advansys_detect: board %d error: failed to kmalloc() adv_sgblk_t buffers.\n",
5351 boardp->id);
5352 err_code = ADV_ERROR;
5353 } else {
5355 /* Save carrier buffer pointer. */
5356 boardp->orig_carrp = carrp;
5359 * Save original pointer for kfree() in case the
5360 * driver is built as a module and can be unloaded.
5362 boardp->orig_reqp = reqp;
5364 adv_dvc_varp->carrier_buf = carrp;
5367 * Point 'adv_reqp' to the request structures and
5368 * link them together.
5370 req_cnt--;
5371 reqp[req_cnt].next_reqp = NULL;
5372 for (; req_cnt > 0; req_cnt--) {
5373 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
5375 boardp->adv_reqp = &reqp[0];
5377 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5379 ASC_DBG(2,
5380 "advansys_detect: AdvInitAsc3550Driver()\n");
5381 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
5382 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5383 ASC_DBG(2,
5384 "advansys_detect: AdvInitAsc38C0800Driver()\n");
5385 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
5386 } else {
5387 ASC_DBG(2,
5388 "advansys_detect: AdvInitAsc38C1600Driver()\n");
5389 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
5391 err_code = adv_dvc_varp->err_code;
5393 if (warn_code || err_code) {
5394 ASC_PRINT3(
5395 "advansys_detect: board %d error: warn 0x%x, error 0x%x\n",
5396 boardp->id, warn_code, err_code);
5401 if (err_code != 0) {
5402 release_region(shp->io_port, boardp->asc_n_io_port);
5403 if (ASC_WIDE_BOARD(boardp)) {
5404 iounmap(boardp->ioremap_addr);
5405 if (boardp->orig_carrp) {
5406 kfree(boardp->orig_carrp);
5407 boardp->orig_carrp = NULL;
5409 if (boardp->orig_reqp) {
5410 kfree(boardp->orig_reqp);
5411 boardp->orig_reqp = boardp->adv_reqp = NULL;
5413 while ((sgp = boardp->adv_sgblkp) != NULL)
5415 boardp->adv_sgblkp = sgp->next_sgblkp;
5416 kfree(sgp);
5419 if (shp->dma_channel != NO_ISA_DMA) {
5420 free_dma(shp->dma_channel);
5422 #ifdef CONFIG_PROC_FS
5423 kfree(boardp->prtbuf);
5424 #endif /* CONFIG_PROC_FS */
5425 free_irq(shp->irq, boardp);
5426 scsi_unregister(shp);
5427 asc_board_count--;
5428 continue;
5430 ASC_DBG_PRT_SCSI_HOST(2, shp);
5434 ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count);
5435 return asc_board_count;
5439 * advansys_release()
5441 * Release resources allocated for a single AdvanSys adapter.
5444 advansys_release(struct Scsi_Host *shp)
5446 asc_board_t *boardp;
5448 ASC_DBG(1, "advansys_release: begin\n");
5449 boardp = ASC_BOARDP(shp);
5450 free_irq(shp->irq, boardp);
5451 if (shp->dma_channel != NO_ISA_DMA) {
5452 ASC_DBG(1, "advansys_release: free_dma()\n");
5453 free_dma(shp->dma_channel);
5455 release_region(shp->io_port, boardp->asc_n_io_port);
5456 if (ASC_WIDE_BOARD(boardp)) {
5457 adv_sgblk_t *sgp = NULL;
5459 iounmap(boardp->ioremap_addr);
5460 if (boardp->orig_carrp) {
5461 kfree(boardp->orig_carrp);
5462 boardp->orig_carrp = NULL;
5464 if (boardp->orig_reqp) {
5465 kfree(boardp->orig_reqp);
5466 boardp->orig_reqp = boardp->adv_reqp = NULL;
5468 while ((sgp = boardp->adv_sgblkp) != NULL)
5470 boardp->adv_sgblkp = sgp->next_sgblkp;
5471 kfree(sgp);
5474 #ifdef CONFIG_PROC_FS
5475 ASC_ASSERT(boardp->prtbuf != NULL);
5476 kfree(boardp->prtbuf);
5477 #endif /* CONFIG_PROC_FS */
5478 scsi_unregister(shp);
5479 ASC_DBG(1, "advansys_release: end\n");
5480 return 0;
5484 * advansys_info()
5486 * Return suitable for printing on the console with the argument
5487 * adapter's configuration information.
5489 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
5490 * otherwise the static 'info' array will be overrun.
5492 const char *
5493 advansys_info(struct Scsi_Host *shp)
5495 static char info[ASC_INFO_SIZE];
5496 asc_board_t *boardp;
5497 ASC_DVC_VAR *asc_dvc_varp;
5498 ADV_DVC_VAR *adv_dvc_varp;
5499 char *busname;
5500 int iolen;
5501 char *widename = NULL;
5503 boardp = ASC_BOARDP(shp);
5504 if (ASC_NARROW_BOARD(boardp)) {
5505 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5506 ASC_DBG(1, "advansys_info: begin\n");
5507 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5508 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == ASC_IS_ISAPNP) {
5509 busname = "ISA PnP";
5510 } else {
5511 busname = "ISA";
5513 /* Don't reference 'shp->n_io_port'; It may be truncated. */
5514 sprintf(info,
5515 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
5516 ASC_VERSION, busname,
5517 (ulong) shp->io_port,
5518 (ulong) shp->io_port + boardp->asc_n_io_port - 1,
5519 shp->irq, shp->dma_channel);
5520 } else {
5521 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
5522 busname = "VL";
5523 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
5524 busname = "EISA";
5525 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
5526 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
5527 == ASC_IS_PCI_ULTRA) {
5528 busname = "PCI Ultra";
5529 } else {
5530 busname = "PCI";
5532 } else {
5533 busname = "?";
5534 ASC_PRINT2( "advansys_info: board %d: unknown bus type %d\n",
5535 boardp->id, asc_dvc_varp->bus_type);
5537 /* Don't reference 'shp->n_io_port'; It may be truncated. */
5538 sprintf(info,
5539 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
5540 ASC_VERSION, busname,
5541 (ulong) shp->io_port,
5542 (ulong) shp->io_port + boardp->asc_n_io_port - 1,
5543 shp->irq);
5545 } else {
5547 * Wide Adapter Information
5549 * Memory-mapped I/O is used instead of I/O space to access
5550 * the adapter, but display the I/O Port range. The Memory
5551 * I/O address is displayed through the driver /proc file.
5553 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5554 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5556 iolen = ADV_3550_IOLEN;
5557 widename = "Ultra-Wide";
5558 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
5560 iolen = ADV_38C0800_IOLEN;
5561 widename = "Ultra2-Wide";
5562 } else
5564 iolen = ADV_38C1600_IOLEN;
5565 widename = "Ultra3-Wide";
5567 sprintf(info, "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
5568 ASC_VERSION,
5569 widename,
5570 (ulong) adv_dvc_varp->iop_base,
5571 (ulong) adv_dvc_varp->iop_base + iolen - 1,
5572 shp->irq);
5574 ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
5575 ASC_DBG(1, "advansys_info: end\n");
5576 return info;
5580 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
5582 * This function always returns 0. Command return status is saved
5583 * in the 'scp' result field.
5586 advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
5588 struct Scsi_Host *shp;
5589 asc_board_t *boardp;
5590 ulong flags;
5591 struct scsi_cmnd *done_scp;
5593 shp = scp->device->host;
5594 boardp = ASC_BOARDP(shp);
5595 ASC_STATS(shp, queuecommand);
5597 /* host_lock taken by mid-level prior to call but need to protect */
5598 /* against own ISR */
5599 spin_lock_irqsave(&boardp->lock, flags);
5602 * Block new commands while handling a reset or abort request.
5604 if (boardp->flags & ASC_HOST_IN_RESET) {
5605 ASC_DBG1(1,
5606 "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
5607 (ulong) scp);
5608 scp->result = HOST_BYTE(DID_RESET);
5611 * Add blocked requests to the board's 'done' queue. The queued
5612 * requests will be completed at the end of the abort or reset
5613 * handling.
5615 asc_enqueue(&boardp->done, scp, ASC_BACK);
5616 spin_unlock_irqrestore(&boardp->lock, flags);
5617 return 0;
5621 * Attempt to execute any waiting commands for the board.
5623 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
5624 ASC_DBG(1,
5625 "advansys_queuecommand: before asc_execute_queue() waiting\n");
5626 asc_execute_queue(&boardp->waiting);
5630 * Save the function pointer to Linux mid-level 'done' function
5631 * and attempt to execute the command.
5633 * If ASC_NOERROR is returned the request has been added to the
5634 * board's 'active' queue and will be completed by the interrupt
5635 * handler.
5637 * If ASC_BUSY is returned add the request to the board's per
5638 * target waiting list. This is the first time the request has
5639 * been tried. Add it to the back of the waiting list. It will be
5640 * retried later.
5642 * If an error occurred, the request will have been placed on the
5643 * board's 'done' queue and must be completed before returning.
5645 scp->scsi_done = done;
5646 switch (asc_execute_scsi_cmnd(scp)) {
5647 case ASC_NOERROR:
5648 break;
5649 case ASC_BUSY:
5650 asc_enqueue(&boardp->waiting, scp, ASC_BACK);
5651 break;
5652 case ASC_ERROR:
5653 default:
5654 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
5655 /* Interrupts could be enabled here. */
5656 asc_scsi_done_list(done_scp);
5657 break;
5659 spin_unlock_irqrestore(&boardp->lock, flags);
5661 return 0;
5665 * advansys_reset()
5667 * Reset the bus associated with the command 'scp'.
5669 * This function runs its own thread. Interrupts must be blocked but
5670 * sleeping is allowed and no locking other than for host structures is
5671 * required. Returns SUCCESS or FAILED.
5674 advansys_reset(struct scsi_cmnd *scp)
5676 struct Scsi_Host *shp;
5677 asc_board_t *boardp;
5678 ASC_DVC_VAR *asc_dvc_varp;
5679 ADV_DVC_VAR *adv_dvc_varp;
5680 ulong flags;
5681 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
5682 struct scsi_cmnd *tscp, *new_last_scp;
5683 int status;
5684 int ret = SUCCESS;
5686 ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong) scp);
5688 #ifdef ADVANSYS_STATS
5689 if (scp->device->host != NULL) {
5690 ASC_STATS(scp->device->host, reset);
5692 #endif /* ADVANSYS_STATS */
5694 if ((shp = scp->device->host) == NULL) {
5695 scp->result = HOST_BYTE(DID_ERROR);
5696 return FAILED;
5699 boardp = ASC_BOARDP(shp);
5701 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
5702 boardp->id);
5704 * Check for re-entrancy.
5706 spin_lock_irqsave(&boardp->lock, flags);
5707 if (boardp->flags & ASC_HOST_IN_RESET) {
5708 spin_unlock_irqrestore(&boardp->lock, flags);
5709 return FAILED;
5711 boardp->flags |= ASC_HOST_IN_RESET;
5712 spin_unlock_irqrestore(&boardp->lock, flags);
5714 if (ASC_NARROW_BOARD(boardp)) {
5716 * Narrow Board
5718 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5721 * Reset the chip and SCSI bus.
5723 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
5724 status = AscInitAsc1000Driver(asc_dvc_varp);
5726 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
5727 if (asc_dvc_varp->err_code) {
5728 ASC_PRINT2(
5729 "advansys_reset: board %d: SCSI bus reset error: 0x%x\n",
5730 boardp->id, asc_dvc_varp->err_code);
5731 ret = FAILED;
5732 } else if (status) {
5733 ASC_PRINT2(
5734 "advansys_reset: board %d: SCSI bus reset warning: 0x%x\n",
5735 boardp->id, status);
5736 } else {
5737 ASC_PRINT1(
5738 "advansys_reset: board %d: SCSI bus reset successful.\n",
5739 boardp->id);
5742 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
5743 spin_lock_irqsave(&boardp->lock, flags);
5745 } else {
5747 * Wide Board
5749 * If the suggest reset bus flags are set, then reset the bus.
5750 * Otherwise only reset the device.
5752 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5755 * Reset the target's SCSI bus.
5757 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
5758 switch (AdvResetChipAndSB(adv_dvc_varp)) {
5759 case ASC_TRUE:
5760 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset successful.\n",
5761 boardp->id);
5762 break;
5763 case ASC_FALSE:
5764 default:
5765 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset error.\n",
5766 boardp->id);
5767 ret = FAILED;
5768 break;
5770 spin_lock_irqsave(&boardp->lock, flags);
5771 (void) AdvISR(adv_dvc_varp);
5773 /* Board lock is held. */
5776 * Dequeue all board 'done' requests. A pointer to the last request
5777 * is returned in 'last_scp'.
5779 done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
5782 * Dequeue all board 'active' requests for all devices and set
5783 * the request status to DID_RESET. A pointer to the last request
5784 * is returned in 'last_scp'.
5786 if (done_scp == NULL) {
5787 done_scp = asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL);
5788 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
5789 tscp->result = HOST_BYTE(DID_RESET);
5791 } else {
5792 /* Append to 'done_scp' at the end with 'last_scp'. */
5793 ASC_ASSERT(last_scp != NULL);
5794 last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
5795 &boardp->active, &new_last_scp, ASC_TID_ALL);
5796 if (new_last_scp != NULL) {
5797 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
5798 for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
5799 tscp->result = HOST_BYTE(DID_RESET);
5801 last_scp = new_last_scp;
5806 * Dequeue all 'waiting' requests and set the request status
5807 * to DID_RESET.
5809 if (done_scp == NULL) {
5810 done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL);
5811 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
5812 tscp->result = HOST_BYTE(DID_RESET);
5814 } else {
5815 /* Append to 'done_scp' at the end with 'last_scp'. */
5816 ASC_ASSERT(last_scp != NULL);
5817 last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
5818 &boardp->waiting, &new_last_scp, ASC_TID_ALL);
5819 if (new_last_scp != NULL) {
5820 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
5821 for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
5822 tscp->result = HOST_BYTE(DID_RESET);
5824 last_scp = new_last_scp;
5828 /* Save the time of the most recently completed reset. */
5829 boardp->last_reset = jiffies;
5831 /* Clear reset flag. */
5832 boardp->flags &= ~ASC_HOST_IN_RESET;
5833 spin_unlock_irqrestore(&boardp->lock, flags);
5836 * Complete all the 'done_scp' requests.
5838 if (done_scp != NULL) {
5839 asc_scsi_done_list(done_scp);
5842 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
5844 return ret;
5848 * advansys_biosparam()
5850 * Translate disk drive geometry if the "BIOS greater than 1 GB"
5851 * support is enabled for a drive.
5853 * ip (information pointer) is an int array with the following definition:
5854 * ip[0]: heads
5855 * ip[1]: sectors
5856 * ip[2]: cylinders
5859 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
5860 sector_t capacity, int ip[])
5862 asc_board_t *boardp;
5864 ASC_DBG(1, "advansys_biosparam: begin\n");
5865 ASC_STATS(sdev->host, biosparam);
5866 boardp = ASC_BOARDP(sdev->host);
5867 if (ASC_NARROW_BOARD(boardp)) {
5868 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
5869 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
5870 ip[0] = 255;
5871 ip[1] = 63;
5872 } else {
5873 ip[0] = 64;
5874 ip[1] = 32;
5876 } else {
5877 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
5878 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
5879 ip[0] = 255;
5880 ip[1] = 63;
5881 } else {
5882 ip[0] = 64;
5883 ip[1] = 32;
5886 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
5887 ASC_DBG(1, "advansys_biosparam: end\n");
5888 return 0;
5892 * advansys_setup()
5894 * This function is called from init/main.c at boot time.
5895 * It it passed LILO parameters that can be set from the
5896 * LILO command line or in /etc/lilo.conf.
5898 * It is used by the AdvanSys driver to either disable I/O
5899 * port scanning or to limit scanning to 1 - 4 I/O ports.
5900 * Regardless of the option setting EISA and PCI boards
5901 * will still be searched for and detected. This option
5902 * only affects searching for ISA and VL boards.
5904 * If ADVANSYS_DEBUG is defined the driver debug level may
5905 * be set using the 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port.
5907 * Examples:
5908 * 1. Eliminate I/O port scanning:
5909 * boot: linux advansys=
5910 * or
5911 * boot: linux advansys=0x0
5912 * 2. Limit I/O port scanning to one I/O port:
5913 * boot: linux advansys=0x110
5914 * 3. Limit I/O port scanning to four I/O ports:
5915 * boot: linux advansys=0x110,0x210,0x230,0x330
5916 * 4. If ADVANSYS_DEBUG, limit I/O port scanning to four I/O ports and
5917 * set the driver debug level to 2.
5918 * boot: linux advansys=0x110,0x210,0x230,0x330,0xdeb2
5920 * ints[0] - number of arguments
5921 * ints[1] - first argument
5922 * ints[2] - second argument
5923 * ...
5925 void __init
5926 advansys_setup(char *str, int *ints)
5928 int i;
5930 if (asc_iopflag == ASC_TRUE) {
5931 printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n");
5932 return;
5935 asc_iopflag = ASC_TRUE;
5937 if (ints[0] > ASC_NUM_IOPORT_PROBE) {
5938 #ifdef ADVANSYS_DEBUG
5939 if ((ints[0] == ASC_NUM_IOPORT_PROBE + 1) &&
5940 (ints[ASC_NUM_IOPORT_PROBE + 1] >> 4 == 0xdeb)) {
5941 asc_dbglvl = ints[ASC_NUM_IOPORT_PROBE + 1] & 0xf;
5942 } else {
5943 #endif /* ADVANSYS_DEBUG */
5944 printk("AdvanSys SCSI: only %d I/O ports accepted\n",
5945 ASC_NUM_IOPORT_PROBE);
5946 #ifdef ADVANSYS_DEBUG
5948 #endif /* ADVANSYS_DEBUG */
5951 #ifdef ADVANSYS_DEBUG
5952 ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]);
5953 for (i = 1; i < ints[0]; i++) {
5954 ASC_DBG2(1, " ints[%d] 0x%x", i, ints[i]);
5956 ASC_DBG(1, "\n");
5957 #endif /* ADVANSYS_DEBUG */
5959 for (i = 1; i <= ints[0] && i <= ASC_NUM_IOPORT_PROBE; i++) {
5960 asc_ioport[i-1] = ints[i];
5961 ASC_DBG2(1, "advansys_setup: asc_ioport[%d] 0x%x\n",
5962 i - 1, asc_ioport[i-1]);
5968 * --- Loadable Driver Support
5971 static struct scsi_host_template driver_template = {
5972 .proc_name = "advansys",
5973 #ifdef CONFIG_PROC_FS
5974 .proc_info = advansys_proc_info,
5975 #endif
5976 .name = "advansys",
5977 .detect = advansys_detect,
5978 .release = advansys_release,
5979 .info = advansys_info,
5980 .queuecommand = advansys_queuecommand,
5981 .eh_bus_reset_handler = advansys_reset,
5982 .bios_param = advansys_biosparam,
5983 .slave_configure = advansys_slave_configure,
5985 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
5986 * must be set. The flag will be cleared in advansys_detect for non-ISA
5987 * adapters. Refer to the comment in scsi_module.c for more information.
5989 .unchecked_isa_dma = 1,
5991 * All adapters controlled by this driver are capable of large
5992 * scatter-gather lists. According to the mid-level SCSI documentation
5993 * this obviates any performance gain provided by setting
5994 * 'use_clustering'. But empirically while CPU utilization is increased
5995 * by enabling clustering, I/O throughput increases as well.
5997 .use_clustering = ENABLE_CLUSTERING,
5999 #include "scsi_module.c"
6003 * --- Miscellaneous Driver Functions
6007 * First-level interrupt handler.
6009 * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
6010 * all boards are currently checked for interrupts on each interrupt, 'dev_id'
6011 * is not referenced. 'dev_id' could be used to identify an interrupt passed
6012 * to the AdvanSys driver which is for a device sharing an interrupt with
6013 * an AdvanSys adapter.
6015 STATIC irqreturn_t
6016 advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs)
6018 ulong flags;
6019 int i;
6020 asc_board_t *boardp;
6021 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
6022 struct scsi_cmnd *new_last_scp;
6023 struct Scsi_Host *shp;
6025 ASC_DBG(1, "advansys_interrupt: begin\n");
6028 * Check for interrupts on all boards.
6029 * AscISR() will call asc_isr_callback().
6031 for (i = 0; i < asc_board_count; i++) {
6032 shp = asc_host[i];
6033 boardp = ASC_BOARDP(shp);
6034 ASC_DBG2(2, "advansys_interrupt: i %d, boardp 0x%lx\n",
6035 i, (ulong) boardp);
6036 spin_lock_irqsave(&boardp->lock, flags);
6037 if (ASC_NARROW_BOARD(boardp)) {
6039 * Narrow Board
6041 if (AscIsIntPending(shp->io_port)) {
6042 ASC_STATS(shp, interrupt);
6043 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
6044 AscISR(&boardp->dvc_var.asc_dvc_var);
6046 } else {
6048 * Wide Board
6050 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
6051 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
6052 ASC_STATS(shp, interrupt);
6057 * Start waiting requests and create a list of completed requests.
6059 * If a reset request is being performed for the board, the reset
6060 * handler will complete pending requests after it has completed.
6062 if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
6063 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%lx, last_scp 0x%lx\n",
6064 (ulong) done_scp, (ulong) last_scp);
6066 /* Start any waiting commands for the board. */
6067 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
6068 ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
6069 asc_execute_queue(&boardp->waiting);
6073 * Add to the list of requests that must be completed.
6075 * 'done_scp' will always be NULL on the first iteration
6076 * of this loop. 'last_scp' is set at the same time as
6077 * 'done_scp'.
6079 if (done_scp == NULL) {
6080 done_scp = asc_dequeue_list(&boardp->done, &last_scp,
6081 ASC_TID_ALL);
6082 } else {
6083 ASC_ASSERT(last_scp != NULL);
6084 last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
6085 &boardp->done, &new_last_scp, ASC_TID_ALL);
6086 if (new_last_scp != NULL) {
6087 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6088 last_scp = new_last_scp;
6092 spin_unlock_irqrestore(&boardp->lock, flags);
6096 * If interrupts were enabled on entry, then they
6097 * are now enabled here.
6099 * Complete all requests on the done list.
6102 asc_scsi_done_list(done_scp);
6104 ASC_DBG(1, "advansys_interrupt: end\n");
6105 return IRQ_HANDLED;
6109 * Set the number of commands to queue per device for the
6110 * specified host adapter.
6112 STATIC int
6113 advansys_slave_configure(struct scsi_device *device)
6115 asc_board_t *boardp;
6117 boardp = ASC_BOARDP(device->host);
6118 boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
6120 * Save a pointer to the device and set its initial/maximum
6121 * queue depth. Only save the pointer for a lun0 dev though.
6123 if(device->lun == 0)
6124 boardp->device[device->id] = device;
6125 if(device->tagged_supported) {
6126 if (ASC_NARROW_BOARD(boardp)) {
6127 scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
6128 boardp->dvc_var.asc_dvc_var.max_dvc_qng[device->id]);
6129 } else {
6130 scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
6131 boardp->dvc_var.adv_dvc_var.max_dvc_qng);
6133 } else {
6134 scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun);
6136 ASC_DBG4(1, "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n",
6137 (ulong) device, (ulong) boardp, device->id, device->queue_depth);
6138 return 0;
6142 * Complete all requests on the singly linked list pointed
6143 * to by 'scp'.
6145 * Interrupts can be enabled on entry.
6147 STATIC void
6148 asc_scsi_done_list(struct scsi_cmnd *scp)
6150 struct scsi_cmnd *tscp;
6152 ASC_DBG(2, "asc_scsi_done_list: begin\n");
6153 while (scp != NULL) {
6154 asc_board_t *boardp;
6155 struct device *dev;
6157 ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong) scp);
6158 tscp = REQPNEXT(scp);
6159 scp->host_scribble = NULL;
6161 boardp = ASC_BOARDP(scp->device->host);
6163 if (ASC_NARROW_BOARD(boardp))
6164 dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
6165 else
6166 dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
6168 if (scp->use_sg)
6169 dma_unmap_sg(dev, (struct scatterlist *)scp->request_buffer,
6170 scp->use_sg, scp->sc_data_direction);
6171 else if (scp->request_bufflen)
6172 dma_unmap_single(dev, scp->SCp.dma_handle,
6173 scp->request_bufflen, scp->sc_data_direction);
6175 ASC_STATS(scp->device->host, done);
6176 ASC_ASSERT(scp->scsi_done != NULL);
6178 scp->scsi_done(scp);
6180 scp = tscp;
6182 ASC_DBG(2, "asc_scsi_done_list: done\n");
6183 return;
6187 * Execute a single 'Scsi_Cmnd'.
6189 * The function 'done' is called when the request has been completed.
6191 * Scsi_Cmnd:
6193 * host - board controlling device
6194 * device - device to send command
6195 * target - target of device
6196 * lun - lun of device
6197 * cmd_len - length of SCSI CDB
6198 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
6199 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
6201 * if (use_sg == 0) {
6202 * request_buffer - buffer address for request
6203 * request_bufflen - length of request buffer
6204 * } else {
6205 * request_buffer - pointer to scatterlist structure
6208 * sense_buffer - sense command buffer
6210 * result (4 bytes of an int):
6211 * Byte Meaning
6212 * 0 SCSI Status Byte Code
6213 * 1 SCSI One Byte Message Code
6214 * 2 Host Error Code
6215 * 3 Mid-Level Error Code
6217 * host driver fields:
6218 * SCp - Scsi_Pointer used for command processing status
6219 * scsi_done - used to save caller's done function
6220 * host_scribble - used for pointer to another struct scsi_cmnd
6222 * If this function returns ASC_NOERROR the request has been enqueued
6223 * on the board's 'active' queue and will be completed from the
6224 * interrupt handler.
6226 * If this function returns ASC_NOERROR the request has been enqueued
6227 * on the board's 'done' queue and must be completed by the caller.
6229 * If ASC_BUSY is returned the request will be enqueued by the
6230 * caller on the target's waiting queue and re-tried later.
6232 STATIC int
6233 asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
6235 asc_board_t *boardp;
6236 ASC_DVC_VAR *asc_dvc_varp;
6237 ADV_DVC_VAR *adv_dvc_varp;
6238 ADV_SCSI_REQ_Q *adv_scsiqp;
6239 struct scsi_device *device;
6240 int ret;
6242 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
6243 (ulong) scp, (ulong) scp->scsi_done);
6245 boardp = ASC_BOARDP(scp->device->host);
6246 device = boardp->device[scp->device->id];
6248 if (ASC_NARROW_BOARD(boardp)) {
6250 * Build and execute Narrow Board request.
6253 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6256 * Build Asc Library request structure using the
6257 * global structures 'asc_scsi_req' and 'asc_sg_head'.
6259 * If an error is returned, then the request has been
6260 * queued on the board done queue. It will be completed
6261 * by the caller.
6263 * asc_build_req() can not return ASC_BUSY.
6265 if (asc_build_req(boardp, scp) == ASC_ERROR) {
6266 ASC_STATS(scp->device->host, build_error);
6267 return ASC_ERROR;
6271 * Execute the command. If there is no error, add the command
6272 * to the active queue.
6274 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
6275 case ASC_NOERROR:
6276 ASC_STATS(scp->device->host, exe_noerror);
6278 * Increment monotonically increasing per device successful
6279 * request counter. Wrapping doesn't matter.
6281 boardp->reqcnt[scp->device->id]++;
6282 asc_enqueue(&boardp->active, scp, ASC_BACK);
6283 ASC_DBG(1,
6284 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
6285 break;
6286 case ASC_BUSY:
6288 * Caller will enqueue request on the target's waiting queue
6289 * and retry later.
6291 ASC_STATS(scp->device->host, exe_busy);
6292 break;
6293 case ASC_ERROR:
6294 ASC_PRINT2(
6295 "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
6296 boardp->id, asc_dvc_varp->err_code);
6297 ASC_STATS(scp->device->host, exe_error);
6298 scp->result = HOST_BYTE(DID_ERROR);
6299 asc_enqueue(&boardp->done, scp, ASC_BACK);
6300 break;
6301 default:
6302 ASC_PRINT2(
6303 "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
6304 boardp->id, asc_dvc_varp->err_code);
6305 ASC_STATS(scp->device->host, exe_unknown);
6306 scp->result = HOST_BYTE(DID_ERROR);
6307 asc_enqueue(&boardp->done, scp, ASC_BACK);
6308 break;
6310 } else {
6312 * Build and execute Wide Board request.
6314 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6317 * Build and get a pointer to an Adv Library request structure.
6319 * If the request is successfully built then send it below,
6320 * otherwise return with an error.
6322 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
6323 case ASC_NOERROR:
6324 ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
6325 break;
6326 case ASC_BUSY:
6327 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
6329 * If busy is returned the request has not been enqueued.
6330 * It will be enqueued by the caller on the target's waiting
6331 * queue and retried later.
6333 * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg'
6334 * count wide board busy conditions. They are updated in
6335 * adv_build_req and adv_get_sglist, respectively.
6337 return ASC_BUSY;
6338 case ASC_ERROR:
6340 * If an error is returned, then the request has been
6341 * queued on the board done queue. It will be completed
6342 * by the caller.
6344 default:
6345 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
6346 ASC_STATS(scp->device->host, build_error);
6347 return ASC_ERROR;
6351 * Execute the command. If there is no error, add the command
6352 * to the active queue.
6354 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
6355 case ASC_NOERROR:
6356 ASC_STATS(scp->device->host, exe_noerror);
6358 * Increment monotonically increasing per device successful
6359 * request counter. Wrapping doesn't matter.
6361 boardp->reqcnt[scp->device->id]++;
6362 asc_enqueue(&boardp->active, scp, ASC_BACK);
6363 ASC_DBG(1,
6364 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
6365 break;
6366 case ASC_BUSY:
6368 * Caller will enqueue request on the target's waiting queue
6369 * and retry later.
6371 ASC_STATS(scp->device->host, exe_busy);
6372 break;
6373 case ASC_ERROR:
6374 ASC_PRINT2(
6375 "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
6376 boardp->id, adv_dvc_varp->err_code);
6377 ASC_STATS(scp->device->host, exe_error);
6378 scp->result = HOST_BYTE(DID_ERROR);
6379 asc_enqueue(&boardp->done, scp, ASC_BACK);
6380 break;
6381 default:
6382 ASC_PRINT2(
6383 "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
6384 boardp->id, adv_dvc_varp->err_code);
6385 ASC_STATS(scp->device->host, exe_unknown);
6386 scp->result = HOST_BYTE(DID_ERROR);
6387 asc_enqueue(&boardp->done, scp, ASC_BACK);
6388 break;
6392 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
6393 return ret;
6397 * Build a request structure for the Asc Library (Narrow Board).
6399 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
6400 * used to build the request.
6402 * If an error occurs, then queue the request on the board done
6403 * queue and return ASC_ERROR.
6405 STATIC int
6406 asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
6408 struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
6411 * Mutually exclusive access is required to 'asc_scsi_q' and
6412 * 'asc_sg_head' until after the request is started.
6414 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
6417 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
6419 asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
6422 * Build the ASC_SCSI_Q request.
6424 * For narrow boards a CDB length maximum of 12 bytes
6425 * is supported.
6427 if (scp->cmd_len > ASC_MAX_CDB_LEN) {
6428 ASC_PRINT3(
6429 "asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN %d\n",
6430 boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN);
6431 scp->result = HOST_BYTE(DID_ERROR);
6432 asc_enqueue(&boardp->done, scp, ASC_BACK);
6433 return ASC_ERROR;
6435 asc_scsi_q.cdbptr = &scp->cmnd[0];
6436 asc_scsi_q.q2.cdb_len = scp->cmd_len;
6437 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
6438 asc_scsi_q.q1.target_lun = scp->device->lun;
6439 asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
6440 asc_scsi_q.q1.sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
6441 asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
6444 * If there are any outstanding requests for the current target,
6445 * then every 255th request send an ORDERED request. This heuristic
6446 * tries to retain the benefit of request sorting while preventing
6447 * request starvation. 255 is the max number of tags or pending commands
6448 * a device may have outstanding.
6450 * The request count is incremented below for every successfully
6451 * started request.
6454 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
6455 (boardp->reqcnt[scp->device->id] % 255) == 0) {
6456 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
6457 } else {
6458 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
6462 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
6463 * buffer command.
6465 if (scp->use_sg == 0) {
6467 * CDB request of single contiguous buffer.
6469 ASC_STATS(scp->device->host, cont_cnt);
6470 scp->SCp.dma_handle = scp->request_bufflen ?
6471 dma_map_single(dev, scp->request_buffer,
6472 scp->request_bufflen, scp->sc_data_direction) : 0;
6473 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
6474 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
6475 ASC_STATS_ADD(scp->device->host, cont_xfer,
6476 ASC_CEILING(scp->request_bufflen, 512));
6477 asc_scsi_q.q1.sg_queue_cnt = 0;
6478 asc_scsi_q.sg_head = NULL;
6479 } else {
6481 * CDB scatter-gather request list.
6483 int sgcnt;
6484 int use_sg;
6485 struct scatterlist *slp;
6487 slp = (struct scatterlist *)scp->request_buffer;
6488 use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
6490 if (use_sg > scp->device->host->sg_tablesize) {
6491 ASC_PRINT3(
6492 "asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
6493 boardp->id, use_sg, scp->device->host->sg_tablesize);
6494 dma_unmap_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
6495 scp->result = HOST_BYTE(DID_ERROR);
6496 asc_enqueue(&boardp->done, scp, ASC_BACK);
6497 return ASC_ERROR;
6500 ASC_STATS(scp->device->host, sg_cnt);
6503 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
6504 * structure to point to it.
6506 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
6508 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
6509 asc_scsi_q.sg_head = &asc_sg_head;
6510 asc_scsi_q.q1.data_cnt = 0;
6511 asc_scsi_q.q1.data_addr = 0;
6512 /* This is a byte value, otherwise it would need to be swapped. */
6513 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
6514 ASC_STATS_ADD(scp->device->host, sg_elem, asc_sg_head.entry_cnt);
6517 * Convert scatter-gather list into ASC_SG_HEAD list.
6519 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
6520 asc_sg_head.sg_list[sgcnt].addr = cpu_to_le32(sg_dma_address(slp));
6521 asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(sg_dma_len(slp));
6522 ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512));
6526 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
6527 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6529 return ASC_NOERROR;
6533 * Build a request structure for the Adv Library (Wide Board).
6535 * If an adv_req_t can not be allocated to issue the request,
6536 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
6538 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
6539 * microcode for DMA addresses or math operations are byte swapped
6540 * to little-endian order.
6542 STATIC int
6543 adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
6544 ADV_SCSI_REQ_Q **adv_scsiqpp)
6546 adv_req_t *reqp;
6547 ADV_SCSI_REQ_Q *scsiqp;
6548 int i;
6549 int ret;
6550 struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
6553 * Allocate an adv_req_t structure from the board to execute
6554 * the command.
6556 if (boardp->adv_reqp == NULL) {
6557 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
6558 ASC_STATS(scp->device->host, adv_build_noreq);
6559 return ASC_BUSY;
6560 } else {
6561 reqp = boardp->adv_reqp;
6562 boardp->adv_reqp = reqp->next_reqp;
6563 reqp->next_reqp = NULL;
6567 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
6569 scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
6572 * Initialize the structure.
6574 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
6577 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
6579 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
6582 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
6584 reqp->cmndp = scp;
6587 * Build the ADV_SCSI_REQ_Q request.
6591 * Set CDB length and copy it to the request structure.
6592 * For wide boards a CDB length maximum of 16 bytes
6593 * is supported.
6595 if (scp->cmd_len > ADV_MAX_CDB_LEN) {
6596 ASC_PRINT3(
6597 "adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n",
6598 boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
6599 scp->result = HOST_BYTE(DID_ERROR);
6600 asc_enqueue(&boardp->done, scp, ASC_BACK);
6601 return ASC_ERROR;
6603 scsiqp->cdb_len = scp->cmd_len;
6604 /* Copy first 12 CDB bytes to cdb[]. */
6605 for (i = 0; i < scp->cmd_len && i < 12; i++) {
6606 scsiqp->cdb[i] = scp->cmnd[i];
6608 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
6609 for (; i < scp->cmd_len; i++) {
6610 scsiqp->cdb16[i - 12] = scp->cmnd[i];
6613 scsiqp->target_id = scp->device->id;
6614 scsiqp->target_lun = scp->device->lun;
6616 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
6617 scsiqp->sense_len = sizeof(scp->sense_buffer);
6620 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
6621 * buffer command.
6624 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
6625 scsiqp->vdata_addr = scp->request_buffer;
6626 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
6628 if (scp->use_sg == 0) {
6630 * CDB request of single contiguous buffer.
6632 reqp->sgblkp = NULL;
6633 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
6634 if (scp->request_bufflen) {
6635 scsiqp->vdata_addr = scp->request_buffer;
6636 scp->SCp.dma_handle =
6637 dma_map_single(dev, scp->request_buffer,
6638 scp->request_bufflen, scp->sc_data_direction);
6639 } else {
6640 scsiqp->vdata_addr = 0;
6641 scp->SCp.dma_handle = 0;
6643 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
6644 scsiqp->sg_list_ptr = NULL;
6645 scsiqp->sg_real_addr = 0;
6646 ASC_STATS(scp->device->host, cont_cnt);
6647 ASC_STATS_ADD(scp->device->host, cont_xfer,
6648 ASC_CEILING(scp->request_bufflen, 512));
6649 } else {
6651 * CDB scatter-gather request list.
6653 struct scatterlist *slp;
6654 int use_sg;
6656 slp = (struct scatterlist *)scp->request_buffer;
6657 use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
6659 if (use_sg > ADV_MAX_SG_LIST) {
6660 ASC_PRINT3(
6661 "adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
6662 boardp->id, use_sg, scp->device->host->sg_tablesize);
6663 dma_unmap_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
6664 scp->result = HOST_BYTE(DID_ERROR);
6665 asc_enqueue(&boardp->done, scp, ASC_BACK);
6668 * Free the 'adv_req_t' structure by adding it back to the
6669 * board free list.
6671 reqp->next_reqp = boardp->adv_reqp;
6672 boardp->adv_reqp = reqp;
6674 return ASC_ERROR;
6677 if ((ret = adv_get_sglist(boardp, reqp, scp, use_sg)) != ADV_SUCCESS) {
6679 * Free the adv_req_t structure by adding it back to the
6680 * board free list.
6682 reqp->next_reqp = boardp->adv_reqp;
6683 boardp->adv_reqp = reqp;
6685 return ret;
6688 ASC_STATS(scp->device->host, sg_cnt);
6689 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
6692 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
6693 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6695 *adv_scsiqpp = scsiqp;
6697 return ASC_NOERROR;
6701 * Build scatter-gather list for Adv Library (Wide Board).
6703 * Additional ADV_SG_BLOCK structures will need to be allocated
6704 * if the total number of scatter-gather elements exceeds
6705 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
6706 * assumed to be physically contiguous.
6708 * Return:
6709 * ADV_SUCCESS(1) - SG List successfully created
6710 * ADV_ERROR(-1) - SG List creation failed
6712 STATIC int
6713 adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, int use_sg)
6715 adv_sgblk_t *sgblkp;
6716 ADV_SCSI_REQ_Q *scsiqp;
6717 struct scatterlist *slp;
6718 int sg_elem_cnt;
6719 ADV_SG_BLOCK *sg_block, *prev_sg_block;
6720 ADV_PADDR sg_block_paddr;
6721 int i;
6723 scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
6724 slp = (struct scatterlist *) scp->request_buffer;
6725 sg_elem_cnt = use_sg;
6726 prev_sg_block = NULL;
6727 reqp->sgblkp = NULL;
6732 * Allocate a 'adv_sgblk_t' structure from the board free
6733 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
6734 * (15) scatter-gather elements.
6736 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
6737 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
6738 ASC_STATS(scp->device->host, adv_build_nosg);
6741 * Allocation failed. Free 'adv_sgblk_t' structures already
6742 * allocated for the request.
6744 while ((sgblkp = reqp->sgblkp) != NULL)
6746 /* Remove 'sgblkp' from the request list. */
6747 reqp->sgblkp = sgblkp->next_sgblkp;
6749 /* Add 'sgblkp' to the board free list. */
6750 sgblkp->next_sgblkp = boardp->adv_sgblkp;
6751 boardp->adv_sgblkp = sgblkp;
6753 return ASC_BUSY;
6754 } else {
6755 /* Complete 'adv_sgblk_t' board allocation. */
6756 boardp->adv_sgblkp = sgblkp->next_sgblkp;
6757 sgblkp->next_sgblkp = NULL;
6760 * Get 8 byte aligned virtual and physical addresses for
6761 * the allocated ADV_SG_BLOCK structure.
6763 sg_block = (ADV_SG_BLOCK *) ADV_8BALIGN(&sgblkp->sg_block);
6764 sg_block_paddr = virt_to_bus(sg_block);
6767 * Check if this is the first 'adv_sgblk_t' for the request.
6769 if (reqp->sgblkp == NULL)
6771 /* Request's first scatter-gather block. */
6772 reqp->sgblkp = sgblkp;
6775 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
6776 * address pointers.
6778 scsiqp->sg_list_ptr = sg_block;
6779 scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr);
6780 } else
6782 /* Request's second or later scatter-gather block. */
6783 sgblkp->next_sgblkp = reqp->sgblkp;
6784 reqp->sgblkp = sgblkp;
6787 * Point the previous ADV_SG_BLOCK structure to
6788 * the newly allocated ADV_SG_BLOCK structure.
6790 ASC_ASSERT(prev_sg_block != NULL);
6791 prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr);
6795 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
6797 sg_block->sg_list[i].sg_addr = cpu_to_le32(sg_dma_address(slp));
6798 sg_block->sg_list[i].sg_count = cpu_to_le32(sg_dma_len(slp));
6799 ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512));
6801 if (--sg_elem_cnt == 0)
6802 { /* Last ADV_SG_BLOCK and scatter-gather entry. */
6803 sg_block->sg_cnt = i + 1;
6804 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
6805 return ADV_SUCCESS;
6807 slp++;
6809 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
6810 prev_sg_block = sg_block;
6812 while (1);
6813 /* NOTREACHED */
6817 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
6819 * Interrupt callback function for the Narrow SCSI Asc Library.
6821 STATIC void
6822 asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
6824 asc_board_t *boardp;
6825 struct scsi_cmnd *scp;
6826 struct Scsi_Host *shp;
6827 int i;
6829 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
6830 (ulong) asc_dvc_varp, (ulong) qdonep);
6831 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
6834 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
6835 * command that has been completed.
6837 scp = (struct scsi_cmnd *) ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
6838 ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong) scp);
6840 if (scp == NULL) {
6841 ASC_PRINT("asc_isr_callback: scp is NULL\n");
6842 return;
6844 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
6847 * If the request's host pointer is not valid, display a
6848 * message and return.
6850 shp = scp->device->host;
6851 for (i = 0; i < asc_board_count; i++) {
6852 if (asc_host[i] == shp) {
6853 break;
6856 if (i == asc_board_count) {
6857 ASC_PRINT2(
6858 "asc_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
6859 (ulong) scp, (ulong) shp);
6860 return;
6863 ASC_STATS(shp, callback);
6864 ASC_DBG1(1, "asc_isr_callback: shp 0x%lx\n", (ulong) shp);
6867 * If the request isn't found on the active queue, it may
6868 * have been removed to handle a reset request.
6869 * Display a message and return.
6871 boardp = ASC_BOARDP(shp);
6872 ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
6873 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
6874 ASC_PRINT2(
6875 "asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
6876 boardp->id, (ulong) scp);
6877 return;
6881 * 'qdonep' contains the command's ending status.
6883 switch (qdonep->d3.done_stat) {
6884 case QD_NO_ERROR:
6885 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
6886 scp->result = 0;
6889 * If an INQUIRY command completed successfully, then call
6890 * the AscInquiryHandling() function to set-up the device.
6892 if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 &&
6893 (scp->request_bufflen - qdonep->remain_bytes) >= 8)
6895 AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7,
6896 (ASC_SCSI_INQUIRY *) scp->request_buffer);
6900 * Check for an underrun condition.
6902 * If there was no error and an underrun condition, then
6903 * then return the number of underrun bytes.
6905 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
6906 qdonep->remain_bytes <= scp->request_bufflen) {
6907 ASC_DBG1(1, "asc_isr_callback: underrun condition %u bytes\n",
6908 (unsigned) qdonep->remain_bytes);
6909 scp->resid = qdonep->remain_bytes;
6911 break;
6913 case QD_WITH_ERROR:
6914 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
6915 switch (qdonep->d3.host_stat) {
6916 case QHSTA_NO_ERROR:
6917 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
6918 ASC_DBG(2, "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
6919 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
6920 sizeof(scp->sense_buffer));
6922 * Note: The 'status_byte()' macro used by target drivers
6923 * defined in scsi.h shifts the status byte returned by
6924 * host drivers right by 1 bit. This is why target drivers
6925 * also use right shifted status byte definitions. For
6926 * instance target drivers use CHECK_CONDITION, defined to
6927 * 0x1, instead of the SCSI defined check condition value
6928 * of 0x2. Host drivers are supposed to return the status
6929 * byte as it is defined by SCSI.
6931 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
6932 STATUS_BYTE(qdonep->d3.scsi_stat);
6933 } else {
6934 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
6936 break;
6938 default:
6939 /* QHSTA error occurred */
6940 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
6941 qdonep->d3.host_stat);
6942 scp->result = HOST_BYTE(DID_BAD_TARGET);
6943 break;
6945 break;
6947 case QD_ABORTED_BY_HOST:
6948 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
6949 scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.scsi_msg) |
6950 STATUS_BYTE(qdonep->d3.scsi_stat);
6951 break;
6953 default:
6954 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n", qdonep->d3.done_stat);
6955 scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
6956 STATUS_BYTE(qdonep->d3.scsi_stat);
6957 break;
6961 * If the 'init_tidmask' bit isn't already set for the target and the
6962 * current request finished normally, then set the bit for the target
6963 * to indicate that a device is present.
6965 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
6966 qdonep->d3.done_stat == QD_NO_ERROR &&
6967 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
6968 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
6972 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
6973 * function, add the command to the end of the board's done queue.
6974 * The done function for the command will be called from
6975 * advansys_interrupt().
6977 asc_enqueue(&boardp->done, scp, ASC_BACK);
6979 return;
6983 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
6985 * Callback function for the Wide SCSI Adv Library.
6987 STATIC void
6988 adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
6990 asc_board_t *boardp;
6991 adv_req_t *reqp;
6992 adv_sgblk_t *sgblkp;
6993 struct scsi_cmnd *scp;
6994 struct Scsi_Host *shp;
6995 int i;
6996 ADV_DCNT resid_cnt;
6999 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
7000 (ulong) adv_dvc_varp, (ulong) scsiqp);
7001 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
7004 * Get the adv_req_t structure for the command that has been
7005 * completed. The adv_req_t structure actually contains the
7006 * completed ADV_SCSI_REQ_Q structure.
7008 reqp = (adv_req_t *) ADV_U32_TO_VADDR(scsiqp->srb_ptr);
7009 ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong) reqp);
7010 if (reqp == NULL) {
7011 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
7012 return;
7016 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
7017 * command that has been completed.
7019 * Note: The adv_req_t request structure and adv_sgblk_t structure,
7020 * if any, are dropped, because a board structure pointer can not be
7021 * determined.
7023 scp = reqp->cmndp;
7024 ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong) scp);
7025 if (scp == NULL) {
7026 ASC_PRINT("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
7027 return;
7029 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
7032 * If the request's host pointer is not valid, display a message
7033 * and return.
7035 shp = scp->device->host;
7036 for (i = 0; i < asc_board_count; i++) {
7037 if (asc_host[i] == shp) {
7038 break;
7042 * Note: If the host structure is not found, the adv_req_t request
7043 * structure and adv_sgblk_t structure, if any, is dropped.
7045 if (i == asc_board_count) {
7046 ASC_PRINT2(
7047 "adv_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
7048 (ulong) scp, (ulong) shp);
7049 return;
7052 ASC_STATS(shp, callback);
7053 ASC_DBG1(1, "adv_isr_callback: shp 0x%lx\n", (ulong) shp);
7056 * If the request isn't found on the active queue, it may have been
7057 * removed to handle a reset request. Display a message and return.
7059 * Note: Because the structure may still be in use don't attempt
7060 * to free the adv_req_t and adv_sgblk_t, if any, structures.
7062 boardp = ASC_BOARDP(shp);
7063 ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
7064 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
7065 ASC_PRINT2(
7066 "adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
7067 boardp->id, (ulong) scp);
7068 return;
7072 * 'done_status' contains the command's ending status.
7074 switch (scsiqp->done_status) {
7075 case QD_NO_ERROR:
7076 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
7077 scp->result = 0;
7080 * Check for an underrun condition.
7082 * If there was no error and an underrun condition, then
7083 * then return the number of underrun bytes.
7085 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
7086 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
7087 resid_cnt <= scp->request_bufflen) {
7088 ASC_DBG1(1, "adv_isr_callback: underrun condition %lu bytes\n",
7089 (ulong) resid_cnt);
7090 scp->resid = resid_cnt;
7092 break;
7094 case QD_WITH_ERROR:
7095 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
7096 switch (scsiqp->host_status) {
7097 case QHSTA_NO_ERROR:
7098 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
7099 ASC_DBG(2, "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
7100 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
7101 sizeof(scp->sense_buffer));
7103 * Note: The 'status_byte()' macro used by target drivers
7104 * defined in scsi.h shifts the status byte returned by
7105 * host drivers right by 1 bit. This is why target drivers
7106 * also use right shifted status byte definitions. For
7107 * instance target drivers use CHECK_CONDITION, defined to
7108 * 0x1, instead of the SCSI defined check condition value
7109 * of 0x2. Host drivers are supposed to return the status
7110 * byte as it is defined by SCSI.
7112 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
7113 STATUS_BYTE(scsiqp->scsi_status);
7114 } else {
7115 scp->result = STATUS_BYTE(scsiqp->scsi_status);
7117 break;
7119 default:
7120 /* Some other QHSTA error occurred. */
7121 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
7122 scsiqp->host_status);
7123 scp->result = HOST_BYTE(DID_BAD_TARGET);
7124 break;
7126 break;
7128 case QD_ABORTED_BY_HOST:
7129 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
7130 scp->result = HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
7131 break;
7133 default:
7134 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n", scsiqp->done_status);
7135 scp->result = HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
7136 break;
7140 * If the 'init_tidmask' bit isn't already set for the target and the
7141 * current request finished normally, then set the bit for the target
7142 * to indicate that a device is present.
7144 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
7145 scsiqp->done_status == QD_NO_ERROR &&
7146 scsiqp->host_status == QHSTA_NO_ERROR) {
7147 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
7151 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
7152 * function, add the command to the end of the board's done queue.
7153 * The done function for the command will be called from
7154 * advansys_interrupt().
7156 asc_enqueue(&boardp->done, scp, ASC_BACK);
7159 * Free all 'adv_sgblk_t' structures allocated for the request.
7161 while ((sgblkp = reqp->sgblkp) != NULL)
7163 /* Remove 'sgblkp' from the request list. */
7164 reqp->sgblkp = sgblkp->next_sgblkp;
7166 /* Add 'sgblkp' to the board free list. */
7167 sgblkp->next_sgblkp = boardp->adv_sgblkp;
7168 boardp->adv_sgblkp = sgblkp;
7172 * Free the adv_req_t structure used with the command by adding
7173 * it back to the board free list.
7175 reqp->next_reqp = boardp->adv_reqp;
7176 boardp->adv_reqp = reqp;
7178 ASC_DBG(1, "adv_isr_callback: done\n");
7180 return;
7184 * adv_async_callback() - Adv Library asynchronous event callback function.
7186 STATIC void
7187 adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
7189 switch (code)
7191 case ADV_ASYNC_SCSI_BUS_RESET_DET:
7193 * The firmware detected a SCSI Bus reset.
7195 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
7196 break;
7198 case ADV_ASYNC_RDMA_FAILURE:
7200 * Handle RDMA failure by resetting the SCSI Bus and
7201 * possibly the chip if it is unresponsive. Log the error
7202 * with a unique code.
7204 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
7205 AdvResetChipAndSB(adv_dvc_varp);
7206 break;
7208 case ADV_HOST_SCSI_BUS_RESET:
7210 * Host generated SCSI bus reset occurred.
7212 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
7213 break;
7215 default:
7216 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
7217 break;
7222 * Add a 'REQP' to the end of specified queue. Set 'tidmask'
7223 * to indicate a command is queued for the device.
7225 * 'flag' may be either ASC_FRONT or ASC_BACK.
7227 * 'REQPNEXT(reqp)' returns reqp's next pointer.
7229 STATIC void
7230 asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
7232 int tid;
7234 ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
7235 (ulong) ascq, (ulong) reqp, flag);
7236 ASC_ASSERT(reqp != NULL);
7237 ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
7238 tid = REQPTID(reqp);
7239 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7240 if (flag == ASC_FRONT) {
7241 reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
7242 ascq->q_first[tid] = reqp;
7243 /* If the queue was empty, set the last pointer. */
7244 if (ascq->q_last[tid] == NULL) {
7245 ascq->q_last[tid] = reqp;
7247 } else { /* ASC_BACK */
7248 if (ascq->q_last[tid] != NULL) {
7249 ascq->q_last[tid]->host_scribble = (unsigned char *)reqp;
7251 ascq->q_last[tid] = reqp;
7252 reqp->host_scribble = NULL;
7253 /* If the queue was empty, set the first pointer. */
7254 if (ascq->q_first[tid] == NULL) {
7255 ascq->q_first[tid] = reqp;
7258 /* The queue has at least one entry, set its bit. */
7259 ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
7260 #ifdef ADVANSYS_STATS
7261 /* Maintain request queue statistics. */
7262 ascq->q_tot_cnt[tid]++;
7263 ascq->q_cur_cnt[tid]++;
7264 if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
7265 ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
7266 ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
7267 tid, ascq->q_max_cnt[tid]);
7269 REQPTIME(reqp) = REQTIMESTAMP();
7270 #endif /* ADVANSYS_STATS */
7271 ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong) reqp);
7272 return;
7276 * Return first queued 'REQP' on the specified queue for
7277 * the specified target device. Clear the 'tidmask' bit for
7278 * the device if no more commands are left queued for it.
7280 * 'REQPNEXT(reqp)' returns reqp's next pointer.
7282 STATIC REQP
7283 asc_dequeue(asc_queue_t *ascq, int tid)
7285 REQP reqp;
7287 ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong) ascq, tid);
7288 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7289 if ((reqp = ascq->q_first[tid]) != NULL) {
7290 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
7291 ascq->q_first[tid] = REQPNEXT(reqp);
7292 /* If the queue is empty, clear its bit and the last pointer. */
7293 if (ascq->q_first[tid] == NULL) {
7294 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7295 ASC_ASSERT(ascq->q_last[tid] == reqp);
7296 ascq->q_last[tid] = NULL;
7298 #ifdef ADVANSYS_STATS
7299 /* Maintain request queue statistics. */
7300 ascq->q_cur_cnt[tid]--;
7301 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
7302 REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
7303 #endif /* ADVANSYS_STATS */
7305 ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong) reqp);
7306 return reqp;
7310 * Return a pointer to a singly linked list of all the requests queued
7311 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
7313 * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
7314 * the last request returned in the singly linked list.
7316 * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
7317 * then all queued requests are concatenated into one list and
7318 * returned.
7320 * Note: If 'lastpp' is used to append a new list to the end of
7321 * an old list, only change the old list last pointer if '*lastpp'
7322 * (or the function return value) is not NULL, i.e. use a temporary
7323 * variable for 'lastpp' and check its value after the function return
7324 * before assigning it to the list last pointer.
7326 * Unfortunately collecting queuing time statistics adds overhead to
7327 * the function that isn't inherent to the function's algorithm.
7329 STATIC REQP
7330 asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
7332 REQP firstp, lastp;
7333 int i;
7335 ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong) ascq, tid);
7336 ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
7339 * If 'tid' is not ASC_TID_ALL, return requests only for
7340 * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
7341 * requests for all tids.
7343 if (tid != ASC_TID_ALL) {
7344 /* Return all requests for the specified 'tid'. */
7345 if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
7346 /* List is empty; Set first and last return pointers to NULL. */
7347 firstp = lastp = NULL;
7348 } else {
7349 firstp = ascq->q_first[tid];
7350 lastp = ascq->q_last[tid];
7351 ascq->q_first[tid] = ascq->q_last[tid] = NULL;
7352 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7353 #ifdef ADVANSYS_STATS
7355 REQP reqp;
7356 ascq->q_cur_cnt[tid] = 0;
7357 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
7358 REQTIMESTAT("asc_dequeue_list", ascq, reqp, tid);
7361 #endif /* ADVANSYS_STATS */
7363 } else {
7364 /* Return all requests for all tids. */
7365 firstp = lastp = NULL;
7366 for (i = 0; i <= ADV_MAX_TID; i++) {
7367 if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
7368 if (firstp == NULL) {
7369 firstp = ascq->q_first[i];
7370 lastp = ascq->q_last[i];
7371 } else {
7372 ASC_ASSERT(lastp != NULL);
7373 lastp->host_scribble = (unsigned char *)ascq->q_first[i];
7374 lastp = ascq->q_last[i];
7376 ascq->q_first[i] = ascq->q_last[i] = NULL;
7377 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7378 #ifdef ADVANSYS_STATS
7379 ascq->q_cur_cnt[i] = 0;
7380 #endif /* ADVANSYS_STATS */
7383 #ifdef ADVANSYS_STATS
7385 REQP reqp;
7386 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
7387 REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->device->id);
7390 #endif /* ADVANSYS_STATS */
7392 if (lastpp) {
7393 *lastpp = lastp;
7395 ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong) firstp);
7396 return firstp;
7400 * Remove the specified 'REQP' from the specified queue for
7401 * the specified target device. Clear the 'tidmask' bit for the
7402 * device if no more commands are left queued for it.
7404 * 'REQPNEXT(reqp)' returns reqp's the next pointer.
7406 * Return ASC_TRUE if the command was found and removed,
7407 * otherwise return ASC_FALSE.
7409 STATIC int
7410 asc_rmqueue(asc_queue_t *ascq, REQP reqp)
7412 REQP currp, prevp;
7413 int tid;
7414 int ret = ASC_FALSE;
7416 ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
7417 (ulong) ascq, (ulong) reqp);
7418 ASC_ASSERT(reqp != NULL);
7420 tid = REQPTID(reqp);
7421 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7424 * Handle the common case of 'reqp' being the first
7425 * entry on the queue.
7427 if (reqp == ascq->q_first[tid]) {
7428 ret = ASC_TRUE;
7429 ascq->q_first[tid] = REQPNEXT(reqp);
7430 /* If the queue is now empty, clear its bit and the last pointer. */
7431 if (ascq->q_first[tid] == NULL) {
7432 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7433 ASC_ASSERT(ascq->q_last[tid] == reqp);
7434 ascq->q_last[tid] = NULL;
7436 } else if (ascq->q_first[tid] != NULL) {
7437 ASC_ASSERT(ascq->q_last[tid] != NULL);
7439 * Because the case of 'reqp' being the first entry has been
7440 * handled above and it is known the queue is not empty, if
7441 * 'reqp' is found on the queue it is guaranteed the queue will
7442 * not become empty and that 'q_first[tid]' will not be changed.
7444 * Set 'prevp' to the first entry, 'currp' to the second entry,
7445 * and search for 'reqp'.
7447 for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
7448 currp; prevp = currp, currp = REQPNEXT(currp)) {
7449 if (currp == reqp) {
7450 ret = ASC_TRUE;
7451 prevp->host_scribble = (unsigned char *)REQPNEXT(currp);
7452 reqp->host_scribble = NULL;
7453 if (ascq->q_last[tid] == reqp) {
7454 ascq->q_last[tid] = prevp;
7456 break;
7460 #ifdef ADVANSYS_STATS
7461 /* Maintain request queue statistics. */
7462 if (ret == ASC_TRUE) {
7463 ascq->q_cur_cnt[tid]--;
7464 REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
7466 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
7467 #endif /* ADVANSYS_STATS */
7468 ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong) reqp, ret);
7469 return ret;
7473 * Execute as many queued requests as possible for the specified queue.
7475 * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd.
7477 STATIC void
7478 asc_execute_queue(asc_queue_t *ascq)
7480 ADV_SCSI_BIT_ID_TYPE scan_tidmask;
7481 REQP reqp;
7482 int i;
7484 ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong) ascq);
7486 * Execute queued commands for devices attached to
7487 * the current board in round-robin fashion.
7489 scan_tidmask = ascq->q_tidmask;
7490 do {
7491 for (i = 0; i <= ADV_MAX_TID; i++) {
7492 if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
7493 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
7494 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7495 } else if (asc_execute_scsi_cmnd((struct scsi_cmnd *) reqp)
7496 == ASC_BUSY) {
7497 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7499 * The request returned ASC_BUSY. Enqueue at the front of
7500 * target's waiting list to maintain correct ordering.
7502 asc_enqueue(ascq, reqp, ASC_FRONT);
7506 } while (scan_tidmask);
7507 return;
7510 #ifdef CONFIG_PROC_FS
7512 * asc_prt_board_devices()
7514 * Print driver information for devices attached to the board.
7516 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7517 * cf. asc_prt_line().
7519 * Return the number of characters copied into 'cp'. No more than
7520 * 'cplen' characters will be copied to 'cp'.
7522 STATIC int
7523 asc_prt_board_devices(struct Scsi_Host *shp, char *cp, int cplen)
7525 asc_board_t *boardp;
7526 int leftlen;
7527 int totlen;
7528 int len;
7529 int chip_scsi_id;
7530 int i;
7532 boardp = ASC_BOARDP(shp);
7533 leftlen = cplen;
7534 totlen = len = 0;
7536 len = asc_prt_line(cp, leftlen,
7537 "\nDevice Information for AdvanSys SCSI Host %d:\n", shp->host_no);
7538 ASC_PRT_NEXT();
7540 if (ASC_NARROW_BOARD(boardp)) {
7541 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7542 } else {
7543 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7546 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
7547 ASC_PRT_NEXT();
7548 for (i = 0; i <= ADV_MAX_TID; i++) {
7549 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
7550 len = asc_prt_line(cp, leftlen, " %X,", i);
7551 ASC_PRT_NEXT();
7554 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
7555 ASC_PRT_NEXT();
7557 return totlen;
7561 * Display Wide Board BIOS Information.
7563 STATIC int
7564 asc_prt_adv_bios(struct Scsi_Host *shp, char *cp, int cplen)
7566 asc_board_t *boardp;
7567 int leftlen;
7568 int totlen;
7569 int len;
7570 ushort major, minor, letter;
7572 boardp = ASC_BOARDP(shp);
7573 leftlen = cplen;
7574 totlen = len = 0;
7576 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
7577 ASC_PRT_NEXT();
7580 * If the BIOS saved a valid signature, then fill in
7581 * the BIOS code segment base address.
7583 if (boardp->bios_signature != 0x55AA) {
7584 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
7585 ASC_PRT_NEXT();
7586 len = asc_prt_line(cp, leftlen,
7587 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
7588 ASC_PRT_NEXT();
7589 len = asc_prt_line(cp, leftlen,
7590 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
7591 ASC_PRT_NEXT();
7592 } else {
7593 major = (boardp->bios_version >> 12) & 0xF;
7594 minor = (boardp->bios_version >> 8) & 0xF;
7595 letter = (boardp->bios_version & 0xFF);
7597 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
7598 major, minor, letter >= 26 ? '?' : letter + 'A');
7599 ASC_PRT_NEXT();
7602 * Current available ROM BIOS release is 3.1I for UW
7603 * and 3.2I for U2W. This code doesn't differentiate
7604 * UW and U2W boards.
7606 if (major < 3 || (major <= 3 && minor < 1) ||
7607 (major <= 3 && minor <= 1 && letter < ('I'- 'A'))) {
7608 len = asc_prt_line(cp, leftlen,
7609 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
7610 ASC_PRT_NEXT();
7611 len = asc_prt_line(cp, leftlen,
7612 "ftp://ftp.connectcom.net/pub\n");
7613 ASC_PRT_NEXT();
7617 return totlen;
7621 * Add serial number to information bar if signature AAh
7622 * is found in at bit 15-9 (7 bits) of word 1.
7624 * Serial Number consists fo 12 alpha-numeric digits.
7626 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
7627 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
7628 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
7629 * 5 - Product revision (A-J) Word0: " "
7631 * Signature Word1: 15-9 (7 bits)
7632 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
7633 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
7635 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
7637 * Note 1: Only production cards will have a serial number.
7639 * Note 2: Signature is most significant 7 bits (0xFE).
7641 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
7643 STATIC int
7644 asc_get_eeprom_string(ushort *serialnum, uchar *cp)
7646 ushort w, num;
7648 if ((serialnum[1] & 0xFE00) != ((ushort) 0xAA << 8)) {
7649 return ASC_FALSE;
7650 } else {
7652 * First word - 6 digits.
7654 w = serialnum[0];
7656 /* Product type - 1st digit. */
7657 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
7658 /* Product type is P=Prototype */
7659 *cp += 0x8;
7661 cp++;
7663 /* Manufacturing location - 2nd digit. */
7664 *cp++ = 'A' + ((w & 0x1C00) >> 10);
7666 /* Product ID - 3rd, 4th digits. */
7667 num = w & 0x3FF;
7668 *cp++ = '0' + (num / 100);
7669 num %= 100;
7670 *cp++ = '0' + (num / 10);
7672 /* Product revision - 5th digit. */
7673 *cp++ = 'A' + (num % 10);
7676 * Second word
7678 w = serialnum[1];
7681 * Year - 6th digit.
7683 * If bit 15 of third word is set, then the
7684 * last digit of the year is greater than 7.
7686 if (serialnum[2] & 0x8000) {
7687 *cp++ = '8' + ((w & 0x1C0) >> 6);
7688 } else {
7689 *cp++ = '0' + ((w & 0x1C0) >> 6);
7692 /* Week of year - 7th, 8th digits. */
7693 num = w & 0x003F;
7694 *cp++ = '0' + num / 10;
7695 num %= 10;
7696 *cp++ = '0' + num;
7699 * Third word
7701 w = serialnum[2] & 0x7FFF;
7703 /* Serial number - 9th digit. */
7704 *cp++ = 'A' + (w / 1000);
7706 /* 10th, 11th, 12th digits. */
7707 num = w % 1000;
7708 *cp++ = '0' + num / 100;
7709 num %= 100;
7710 *cp++ = '0' + num / 10;
7711 num %= 10;
7712 *cp++ = '0' + num;
7714 *cp = '\0'; /* Null Terminate the string. */
7715 return ASC_TRUE;
7720 * asc_prt_asc_board_eeprom()
7722 * Print board EEPROM configuration.
7724 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7725 * cf. asc_prt_line().
7727 * Return the number of characters copied into 'cp'. No more than
7728 * 'cplen' characters will be copied to 'cp'.
7730 STATIC int
7731 asc_prt_asc_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
7733 asc_board_t *boardp;
7734 ASC_DVC_VAR *asc_dvc_varp;
7735 int leftlen;
7736 int totlen;
7737 int len;
7738 ASCEEP_CONFIG *ep;
7739 int i;
7740 #ifdef CONFIG_ISA
7741 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
7742 #endif /* CONFIG_ISA */
7743 uchar serialstr[13];
7745 boardp = ASC_BOARDP(shp);
7746 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
7747 ep = &boardp->eep_config.asc_eep;
7749 leftlen = cplen;
7750 totlen = len = 0;
7752 len = asc_prt_line(cp, leftlen,
7753 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
7754 ASC_PRT_NEXT();
7756 if (asc_get_eeprom_string((ushort *) &ep->adapter_info[0], serialstr) ==
7757 ASC_TRUE) {
7758 len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
7759 ASC_PRT_NEXT();
7760 } else {
7761 if (ep->adapter_info[5] == 0xBB) {
7762 len = asc_prt_line(cp, leftlen,
7763 " Default Settings Used for EEPROM-less Adapter.\n");
7764 ASC_PRT_NEXT();
7765 } else {
7766 len = asc_prt_line(cp, leftlen,
7767 " Serial Number Signature Not Present.\n");
7768 ASC_PRT_NEXT();
7772 len = asc_prt_line(cp, leftlen,
7773 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7774 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng, ep->max_tag_qng);
7775 ASC_PRT_NEXT();
7777 len = asc_prt_line(cp, leftlen,
7778 " cntl 0x%x, no_scam 0x%x\n",
7779 ep->cntl, ep->no_scam);
7780 ASC_PRT_NEXT();
7782 len = asc_prt_line(cp, leftlen,
7783 " Target ID: ");
7784 ASC_PRT_NEXT();
7785 for (i = 0; i <= ASC_MAX_TID; i++) {
7786 len = asc_prt_line(cp, leftlen, " %d", i);
7787 ASC_PRT_NEXT();
7789 len = asc_prt_line(cp, leftlen, "\n");
7790 ASC_PRT_NEXT();
7792 len = asc_prt_line(cp, leftlen,
7793 " Disconnects: ");
7794 ASC_PRT_NEXT();
7795 for (i = 0; i <= ASC_MAX_TID; i++) {
7796 len = asc_prt_line(cp, leftlen, " %c",
7797 (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7798 ASC_PRT_NEXT();
7800 len = asc_prt_line(cp, leftlen, "\n");
7801 ASC_PRT_NEXT();
7803 len = asc_prt_line(cp, leftlen,
7804 " Command Queuing: ");
7805 ASC_PRT_NEXT();
7806 for (i = 0; i <= ASC_MAX_TID; i++) {
7807 len = asc_prt_line(cp, leftlen, " %c",
7808 (ep->use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7809 ASC_PRT_NEXT();
7811 len = asc_prt_line(cp, leftlen, "\n");
7812 ASC_PRT_NEXT();
7814 len = asc_prt_line(cp, leftlen,
7815 " Start Motor: ");
7816 ASC_PRT_NEXT();
7817 for (i = 0; i <= ASC_MAX_TID; i++) {
7818 len = asc_prt_line(cp, leftlen, " %c",
7819 (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7820 ASC_PRT_NEXT();
7822 len = asc_prt_line(cp, leftlen, "\n");
7823 ASC_PRT_NEXT();
7825 len = asc_prt_line(cp, leftlen,
7826 " Synchronous Transfer:");
7827 ASC_PRT_NEXT();
7828 for (i = 0; i <= ASC_MAX_TID; i++) {
7829 len = asc_prt_line(cp, leftlen, " %c",
7830 (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7831 ASC_PRT_NEXT();
7833 len = asc_prt_line(cp, leftlen, "\n");
7834 ASC_PRT_NEXT();
7836 #ifdef CONFIG_ISA
7837 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
7838 len = asc_prt_line(cp, leftlen,
7839 " Host ISA DMA speed: %d MB/S\n",
7840 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
7841 ASC_PRT_NEXT();
7843 #endif /* CONFIG_ISA */
7845 return totlen;
7849 * asc_prt_adv_board_eeprom()
7851 * Print board EEPROM configuration.
7853 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7854 * cf. asc_prt_line().
7856 * Return the number of characters copied into 'cp'. No more than
7857 * 'cplen' characters will be copied to 'cp'.
7859 STATIC int
7860 asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
7862 asc_board_t *boardp;
7863 ADV_DVC_VAR *adv_dvc_varp;
7864 int leftlen;
7865 int totlen;
7866 int len;
7867 int i;
7868 char *termstr;
7869 uchar serialstr[13];
7870 ADVEEP_3550_CONFIG *ep_3550 = NULL;
7871 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
7872 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
7873 ushort word;
7874 ushort *wordp;
7875 ushort sdtr_speed = 0;
7877 boardp = ASC_BOARDP(shp);
7878 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
7879 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7881 ep_3550 = &boardp->eep_config.adv_3550_eep;
7882 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7884 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
7885 } else
7887 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
7890 leftlen = cplen;
7891 totlen = len = 0;
7893 len = asc_prt_line(cp, leftlen,
7894 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
7895 ASC_PRT_NEXT();
7897 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7899 wordp = &ep_3550->serial_number_word1;
7900 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7902 wordp = &ep_38C0800->serial_number_word1;
7903 } else
7905 wordp = &ep_38C1600->serial_number_word1;
7908 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
7909 len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
7910 ASC_PRT_NEXT();
7911 } else {
7912 len = asc_prt_line(cp, leftlen,
7913 " Serial Number Signature Not Present.\n");
7914 ASC_PRT_NEXT();
7917 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7919 len = asc_prt_line(cp, leftlen,
7920 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7921 ep_3550->adapter_scsi_id, ep_3550->max_host_qng,
7922 ep_3550->max_dvc_qng);
7923 ASC_PRT_NEXT();
7924 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7926 len = asc_prt_line(cp, leftlen,
7927 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7928 ep_38C0800->adapter_scsi_id, ep_38C0800->max_host_qng,
7929 ep_38C0800->max_dvc_qng);
7930 ASC_PRT_NEXT();
7931 } else
7933 len = asc_prt_line(cp, leftlen,
7934 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7935 ep_38C1600->adapter_scsi_id, ep_38C1600->max_host_qng,
7936 ep_38C1600->max_dvc_qng);
7937 ASC_PRT_NEXT();
7939 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7941 word = ep_3550->termination;
7942 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7944 word = ep_38C0800->termination_lvd;
7945 } else
7947 word = ep_38C1600->termination_lvd;
7949 switch (word) {
7950 case 1:
7951 termstr = "Low Off/High Off";
7952 break;
7953 case 2:
7954 termstr = "Low Off/High On";
7955 break;
7956 case 3:
7957 termstr = "Low On/High On";
7958 break;
7959 default:
7960 case 0:
7961 termstr = "Automatic";
7962 break;
7965 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7967 len = asc_prt_line(cp, leftlen,
7968 " termination: %u (%s), bios_ctrl: 0x%x\n",
7969 ep_3550->termination, termstr, ep_3550->bios_ctrl);
7970 ASC_PRT_NEXT();
7971 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7973 len = asc_prt_line(cp, leftlen,
7974 " termination: %u (%s), bios_ctrl: 0x%x\n",
7975 ep_38C0800->termination_lvd, termstr, ep_38C0800->bios_ctrl);
7976 ASC_PRT_NEXT();
7977 } else
7979 len = asc_prt_line(cp, leftlen,
7980 " termination: %u (%s), bios_ctrl: 0x%x\n",
7981 ep_38C1600->termination_lvd, termstr, ep_38C1600->bios_ctrl);
7982 ASC_PRT_NEXT();
7985 len = asc_prt_line(cp, leftlen,
7986 " Target ID: ");
7987 ASC_PRT_NEXT();
7988 for (i = 0; i <= ADV_MAX_TID; i++) {
7989 len = asc_prt_line(cp, leftlen, " %X", i);
7990 ASC_PRT_NEXT();
7992 len = asc_prt_line(cp, leftlen, "\n");
7993 ASC_PRT_NEXT();
7995 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7997 word = ep_3550->disc_enable;
7998 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8000 word = ep_38C0800->disc_enable;
8001 } else
8003 word = ep_38C1600->disc_enable;
8005 len = asc_prt_line(cp, leftlen,
8006 " Disconnects: ");
8007 ASC_PRT_NEXT();
8008 for (i = 0; i <= ADV_MAX_TID; i++) {
8009 len = asc_prt_line(cp, leftlen, " %c",
8010 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8011 ASC_PRT_NEXT();
8013 len = asc_prt_line(cp, leftlen, "\n");
8014 ASC_PRT_NEXT();
8016 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8018 word = ep_3550->tagqng_able;
8019 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8021 word = ep_38C0800->tagqng_able;
8022 } else
8024 word = ep_38C1600->tagqng_able;
8026 len = asc_prt_line(cp, leftlen,
8027 " Command Queuing: ");
8028 ASC_PRT_NEXT();
8029 for (i = 0; i <= ADV_MAX_TID; i++) {
8030 len = asc_prt_line(cp, leftlen, " %c",
8031 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8032 ASC_PRT_NEXT();
8034 len = asc_prt_line(cp, leftlen, "\n");
8035 ASC_PRT_NEXT();
8037 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8039 word = ep_3550->start_motor;
8040 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8042 word = ep_38C0800->start_motor;
8043 } else
8045 word = ep_38C1600->start_motor;
8047 len = asc_prt_line(cp, leftlen,
8048 " Start Motor: ");
8049 ASC_PRT_NEXT();
8050 for (i = 0; i <= ADV_MAX_TID; i++) {
8051 len = asc_prt_line(cp, leftlen, " %c",
8052 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8053 ASC_PRT_NEXT();
8055 len = asc_prt_line(cp, leftlen, "\n");
8056 ASC_PRT_NEXT();
8058 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8060 len = asc_prt_line(cp, leftlen,
8061 " Synchronous Transfer:");
8062 ASC_PRT_NEXT();
8063 for (i = 0; i <= ADV_MAX_TID; i++) {
8064 len = asc_prt_line(cp, leftlen, " %c",
8065 (ep_3550->sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8066 ASC_PRT_NEXT();
8068 len = asc_prt_line(cp, leftlen, "\n");
8069 ASC_PRT_NEXT();
8072 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8074 len = asc_prt_line(cp, leftlen,
8075 " Ultra Transfer: ");
8076 ASC_PRT_NEXT();
8077 for (i = 0; i <= ADV_MAX_TID; i++) {
8078 len = asc_prt_line(cp, leftlen, " %c",
8079 (ep_3550->ultra_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8080 ASC_PRT_NEXT();
8082 len = asc_prt_line(cp, leftlen, "\n");
8083 ASC_PRT_NEXT();
8086 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8088 word = ep_3550->wdtr_able;
8089 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8091 word = ep_38C0800->wdtr_able;
8092 } else
8094 word = ep_38C1600->wdtr_able;
8096 len = asc_prt_line(cp, leftlen,
8097 " Wide Transfer: ");
8098 ASC_PRT_NEXT();
8099 for (i = 0; i <= ADV_MAX_TID; i++) {
8100 len = asc_prt_line(cp, leftlen, " %c",
8101 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8102 ASC_PRT_NEXT();
8104 len = asc_prt_line(cp, leftlen, "\n");
8105 ASC_PRT_NEXT();
8107 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
8108 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600)
8110 len = asc_prt_line(cp, leftlen,
8111 " Synchronous Transfer Speed (Mhz):\n ");
8112 ASC_PRT_NEXT();
8113 for (i = 0; i <= ADV_MAX_TID; i++) {
8114 char *speed_str;
8116 if (i == 0)
8118 sdtr_speed = adv_dvc_varp->sdtr_speed1;
8119 } else if (i == 4)
8121 sdtr_speed = adv_dvc_varp->sdtr_speed2;
8122 } else if (i == 8)
8124 sdtr_speed = adv_dvc_varp->sdtr_speed3;
8125 } else if (i == 12)
8127 sdtr_speed = adv_dvc_varp->sdtr_speed4;
8129 switch (sdtr_speed & ADV_MAX_TID)
8131 case 0: speed_str = "Off"; break;
8132 case 1: speed_str = " 5"; break;
8133 case 2: speed_str = " 10"; break;
8134 case 3: speed_str = " 20"; break;
8135 case 4: speed_str = " 40"; break;
8136 case 5: speed_str = " 80"; break;
8137 default: speed_str = "Unk"; break;
8139 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
8140 ASC_PRT_NEXT();
8141 if (i == 7)
8143 len = asc_prt_line(cp, leftlen, "\n ");
8144 ASC_PRT_NEXT();
8146 sdtr_speed >>= 4;
8148 len = asc_prt_line(cp, leftlen, "\n");
8149 ASC_PRT_NEXT();
8152 return totlen;
8156 * asc_prt_driver_conf()
8158 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8159 * cf. asc_prt_line().
8161 * Return the number of characters copied into 'cp'. No more than
8162 * 'cplen' characters will be copied to 'cp'.
8164 STATIC int
8165 asc_prt_driver_conf(struct Scsi_Host *shp, char *cp, int cplen)
8167 asc_board_t *boardp;
8168 int leftlen;
8169 int totlen;
8170 int len;
8171 int chip_scsi_id;
8173 boardp = ASC_BOARDP(shp);
8175 leftlen = cplen;
8176 totlen = len = 0;
8178 len = asc_prt_line(cp, leftlen,
8179 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
8180 shp->host_no);
8181 ASC_PRT_NEXT();
8183 len = asc_prt_line(cp, leftlen,
8184 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
8185 shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun,
8186 shp->max_channel);
8187 ASC_PRT_NEXT();
8189 len = asc_prt_line(cp, leftlen,
8190 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
8191 shp->unique_id, shp->can_queue, shp->this_id, shp->sg_tablesize,
8192 shp->cmd_per_lun);
8193 ASC_PRT_NEXT();
8195 len = asc_prt_line(cp, leftlen,
8196 " unchecked_isa_dma %d, use_clustering %d\n",
8197 shp->unchecked_isa_dma, shp->use_clustering);
8198 ASC_PRT_NEXT();
8200 len = asc_prt_line(cp, leftlen,
8201 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
8202 boardp->flags, boardp->last_reset, jiffies, boardp->asc_n_io_port);
8203 ASC_PRT_NEXT();
8205 /* 'shp->n_io_port' may be truncated because it is only one byte. */
8206 len = asc_prt_line(cp, leftlen,
8207 " io_port 0x%x, n_io_port 0x%x\n",
8208 shp->io_port, shp->n_io_port);
8209 ASC_PRT_NEXT();
8211 if (ASC_NARROW_BOARD(boardp)) {
8212 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
8213 } else {
8214 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
8217 return totlen;
8221 * asc_prt_asc_board_info()
8223 * Print dynamic board configuration information.
8225 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8226 * cf. asc_prt_line().
8228 * Return the number of characters copied into 'cp'. No more than
8229 * 'cplen' characters will be copied to 'cp'.
8231 STATIC int
8232 asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8234 asc_board_t *boardp;
8235 int chip_scsi_id;
8236 int leftlen;
8237 int totlen;
8238 int len;
8239 ASC_DVC_VAR *v;
8240 ASC_DVC_CFG *c;
8241 int i;
8242 int renegotiate = 0;
8244 boardp = ASC_BOARDP(shp);
8245 v = &boardp->dvc_var.asc_dvc_var;
8246 c = &boardp->dvc_cfg.asc_dvc_cfg;
8247 chip_scsi_id = c->chip_scsi_id;
8249 leftlen = cplen;
8250 totlen = len = 0;
8252 len = asc_prt_line(cp, leftlen,
8253 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8254 shp->host_no);
8255 ASC_PRT_NEXT();
8257 len = asc_prt_line(cp, leftlen,
8258 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
8259 c->chip_version, c->lib_version, c->lib_serial_no, c->mcode_date);
8260 ASC_PRT_NEXT();
8262 len = asc_prt_line(cp, leftlen,
8263 " mcode_version 0x%x, err_code %u\n",
8264 c->mcode_version, v->err_code);
8265 ASC_PRT_NEXT();
8267 /* Current number of commands waiting for the host. */
8268 len = asc_prt_line(cp, leftlen,
8269 " Total Command Pending: %d\n", v->cur_total_qng);
8270 ASC_PRT_NEXT();
8272 len = asc_prt_line(cp, leftlen,
8273 " Command Queuing:");
8274 ASC_PRT_NEXT();
8275 for (i = 0; i <= ASC_MAX_TID; i++) {
8276 if ((chip_scsi_id == i) ||
8277 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8278 continue;
8280 len = asc_prt_line(cp, leftlen, " %X:%c",
8281 i, (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8282 ASC_PRT_NEXT();
8284 len = asc_prt_line(cp, leftlen, "\n");
8285 ASC_PRT_NEXT();
8287 /* Current number of commands waiting for a device. */
8288 len = asc_prt_line(cp, leftlen,
8289 " Command Queue Pending:");
8290 ASC_PRT_NEXT();
8291 for (i = 0; i <= ASC_MAX_TID; i++) {
8292 if ((chip_scsi_id == i) ||
8293 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8294 continue;
8296 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
8297 ASC_PRT_NEXT();
8299 len = asc_prt_line(cp, leftlen, "\n");
8300 ASC_PRT_NEXT();
8302 /* Current limit on number of commands that can be sent to a device. */
8303 len = asc_prt_line(cp, leftlen,
8304 " Command Queue Limit:");
8305 ASC_PRT_NEXT();
8306 for (i = 0; i <= ASC_MAX_TID; i++) {
8307 if ((chip_scsi_id == i) ||
8308 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8309 continue;
8311 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
8312 ASC_PRT_NEXT();
8314 len = asc_prt_line(cp, leftlen, "\n");
8315 ASC_PRT_NEXT();
8317 /* Indicate whether the device has returned queue full status. */
8318 len = asc_prt_line(cp, leftlen,
8319 " Command Queue Full:");
8320 ASC_PRT_NEXT();
8321 for (i = 0; i <= ASC_MAX_TID; i++) {
8322 if ((chip_scsi_id == i) ||
8323 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8324 continue;
8326 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
8327 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
8328 i, boardp->queue_full_cnt[i]);
8329 } else {
8330 len = asc_prt_line(cp, leftlen, " %X:N", i);
8332 ASC_PRT_NEXT();
8334 len = asc_prt_line(cp, leftlen, "\n");
8335 ASC_PRT_NEXT();
8337 len = asc_prt_line(cp, leftlen,
8338 " Synchronous Transfer:");
8339 ASC_PRT_NEXT();
8340 for (i = 0; i <= ASC_MAX_TID; i++) {
8341 if ((chip_scsi_id == i) ||
8342 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8343 continue;
8345 len = asc_prt_line(cp, leftlen, " %X:%c",
8346 i, (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8347 ASC_PRT_NEXT();
8349 len = asc_prt_line(cp, leftlen, "\n");
8350 ASC_PRT_NEXT();
8352 for (i = 0; i <= ASC_MAX_TID; i++) {
8353 uchar syn_period_ix;
8355 if ((chip_scsi_id == i) ||
8356 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
8357 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
8358 continue;
8361 len = asc_prt_line(cp, leftlen, " %X:", i);
8362 ASC_PRT_NEXT();
8364 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0)
8366 len = asc_prt_line(cp, leftlen, " Asynchronous");
8367 ASC_PRT_NEXT();
8368 } else
8370 syn_period_ix =
8371 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1);
8373 len = asc_prt_line(cp, leftlen,
8374 " Transfer Period Factor: %d (%d.%d Mhz),",
8375 v->sdtr_period_tbl[syn_period_ix],
8376 250 / v->sdtr_period_tbl[syn_period_ix],
8377 ASC_TENTHS(250, v->sdtr_period_tbl[syn_period_ix]));
8378 ASC_PRT_NEXT();
8380 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
8381 boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET);
8382 ASC_PRT_NEXT();
8385 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8386 len = asc_prt_line(cp, leftlen, "*\n");
8387 renegotiate = 1;
8388 } else
8390 len = asc_prt_line(cp, leftlen, "\n");
8392 ASC_PRT_NEXT();
8395 if (renegotiate)
8397 len = asc_prt_line(cp, leftlen,
8398 " * = Re-negotiation pending before next command.\n");
8399 ASC_PRT_NEXT();
8402 return totlen;
8406 * asc_prt_adv_board_info()
8408 * Print dynamic board configuration information.
8410 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8411 * cf. asc_prt_line().
8413 * Return the number of characters copied into 'cp'. No more than
8414 * 'cplen' characters will be copied to 'cp'.
8416 STATIC int
8417 asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8419 asc_board_t *boardp;
8420 int leftlen;
8421 int totlen;
8422 int len;
8423 int i;
8424 ADV_DVC_VAR *v;
8425 ADV_DVC_CFG *c;
8426 AdvPortAddr iop_base;
8427 ushort chip_scsi_id;
8428 ushort lramword;
8429 uchar lrambyte;
8430 ushort tagqng_able;
8431 ushort sdtr_able, wdtr_able;
8432 ushort wdtr_done, sdtr_done;
8433 ushort period = 0;
8434 int renegotiate = 0;
8436 boardp = ASC_BOARDP(shp);
8437 v = &boardp->dvc_var.adv_dvc_var;
8438 c = &boardp->dvc_cfg.adv_dvc_cfg;
8439 iop_base = v->iop_base;
8440 chip_scsi_id = v->chip_scsi_id;
8442 leftlen = cplen;
8443 totlen = len = 0;
8445 len = asc_prt_line(cp, leftlen,
8446 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8447 shp->host_no);
8448 ASC_PRT_NEXT();
8450 len = asc_prt_line(cp, leftlen,
8451 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
8452 v->iop_base,
8453 AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1) & CABLE_DETECT,
8454 v->err_code);
8455 ASC_PRT_NEXT();
8457 len = asc_prt_line(cp, leftlen,
8458 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
8459 c->chip_version, c->lib_version, c->mcode_date, c->mcode_version);
8460 ASC_PRT_NEXT();
8462 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8463 len = asc_prt_line(cp, leftlen,
8464 " Queuing Enabled:");
8465 ASC_PRT_NEXT();
8466 for (i = 0; i <= ADV_MAX_TID; i++) {
8467 if ((chip_scsi_id == i) ||
8468 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8469 continue;
8472 len = asc_prt_line(cp, leftlen, " %X:%c",
8473 i, (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8474 ASC_PRT_NEXT();
8476 len = asc_prt_line(cp, leftlen, "\n");
8477 ASC_PRT_NEXT();
8479 len = asc_prt_line(cp, leftlen,
8480 " Queue Limit:");
8481 ASC_PRT_NEXT();
8482 for (i = 0; i <= ADV_MAX_TID; i++) {
8483 if ((chip_scsi_id == i) ||
8484 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8485 continue;
8488 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, lrambyte);
8490 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
8491 ASC_PRT_NEXT();
8493 len = asc_prt_line(cp, leftlen, "\n");
8494 ASC_PRT_NEXT();
8496 len = asc_prt_line(cp, leftlen,
8497 " Command Pending:");
8498 ASC_PRT_NEXT();
8499 for (i = 0; i <= ADV_MAX_TID; i++) {
8500 if ((chip_scsi_id == i) ||
8501 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8502 continue;
8505 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, lrambyte);
8507 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
8508 ASC_PRT_NEXT();
8510 len = asc_prt_line(cp, leftlen, "\n");
8511 ASC_PRT_NEXT();
8513 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8514 len = asc_prt_line(cp, leftlen,
8515 " Wide Enabled:");
8516 ASC_PRT_NEXT();
8517 for (i = 0; i <= ADV_MAX_TID; i++) {
8518 if ((chip_scsi_id == i) ||
8519 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8520 continue;
8523 len = asc_prt_line(cp, leftlen, " %X:%c",
8524 i, (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8525 ASC_PRT_NEXT();
8527 len = asc_prt_line(cp, leftlen, "\n");
8528 ASC_PRT_NEXT();
8530 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
8531 len = asc_prt_line(cp, leftlen,
8532 " Transfer Bit Width:");
8533 ASC_PRT_NEXT();
8534 for (i = 0; i <= ADV_MAX_TID; i++) {
8535 if ((chip_scsi_id == i) ||
8536 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8537 continue;
8540 AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
8541 lramword);
8543 len = asc_prt_line(cp, leftlen, " %X:%d",
8544 i, (lramword & 0x8000) ? 16 : 8);
8545 ASC_PRT_NEXT();
8547 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
8548 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8549 len = asc_prt_line(cp, leftlen, "*");
8550 ASC_PRT_NEXT();
8551 renegotiate = 1;
8554 len = asc_prt_line(cp, leftlen, "\n");
8555 ASC_PRT_NEXT();
8557 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8558 len = asc_prt_line(cp, leftlen,
8559 " Synchronous Enabled:");
8560 ASC_PRT_NEXT();
8561 for (i = 0; i <= ADV_MAX_TID; i++) {
8562 if ((chip_scsi_id == i) ||
8563 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8564 continue;
8567 len = asc_prt_line(cp, leftlen, " %X:%c",
8568 i, (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8569 ASC_PRT_NEXT();
8571 len = asc_prt_line(cp, leftlen, "\n");
8572 ASC_PRT_NEXT();
8574 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
8575 for (i = 0; i <= ADV_MAX_TID; i++) {
8577 AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
8578 lramword);
8579 lramword &= ~0x8000;
8581 if ((chip_scsi_id == i) ||
8582 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
8583 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
8584 continue;
8587 len = asc_prt_line(cp, leftlen, " %X:", i);
8588 ASC_PRT_NEXT();
8590 if ((lramword & 0x1F) == 0) /* Check for REQ/ACK Offset 0. */
8592 len = asc_prt_line(cp, leftlen, " Asynchronous");
8593 ASC_PRT_NEXT();
8594 } else
8596 len = asc_prt_line(cp, leftlen, " Transfer Period Factor: ");
8597 ASC_PRT_NEXT();
8599 if ((lramword & 0x1F00) == 0x1100) /* 80 Mhz */
8601 len = asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
8602 ASC_PRT_NEXT();
8603 } else if ((lramword & 0x1F00) == 0x1000) /* 40 Mhz */
8605 len = asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
8606 ASC_PRT_NEXT();
8607 } else /* 20 Mhz or below. */
8609 period = (((lramword >> 8) * 25) + 50)/4;
8611 if (period == 0) /* Should never happen. */
8613 len = asc_prt_line(cp, leftlen, "%d (? Mhz), ");
8614 ASC_PRT_NEXT();
8615 } else
8617 len = asc_prt_line(cp, leftlen,
8618 "%d (%d.%d Mhz),",
8619 period, 250/period, ASC_TENTHS(250, period));
8620 ASC_PRT_NEXT();
8624 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
8625 lramword & 0x1F);
8626 ASC_PRT_NEXT();
8629 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8630 len = asc_prt_line(cp, leftlen, "*\n");
8631 renegotiate = 1;
8632 } else
8634 len = asc_prt_line(cp, leftlen, "\n");
8636 ASC_PRT_NEXT();
8639 if (renegotiate)
8641 len = asc_prt_line(cp, leftlen,
8642 " * = Re-negotiation pending before next command.\n");
8643 ASC_PRT_NEXT();
8646 return totlen;
8650 * asc_proc_copy()
8652 * Copy proc information to a read buffer taking into account the current
8653 * read offset in the file and the remaining space in the read buffer.
8655 STATIC int
8656 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
8657 char *cp, int cplen)
8659 int cnt = 0;
8661 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
8662 (unsigned) offset, (unsigned) advoffset, cplen);
8663 if (offset <= advoffset) {
8664 /* Read offset below current offset, copy everything. */
8665 cnt = min(cplen, leftlen);
8666 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
8667 (ulong) curbuf, (ulong) cp, cnt);
8668 memcpy(curbuf, cp, cnt);
8669 } else if (offset < advoffset + cplen) {
8670 /* Read offset within current range, partial copy. */
8671 cnt = (advoffset + cplen) - offset;
8672 cp = (cp + cplen) - cnt;
8673 cnt = min(cnt, leftlen);
8674 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
8675 (ulong) curbuf, (ulong) cp, cnt);
8676 memcpy(curbuf, cp, cnt);
8678 return cnt;
8682 * asc_prt_line()
8684 * If 'cp' is NULL print to the console, otherwise print to a buffer.
8686 * Return 0 if printing to the console, otherwise return the number of
8687 * bytes written to the buffer.
8689 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
8690 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
8692 STATIC int
8693 asc_prt_line(char *buf, int buflen, char *fmt, ...)
8695 va_list args;
8696 int ret;
8697 char s[ASC_PRTLINE_SIZE];
8699 va_start(args, fmt);
8700 ret = vsprintf(s, fmt, args);
8701 ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
8702 if (buf == NULL) {
8703 (void) printk(s);
8704 ret = 0;
8705 } else {
8706 ret = min(buflen, ret);
8707 memcpy(buf, s, ret);
8709 va_end(args);
8710 return ret;
8712 #endif /* CONFIG_PROC_FS */
8716 * --- Functions Required by the Asc Library
8720 * Delay for 'n' milliseconds. Don't use the 'jiffies'
8721 * global variable which is incremented once every 5 ms
8722 * from a timer interrupt, because this function may be
8723 * called when interrupts are disabled.
8725 STATIC void
8726 DvcSleepMilliSecond(ADV_DCNT n)
8728 ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong) n);
8729 mdelay(n);
8733 * Currently and inline noop but leave as a placeholder.
8734 * Leave DvcEnterCritical() as a noop placeholder.
8736 STATIC inline ulong
8737 DvcEnterCritical(void)
8739 return 0;
8743 * Critical sections are all protected by the board spinlock.
8744 * Leave DvcLeaveCritical() as a noop placeholder.
8746 STATIC inline void
8747 DvcLeaveCritical(ulong flags)
8749 return;
8753 * void
8754 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
8756 * Calling/Exit State:
8757 * none
8759 * Description:
8760 * Output an ASC_SCSI_Q structure to the chip
8762 STATIC void
8763 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
8765 int i;
8767 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
8768 AscSetChipLramAddr(iop_base, s_addr);
8769 for (i = 0; i < 2 * words; i += 2) {
8770 if (i == 4 || i == 20) {
8771 continue;
8773 outpw(iop_base + IOP_RAM_DATA,
8774 ((ushort) outbuf[i + 1] << 8) | outbuf[i]);
8779 * void
8780 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
8782 * Calling/Exit State:
8783 * none
8785 * Description:
8786 * Input an ASC_QDONE_INFO structure from the chip
8788 STATIC void
8789 DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
8791 int i;
8792 ushort word;
8794 AscSetChipLramAddr(iop_base, s_addr);
8795 for (i = 0; i < 2 * words; i += 2) {
8796 if (i == 10) {
8797 continue;
8799 word = inpw(iop_base + IOP_RAM_DATA);
8800 inbuf[i] = word & 0xff;
8801 inbuf[i + 1] = (word >> 8) & 0xff;
8803 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
8807 * Read a PCI configuration byte.
8809 STATIC uchar __init
8810 DvcReadPCIConfigByte(
8811 ASC_DVC_VAR *asc_dvc,
8812 ushort offset)
8814 #ifdef CONFIG_PCI
8815 uchar byte_data;
8816 pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
8817 return byte_data;
8818 #else /* !defined(CONFIG_PCI) */
8819 return 0;
8820 #endif /* !defined(CONFIG_PCI) */
8824 * Write a PCI configuration byte.
8826 STATIC void __init
8827 DvcWritePCIConfigByte(
8828 ASC_DVC_VAR *asc_dvc,
8829 ushort offset,
8830 uchar byte_data)
8832 #ifdef CONFIG_PCI
8833 pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
8834 #endif /* CONFIG_PCI */
8838 * Return the BIOS address of the adapter at the specified
8839 * I/O port and with the specified bus type.
8841 STATIC ushort __init
8842 AscGetChipBiosAddress(
8843 PortAddr iop_base,
8844 ushort bus_type)
8846 ushort cfg_lsw;
8847 ushort bios_addr;
8850 * The PCI BIOS is re-located by the motherboard BIOS. Because
8851 * of this the driver can not determine where a PCI BIOS is
8852 * loaded and executes.
8854 if (bus_type & ASC_IS_PCI)
8856 return(0);
8859 #ifdef CONFIG_ISA
8860 if((bus_type & ASC_IS_EISA) != 0)
8862 cfg_lsw = AscGetEisaChipCfg(iop_base);
8863 cfg_lsw &= 0x000F;
8864 bios_addr = (ushort)(ASC_BIOS_MIN_ADDR +
8865 (cfg_lsw * ASC_BIOS_BANK_SIZE));
8866 return(bios_addr);
8867 }/* if */
8868 #endif /* CONFIG_ISA */
8870 cfg_lsw = AscGetChipCfgLsw(iop_base);
8873 * ISA PnP uses the top bit as the 32K BIOS flag
8875 if (bus_type == ASC_IS_ISAPNP)
8877 cfg_lsw &= 0x7FFF;
8878 }/* if */
8880 bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
8881 ASC_BIOS_MIN_ADDR);
8882 return(bios_addr);
8887 * --- Functions Required by the Adv Library
8891 * DvcGetPhyAddr()
8893 * Return the physical address of 'vaddr' and set '*lenp' to the
8894 * number of physically contiguous bytes that follow 'vaddr'.
8895 * 'flag' indicates the type of structure whose physical address
8896 * is being translated.
8898 * Note: Because Linux currently doesn't page the kernel and all
8899 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
8901 ADV_PADDR
8902 DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
8903 uchar *vaddr, ADV_SDCNT *lenp, int flag)
8905 ADV_PADDR paddr;
8907 paddr = virt_to_bus(vaddr);
8909 ASC_DBG4(4,
8910 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
8911 (ulong) vaddr, (ulong) lenp, (ulong) *((ulong *) lenp), (ulong) paddr);
8913 return paddr;
8917 * Read a PCI configuration byte.
8919 STATIC uchar __init
8920 DvcAdvReadPCIConfigByte(
8921 ADV_DVC_VAR *asc_dvc,
8922 ushort offset)
8924 #ifdef CONFIG_PCI
8925 uchar byte_data;
8926 pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
8927 return byte_data;
8928 #else /* CONFIG_PCI */
8929 return 0;
8930 #endif /* CONFIG_PCI */
8934 * Write a PCI configuration byte.
8936 STATIC void __init
8937 DvcAdvWritePCIConfigByte(
8938 ADV_DVC_VAR *asc_dvc,
8939 ushort offset,
8940 uchar byte_data)
8942 #ifdef CONFIG_PCI
8943 pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
8944 #else /* CONFIG_PCI */
8945 return;
8946 #endif /* CONFIG_PCI */
8950 * --- Tracing and Debugging Functions
8953 #ifdef ADVANSYS_STATS
8954 #ifdef CONFIG_PROC_FS
8956 * asc_prt_board_stats()
8958 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8959 * cf. asc_prt_line().
8961 * Return the number of characters copied into 'cp'. No more than
8962 * 'cplen' characters will be copied to 'cp'.
8964 STATIC int
8965 asc_prt_board_stats(struct Scsi_Host *shp, char *cp, int cplen)
8967 int leftlen;
8968 int totlen;
8969 int len;
8970 struct asc_stats *s;
8971 asc_board_t *boardp;
8973 leftlen = cplen;
8974 totlen = len = 0;
8976 boardp = ASC_BOARDP(shp);
8977 s = &boardp->asc_stats;
8979 len = asc_prt_line(cp, leftlen,
8980 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", shp->host_no);
8981 ASC_PRT_NEXT();
8983 len = asc_prt_line(cp, leftlen,
8984 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
8985 s->queuecommand, s->reset, s->biosparam, s->interrupt);
8986 ASC_PRT_NEXT();
8988 len = asc_prt_line(cp, leftlen,
8989 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
8990 s->callback, s->done, s->build_error, s->adv_build_noreq,
8991 s->adv_build_nosg);
8992 ASC_PRT_NEXT();
8994 len = asc_prt_line(cp, leftlen,
8995 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
8996 s->exe_noerror, s->exe_busy, s->exe_error, s->exe_unknown);
8997 ASC_PRT_NEXT();
9000 * Display data transfer statistics.
9002 if (s->cont_cnt > 0) {
9003 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
9004 ASC_PRT_NEXT();
9006 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
9007 s->cont_xfer/2,
9008 ASC_TENTHS(s->cont_xfer, 2));
9009 ASC_PRT_NEXT();
9011 /* Contiguous transfer average size */
9012 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
9013 (s->cont_xfer/2)/s->cont_cnt,
9014 ASC_TENTHS((s->cont_xfer/2), s->cont_cnt));
9015 ASC_PRT_NEXT();
9018 if (s->sg_cnt > 0) {
9020 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
9021 s->sg_cnt, s->sg_elem);
9022 ASC_PRT_NEXT();
9024 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
9025 s->sg_xfer/2,
9026 ASC_TENTHS(s->sg_xfer, 2));
9027 ASC_PRT_NEXT();
9029 /* Scatter gather transfer statistics */
9030 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
9031 s->sg_elem/s->sg_cnt,
9032 ASC_TENTHS(s->sg_elem, s->sg_cnt));
9033 ASC_PRT_NEXT();
9035 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
9036 (s->sg_xfer/2)/s->sg_elem,
9037 ASC_TENTHS((s->sg_xfer/2), s->sg_elem));
9038 ASC_PRT_NEXT();
9040 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
9041 (s->sg_xfer/2)/s->sg_cnt,
9042 ASC_TENTHS((s->sg_xfer/2), s->sg_cnt));
9043 ASC_PRT_NEXT();
9047 * Display request queuing statistics.
9049 len = asc_prt_line(cp, leftlen,
9050 " Active and Waiting Request Queues (Time Unit: %d HZ):\n", HZ);
9051 ASC_PRT_NEXT();
9054 return totlen;
9058 * asc_prt_target_stats()
9060 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
9061 * cf. asc_prt_line().
9063 * This is separated from asc_prt_board_stats because a full set
9064 * of targets will overflow ASC_PRTBUF_SIZE.
9066 * Return the number of characters copied into 'cp'. No more than
9067 * 'cplen' characters will be copied to 'cp'.
9069 STATIC int
9070 asc_prt_target_stats(struct Scsi_Host *shp, int tgt_id, char *cp, int cplen)
9072 int leftlen;
9073 int totlen;
9074 int len;
9075 struct asc_stats *s;
9076 ushort chip_scsi_id;
9077 asc_board_t *boardp;
9078 asc_queue_t *active;
9079 asc_queue_t *waiting;
9081 leftlen = cplen;
9082 totlen = len = 0;
9084 boardp = ASC_BOARDP(shp);
9085 s = &boardp->asc_stats;
9087 active = &ASC_BOARDP(shp)->active;
9088 waiting = &ASC_BOARDP(shp)->waiting;
9090 if (ASC_NARROW_BOARD(boardp)) {
9091 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
9092 } else {
9093 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
9096 if ((chip_scsi_id == tgt_id) ||
9097 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
9098 return 0;
9101 do {
9102 if (active->q_tot_cnt[tgt_id] > 0 || waiting->q_tot_cnt[tgt_id] > 0) {
9103 len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
9104 ASC_PRT_NEXT();
9106 len = asc_prt_line(cp, leftlen,
9107 " active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
9108 active->q_cur_cnt[tgt_id], active->q_max_cnt[tgt_id],
9109 active->q_tot_cnt[tgt_id],
9110 active->q_min_tim[tgt_id], active->q_max_tim[tgt_id],
9111 (active->q_tot_cnt[tgt_id] == 0) ? 0 :
9112 (active->q_tot_tim[tgt_id]/active->q_tot_cnt[tgt_id]),
9113 (active->q_tot_cnt[tgt_id] == 0) ? 0 :
9114 ASC_TENTHS(active->q_tot_tim[tgt_id],
9115 active->q_tot_cnt[tgt_id]));
9116 ASC_PRT_NEXT();
9118 len = asc_prt_line(cp, leftlen,
9119 " waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
9120 waiting->q_cur_cnt[tgt_id], waiting->q_max_cnt[tgt_id],
9121 waiting->q_tot_cnt[tgt_id],
9122 waiting->q_min_tim[tgt_id], waiting->q_max_tim[tgt_id],
9123 (waiting->q_tot_cnt[tgt_id] == 0) ? 0 :
9124 (waiting->q_tot_tim[tgt_id]/waiting->q_tot_cnt[tgt_id]),
9125 (waiting->q_tot_cnt[tgt_id] == 0) ? 0 :
9126 ASC_TENTHS(waiting->q_tot_tim[tgt_id],
9127 waiting->q_tot_cnt[tgt_id]));
9128 ASC_PRT_NEXT();
9130 } while (0);
9132 return totlen;
9134 #endif /* CONFIG_PROC_FS */
9135 #endif /* ADVANSYS_STATS */
9137 #ifdef ADVANSYS_DEBUG
9139 * asc_prt_scsi_host()
9141 STATIC void
9142 asc_prt_scsi_host(struct Scsi_Host *s)
9144 asc_board_t *boardp;
9146 boardp = ASC_BOARDP(s);
9148 printk("Scsi_Host at addr 0x%lx\n", (ulong) s);
9149 printk(
9150 " host_busy %u, host_no %d, last_reset %d,\n",
9151 s->host_busy, s->host_no,
9152 (unsigned) s->last_reset);
9154 printk(
9155 " base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
9156 (ulong) s->base, (ulong) s->io_port, s->n_io_port, s->irq);
9158 printk(
9159 " dma_channel %d, this_id %d, can_queue %d,\n",
9160 s->dma_channel, s->this_id, s->can_queue);
9162 printk(
9163 " cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
9164 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
9166 if (ASC_NARROW_BOARD(boardp)) {
9167 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
9168 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
9169 } else {
9170 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
9171 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
9176 * asc_prt_scsi_cmnd()
9178 STATIC void
9179 asc_prt_scsi_cmnd(struct scsi_cmnd *s)
9181 printk("struct scsi_cmnd at addr 0x%lx\n", (ulong) s);
9183 printk(
9184 " host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
9185 (ulong) s->device->host, (ulong) s->device, s->device->id, s->device->lun,
9186 s->device->channel);
9188 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
9190 printk (
9191 "sc_data_direction %u, resid %d\n",
9192 s->sc_data_direction, s->resid);
9194 printk(
9195 " use_sg %u, sglist_len %u\n",
9196 s->use_sg, s->sglist_len);
9198 printk(
9199 " serial_number 0x%x, retries %d, allowed %d\n",
9200 (unsigned) s->serial_number, s->retries, s->allowed);
9202 printk(
9203 " timeout_per_command %d\n",
9204 s->timeout_per_command);
9206 printk(
9207 " scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
9208 (ulong) s->scsi_done, (ulong) s->done,
9209 (ulong) s->host_scribble, s->result);
9211 printk(
9212 " tag %u, pid %u\n",
9213 (unsigned) s->tag, (unsigned) s->pid);
9217 * asc_prt_asc_dvc_var()
9219 STATIC void
9220 asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
9222 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong) h);
9224 printk(
9225 " iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n",
9226 h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
9228 printk(
9229 " bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n",
9230 h->bus_type, (ulong) h->isr_callback, (ulong) h->exe_callback,
9231 (unsigned) h->init_sdtr);
9233 printk(
9234 " sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n",
9235 (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng,
9236 (unsigned) h->unit_not_ready, (unsigned) h->chip_no);
9238 printk(
9239 " queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n",
9240 (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor,
9241 (unsigned) h->scsi_reset_wait);
9243 printk(
9244 " is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n",
9245 (unsigned) h->is_in_int, (unsigned) h->max_total_qng,
9246 (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt);
9248 printk(
9249 " last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n",
9250 (unsigned) h->last_q_shortage, (unsigned) h->init_state,
9251 (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer);
9253 printk(
9254 " cfg 0x%lx, irq_no 0x%x\n",
9255 (ulong) h->cfg, (unsigned) h->irq_no);
9259 * asc_prt_asc_dvc_cfg()
9261 STATIC void
9262 asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
9264 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong) h);
9266 printk(
9267 " can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
9268 h->can_tagged_qng, h->cmd_qng_enabled);
9269 printk(
9270 " disc_enable 0x%x, sdtr_enable 0x%x,\n",
9271 h->disc_enable, h->sdtr_enable);
9273 printk(
9274 " chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
9275 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
9276 h->chip_version);
9278 printk(
9279 " pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
9280 to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
9281 h->mcode_date);
9283 printk(
9284 " mcode_version %d, overrun_buf 0x%lx\n",
9285 h->mcode_version, (ulong) h->overrun_buf);
9289 * asc_prt_asc_scsi_q()
9291 STATIC void
9292 asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
9294 ASC_SG_HEAD *sgp;
9295 int i;
9297 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong) q);
9299 printk(
9300 " target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
9301 q->q2.target_ix, q->q1.target_lun,
9302 (ulong) q->q2.srb_ptr, q->q2.tag_code);
9304 printk(
9305 " data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
9306 (ulong) le32_to_cpu(q->q1.data_addr),
9307 (ulong) le32_to_cpu(q->q1.data_cnt),
9308 (ulong) le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
9310 printk(
9311 " cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
9312 (ulong) q->cdbptr, q->q2.cdb_len,
9313 (ulong) q->sg_head, q->q1.sg_queue_cnt);
9315 if (q->sg_head) {
9316 sgp = q->sg_head;
9317 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong) sgp);
9318 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt);
9319 for (i = 0; i < sgp->entry_cnt; i++) {
9320 printk(" [%u]: addr 0x%lx, bytes %lu\n",
9321 i, (ulong) le32_to_cpu(sgp->sg_list[i].addr),
9322 (ulong) le32_to_cpu(sgp->sg_list[i].bytes));
9329 * asc_prt_asc_qdone_info()
9331 STATIC void
9332 asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
9334 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong) q);
9335 printk(
9336 " srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
9337 (ulong) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
9338 q->d2.tag_code);
9339 printk(
9340 " done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
9341 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
9345 * asc_prt_adv_dvc_var()
9347 * Display an ADV_DVC_VAR structure.
9349 STATIC void
9350 asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
9352 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong) h);
9354 printk(
9355 " iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
9356 (ulong) h->iop_base, h->err_code, (unsigned) h->ultra_able);
9358 printk(
9359 " isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
9360 (ulong) h->isr_callback, (unsigned) h->sdtr_able,
9361 (unsigned) h->wdtr_able);
9363 printk(
9364 " start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
9365 (unsigned) h->start_motor,
9366 (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
9368 printk(
9369 " max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
9370 (unsigned) h->max_host_qng, (unsigned) h->max_dvc_qng,
9371 (ulong) h->carr_freelist);
9373 printk(
9374 " icq_sp 0x%lx, irq_sp 0x%lx\n",
9375 (ulong) h->icq_sp, (ulong) h->irq_sp);
9377 printk(
9378 " no_scam 0x%x, tagqng_able 0x%x\n",
9379 (unsigned) h->no_scam, (unsigned) h->tagqng_able);
9381 printk(
9382 " chip_scsi_id 0x%x, cfg 0x%lx\n",
9383 (unsigned) h->chip_scsi_id, (ulong) h->cfg);
9387 * asc_prt_adv_dvc_cfg()
9389 * Display an ADV_DVC_CFG structure.
9391 STATIC void
9392 asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
9394 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong) h);
9396 printk(
9397 " disc_enable 0x%x, termination 0x%x\n",
9398 h->disc_enable, h->termination);
9400 printk(
9401 " chip_version 0x%x, mcode_date 0x%x\n",
9402 h->chip_version, h->mcode_date);
9404 printk(
9405 " mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
9406 h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
9408 printk(
9409 " control_flag 0x%x, pci_slot_info 0x%x\n",
9410 h->control_flag, h->pci_slot_info);
9414 * asc_prt_adv_scsi_req_q()
9416 * Display an ADV_SCSI_REQ_Q structure.
9418 STATIC void
9419 asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
9421 int sg_blk_cnt;
9422 struct asc_sg_block *sg_ptr;
9424 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong) q);
9426 printk(
9427 " target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
9428 q->target_id, q->target_lun, (ulong) q->srb_ptr, q->a_flag);
9430 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
9431 q->cntl, (ulong) le32_to_cpu(q->data_addr), (ulong) q->vdata_addr);
9433 printk(
9434 " data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
9435 (ulong) le32_to_cpu(q->data_cnt),
9436 (ulong) le32_to_cpu(q->sense_addr), q->sense_len);
9438 printk(
9439 " cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
9440 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
9442 printk(
9443 " sg_working_ix 0x%x, target_cmd %u\n",
9444 q->sg_working_ix, q->target_cmd);
9446 printk(
9447 " scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
9448 (ulong) le32_to_cpu(q->scsiq_rptr),
9449 (ulong) le32_to_cpu(q->sg_real_addr), (ulong) q->sg_list_ptr);
9451 /* Display the request's ADV_SG_BLOCK structures. */
9452 if (q->sg_list_ptr != NULL)
9454 sg_blk_cnt = 0;
9455 while (1) {
9457 * 'sg_ptr' is a physical address. Convert it to a virtual
9458 * address by indexing 'sg_blk_cnt' into the virtual address
9459 * array 'sg_list_ptr'.
9461 * XXX - Assumes all SG physical blocks are virtually contiguous.
9463 sg_ptr = &(((ADV_SG_BLOCK *) (q->sg_list_ptr))[sg_blk_cnt]);
9464 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
9465 if (sg_ptr->sg_ptr == 0)
9467 break;
9469 sg_blk_cnt++;
9475 * asc_prt_adv_sgblock()
9477 * Display an ADV_SG_BLOCK structure.
9479 STATIC void
9480 asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
9482 int i;
9484 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
9485 (ulong) b, sgblockno);
9486 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
9487 b->sg_cnt, (ulong) le32_to_cpu(b->sg_ptr));
9488 ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
9489 if (b->sg_ptr != 0)
9491 ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
9493 for (i = 0; i < b->sg_cnt; i++) {
9494 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
9495 i, (ulong) b->sg_list[i].sg_addr, (ulong) b->sg_list[i].sg_count);
9500 * asc_prt_hex()
9502 * Print hexadecimal output in 4 byte groupings 32 bytes
9503 * or 8 double-words per line.
9505 STATIC void
9506 asc_prt_hex(char *f, uchar *s, int l)
9508 int i;
9509 int j;
9510 int k;
9511 int m;
9513 printk("%s: (%d bytes)\n", f, l);
9515 for (i = 0; i < l; i += 32) {
9517 /* Display a maximum of 8 double-words per line. */
9518 if ((k = (l - i) / 4) >= 8) {
9519 k = 8;
9520 m = 0;
9521 } else {
9522 m = (l - i) % 4;
9525 for (j = 0; j < k; j++) {
9526 printk(" %2.2X%2.2X%2.2X%2.2X",
9527 (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1],
9528 (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]);
9531 switch (m) {
9532 case 0:
9533 default:
9534 break;
9535 case 1:
9536 printk(" %2.2X",
9537 (unsigned) s[i+(j*4)]);
9538 break;
9539 case 2:
9540 printk(" %2.2X%2.2X",
9541 (unsigned) s[i+(j*4)],
9542 (unsigned) s[i+(j*4)+1]);
9543 break;
9544 case 3:
9545 printk(" %2.2X%2.2X%2.2X",
9546 (unsigned) s[i+(j*4)+1],
9547 (unsigned) s[i+(j*4)+2],
9548 (unsigned) s[i+(j*4)+3]);
9549 break;
9552 printk("\n");
9555 #endif /* ADVANSYS_DEBUG */
9558 * --- Asc Library Functions
9561 STATIC ushort __init
9562 AscGetEisaChipCfg(
9563 PortAddr iop_base)
9565 PortAddr eisa_cfg_iop;
9567 eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
9568 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
9569 return (inpw(eisa_cfg_iop));
9572 STATIC uchar __init
9573 AscSetChipScsiID(
9574 PortAddr iop_base,
9575 uchar new_host_id
9578 ushort cfg_lsw;
9580 if (AscGetChipScsiID(iop_base) == new_host_id) {
9581 return (new_host_id);
9583 cfg_lsw = AscGetChipCfgLsw(iop_base);
9584 cfg_lsw &= 0xF8FF;
9585 cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID) << 8);
9586 AscSetChipCfgLsw(iop_base, cfg_lsw);
9587 return (AscGetChipScsiID(iop_base));
9590 STATIC uchar __init
9591 AscGetChipScsiCtrl(
9592 PortAddr iop_base)
9594 uchar sc;
9596 AscSetBank(iop_base, 1);
9597 sc = inp(iop_base + IOP_REG_SC);
9598 AscSetBank(iop_base, 0);
9599 return (sc);
9602 STATIC uchar __init
9603 AscGetChipVersion(
9604 PortAddr iop_base,
9605 ushort bus_type
9608 if ((bus_type & ASC_IS_EISA) != 0) {
9609 PortAddr eisa_iop;
9610 uchar revision;
9611 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
9612 (PortAddr) ASC_EISA_REV_IOP_MASK;
9613 revision = inp(eisa_iop);
9614 return ((uchar) ((ASC_CHIP_MIN_VER_EISA - 1) + revision));
9616 return (AscGetChipVerNo(iop_base));
9619 STATIC ushort __init
9620 AscGetChipBusType(
9621 PortAddr iop_base)
9623 ushort chip_ver;
9625 chip_ver = AscGetChipVerNo(iop_base);
9626 if (
9627 (chip_ver >= ASC_CHIP_MIN_VER_VL)
9628 && (chip_ver <= ASC_CHIP_MAX_VER_VL)
9630 if (
9631 ((iop_base & 0x0C30) == 0x0C30)
9632 || ((iop_base & 0x0C50) == 0x0C50)
9634 return (ASC_IS_EISA);
9636 return (ASC_IS_VL);
9638 if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
9639 (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
9640 if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
9641 return (ASC_IS_ISAPNP);
9643 return (ASC_IS_ISA);
9644 } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
9645 (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
9646 return (ASC_IS_PCI);
9648 return (0);
9651 STATIC ASC_DCNT
9652 AscLoadMicroCode(
9653 PortAddr iop_base,
9654 ushort s_addr,
9655 uchar *mcode_buf,
9656 ushort mcode_size
9659 ASC_DCNT chksum;
9660 ushort mcode_word_size;
9661 ushort mcode_chksum;
9663 /* Write the microcode buffer starting at LRAM address 0. */
9664 mcode_word_size = (ushort) (mcode_size >> 1);
9665 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
9666 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
9668 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
9669 ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong) chksum);
9670 mcode_chksum = (ushort) AscMemSumLramWord(iop_base,
9671 (ushort) ASC_CODE_SEC_BEG,
9672 (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2));
9673 ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
9674 (ulong) mcode_chksum);
9675 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
9676 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
9677 return (chksum);
9680 STATIC int
9681 AscFindSignature(
9682 PortAddr iop_base
9685 ushort sig_word;
9687 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
9688 iop_base, AscGetChipSignatureByte(iop_base));
9689 if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) {
9690 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
9691 iop_base, AscGetChipSignatureWord(iop_base));
9692 sig_word = AscGetChipSignatureWord(iop_base);
9693 if ((sig_word == (ushort) ASC_1000_ID0W) ||
9694 (sig_word == (ushort) ASC_1000_ID0W_FIX)) {
9695 return (1);
9698 return (0);
9701 STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __initdata =
9703 0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
9704 ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
9707 #ifdef CONFIG_ISA
9708 STATIC uchar _isa_pnp_inited __initdata = 0;
9710 STATIC PortAddr __init
9711 AscSearchIOPortAddr(
9712 PortAddr iop_beg,
9713 ushort bus_type)
9715 if (bus_type & ASC_IS_VL) {
9716 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
9717 if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL) {
9718 return (iop_beg);
9721 return (0);
9723 if (bus_type & ASC_IS_ISA) {
9724 if (_isa_pnp_inited == 0) {
9725 AscSetISAPNPWaitForKey();
9726 _isa_pnp_inited++;
9728 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
9729 if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT) != 0) {
9730 return (iop_beg);
9733 return (0);
9735 if (bus_type & ASC_IS_EISA) {
9736 if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
9737 return (iop_beg);
9739 return (0);
9741 return (0);
9744 STATIC PortAddr __init
9745 AscSearchIOPortAddr11(
9746 PortAddr s_addr
9749 int i;
9750 PortAddr iop_base;
9752 for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
9753 if (_asc_def_iop_base[i] > s_addr) {
9754 break;
9757 for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
9758 iop_base = _asc_def_iop_base[i];
9759 if (check_region(iop_base, ASC_IOADR_GAP) != 0) {
9760 ASC_DBG1(1,
9761 "AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n",
9762 iop_base);
9763 continue;
9765 ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n", iop_base);
9766 if (AscFindSignature(iop_base)) {
9767 return (iop_base);
9770 return (0);
9773 STATIC void __init
9774 AscSetISAPNPWaitForKey(void)
9776 outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
9777 outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
9778 return;
9780 #endif /* CONFIG_ISA */
9782 STATIC void __init
9783 AscToggleIRQAct(
9784 PortAddr iop_base
9787 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
9788 AscSetChipStatus(iop_base, 0);
9789 return;
9792 STATIC uchar __init
9793 AscGetChipIRQ(
9794 PortAddr iop_base,
9795 ushort bus_type)
9797 ushort cfg_lsw;
9798 uchar chip_irq;
9800 if ((bus_type & ASC_IS_EISA) != 0) {
9801 cfg_lsw = AscGetEisaChipCfg(iop_base);
9802 chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10);
9803 if ((chip_irq == 13) || (chip_irq > 15)) {
9804 return (0);
9806 return (chip_irq);
9808 if ((bus_type & ASC_IS_VL) != 0) {
9809 cfg_lsw = AscGetChipCfgLsw(iop_base);
9810 chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07));
9811 if ((chip_irq == 0) ||
9812 (chip_irq == 4) ||
9813 (chip_irq == 7)) {
9814 return (0);
9816 return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1)));
9818 cfg_lsw = AscGetChipCfgLsw(iop_base);
9819 chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03));
9820 if (chip_irq == 3)
9821 chip_irq += (uchar) 2;
9822 return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
9825 STATIC uchar __init
9826 AscSetChipIRQ(
9827 PortAddr iop_base,
9828 uchar irq_no,
9829 ushort bus_type)
9831 ushort cfg_lsw;
9833 if ((bus_type & ASC_IS_VL) != 0) {
9834 if (irq_no != 0) {
9835 if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) {
9836 irq_no = 0;
9837 } else {
9838 irq_no -= (uchar) ((ASC_MIN_IRQ_NO - 1));
9841 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE3);
9842 cfg_lsw |= (ushort) 0x0010;
9843 AscSetChipCfgLsw(iop_base, cfg_lsw);
9844 AscToggleIRQAct(iop_base);
9845 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE0);
9846 cfg_lsw |= (ushort) ((irq_no & 0x07) << 2);
9847 AscSetChipCfgLsw(iop_base, cfg_lsw);
9848 AscToggleIRQAct(iop_base);
9849 return (AscGetChipIRQ(iop_base, bus_type));
9851 if ((bus_type & (ASC_IS_ISA)) != 0) {
9852 if (irq_no == 15)
9853 irq_no -= (uchar) 2;
9854 irq_no -= (uchar) ASC_MIN_IRQ_NO;
9855 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFF3);
9856 cfg_lsw |= (ushort) ((irq_no & 0x03) << 2);
9857 AscSetChipCfgLsw(iop_base, cfg_lsw);
9858 return (AscGetChipIRQ(iop_base, bus_type));
9860 return (0);
9863 #ifdef CONFIG_ISA
9864 STATIC void __init
9865 AscEnableIsaDma(
9866 uchar dma_channel)
9868 if (dma_channel < 4) {
9869 outp(0x000B, (ushort) (0xC0 | dma_channel));
9870 outp(0x000A, dma_channel);
9871 } else if (dma_channel < 8) {
9872 outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4)));
9873 outp(0x00D4, (ushort) (dma_channel - 4));
9875 return;
9877 #endif /* CONFIG_ISA */
9879 STATIC int
9880 AscIsrChipHalted(
9881 ASC_DVC_VAR *asc_dvc
9884 EXT_MSG ext_msg;
9885 EXT_MSG out_msg;
9886 ushort halt_q_addr;
9887 int sdtr_accept;
9888 ushort int_halt_code;
9889 ASC_SCSI_BIT_ID_TYPE scsi_busy;
9890 ASC_SCSI_BIT_ID_TYPE target_id;
9891 PortAddr iop_base;
9892 uchar tag_code;
9893 uchar q_status;
9894 uchar halt_qp;
9895 uchar sdtr_data;
9896 uchar target_ix;
9897 uchar q_cntl, tid_no;
9898 uchar cur_dvc_qng;
9899 uchar asyn_sdtr;
9900 uchar scsi_status;
9901 asc_board_t *boardp;
9903 ASC_ASSERT(asc_dvc->drv_ptr != NULL);
9904 boardp = asc_dvc->drv_ptr;
9906 iop_base = asc_dvc->iop_base;
9907 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
9909 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
9910 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
9911 target_ix = AscReadLramByte(iop_base,
9912 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX));
9913 q_cntl = AscReadLramByte(iop_base,
9914 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL));
9915 tid_no = ASC_TIX_TO_TID(target_ix);
9916 target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no);
9917 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
9918 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
9919 } else {
9920 asyn_sdtr = 0;
9922 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
9923 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
9924 AscSetChipSDTR(iop_base, 0, tid_no);
9925 boardp->sdtr_data[tid_no] = 0;
9927 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9928 return (0);
9929 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
9930 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
9931 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
9932 boardp->sdtr_data[tid_no] = asyn_sdtr;
9934 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9935 return (0);
9936 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
9938 AscMemWordCopyPtrFromLram(iop_base,
9939 ASCV_MSGIN_BEG,
9940 (uchar *) &ext_msg,
9941 sizeof(EXT_MSG) >> 1);
9943 if (ext_msg.msg_type == MS_EXTEND &&
9944 ext_msg.msg_req == MS_SDTR_CODE &&
9945 ext_msg.msg_len == MS_SDTR_LEN) {
9946 sdtr_accept = TRUE;
9947 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
9949 sdtr_accept = FALSE;
9950 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
9952 if ((ext_msg.xfer_period <
9953 asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index]) ||
9954 (ext_msg.xfer_period >
9955 asc_dvc->sdtr_period_tbl[asc_dvc->max_sdtr_index])) {
9956 sdtr_accept = FALSE;
9957 ext_msg.xfer_period =
9958 asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index];
9960 if (sdtr_accept) {
9961 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
9962 ext_msg.req_ack_offset);
9963 if ((sdtr_data == 0xFF)) {
9965 q_cntl |= QC_MSG_OUT;
9966 asc_dvc->init_sdtr &= ~target_id;
9967 asc_dvc->sdtr_done &= ~target_id;
9968 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
9969 boardp->sdtr_data[tid_no] = asyn_sdtr;
9972 if (ext_msg.req_ack_offset == 0) {
9974 q_cntl &= ~QC_MSG_OUT;
9975 asc_dvc->init_sdtr &= ~target_id;
9976 asc_dvc->sdtr_done &= ~target_id;
9977 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
9978 } else {
9979 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
9981 q_cntl &= ~QC_MSG_OUT;
9982 asc_dvc->sdtr_done |= target_id;
9983 asc_dvc->init_sdtr |= target_id;
9984 asc_dvc->pci_fix_asyn_xfer &= ~target_id;
9985 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
9986 ext_msg.req_ack_offset);
9987 AscSetChipSDTR(iop_base, sdtr_data, tid_no);
9988 boardp->sdtr_data[tid_no] = sdtr_data;
9989 } else {
9991 q_cntl |= QC_MSG_OUT;
9992 AscMsgOutSDTR(asc_dvc,
9993 ext_msg.xfer_period,
9994 ext_msg.req_ack_offset);
9995 asc_dvc->pci_fix_asyn_xfer &= ~target_id;
9996 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
9997 ext_msg.req_ack_offset);
9998 AscSetChipSDTR(iop_base, sdtr_data, tid_no);
9999 boardp->sdtr_data[tid_no] = sdtr_data;
10000 asc_dvc->sdtr_done |= target_id;
10001 asc_dvc->init_sdtr |= target_id;
10005 AscWriteLramByte(iop_base,
10006 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10007 q_cntl);
10008 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10009 return (0);
10010 } else if (ext_msg.msg_type == MS_EXTEND &&
10011 ext_msg.msg_req == MS_WDTR_CODE &&
10012 ext_msg.msg_len == MS_WDTR_LEN) {
10014 ext_msg.wdtr_width = 0;
10015 AscMemWordCopyPtrToLram(iop_base,
10016 ASCV_MSGOUT_BEG,
10017 (uchar *) &ext_msg,
10018 sizeof(EXT_MSG) >> 1);
10019 q_cntl |= QC_MSG_OUT;
10020 AscWriteLramByte(iop_base,
10021 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10022 q_cntl);
10023 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10024 return (0);
10025 } else {
10027 ext_msg.msg_type = MESSAGE_REJECT;
10028 AscMemWordCopyPtrToLram(iop_base,
10029 ASCV_MSGOUT_BEG,
10030 (uchar *) &ext_msg,
10031 sizeof(EXT_MSG) >> 1);
10032 q_cntl |= QC_MSG_OUT;
10033 AscWriteLramByte(iop_base,
10034 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10035 q_cntl);
10036 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10037 return (0);
10039 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
10041 q_cntl |= QC_REQ_SENSE;
10043 if ((asc_dvc->init_sdtr & target_id) != 0) {
10045 asc_dvc->sdtr_done &= ~target_id;
10047 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10048 q_cntl |= QC_MSG_OUT;
10049 AscMsgOutSDTR(asc_dvc,
10050 asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
10051 (uchar) (asc_dvc->max_sdtr_index - 1)],
10052 (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
10055 AscWriteLramByte(iop_base,
10056 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10057 q_cntl);
10059 tag_code = AscReadLramByte(iop_base,
10060 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
10061 tag_code &= 0xDC;
10062 if (
10063 (asc_dvc->pci_fix_asyn_xfer & target_id)
10064 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
10067 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
10068 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
10071 AscWriteLramByte(iop_base,
10072 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE),
10073 tag_code);
10075 q_status = AscReadLramByte(iop_base,
10076 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS));
10077 q_status |= (QS_READY | QS_BUSY);
10078 AscWriteLramByte(iop_base,
10079 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10080 q_status);
10082 scsi_busy = AscReadLramByte(iop_base,
10083 (ushort) ASCV_SCSIBUSY_B);
10084 scsi_busy &= ~target_id;
10085 AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10087 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10088 return (0);
10089 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
10091 AscMemWordCopyPtrFromLram(iop_base,
10092 ASCV_MSGOUT_BEG,
10093 (uchar *) &out_msg,
10094 sizeof(EXT_MSG) >> 1);
10096 if ((out_msg.msg_type == MS_EXTEND) &&
10097 (out_msg.msg_len == MS_SDTR_LEN) &&
10098 (out_msg.msg_req == MS_SDTR_CODE)) {
10100 asc_dvc->init_sdtr &= ~target_id;
10101 asc_dvc->sdtr_done &= ~target_id;
10102 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10103 boardp->sdtr_data[tid_no] = asyn_sdtr;
10105 q_cntl &= ~QC_MSG_OUT;
10106 AscWriteLramByte(iop_base,
10107 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10108 q_cntl);
10109 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10110 return (0);
10111 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
10113 scsi_status = AscReadLramByte(iop_base,
10114 (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS));
10115 cur_dvc_qng = AscReadLramByte(iop_base,
10116 (ushort) ((ushort) ASC_QADR_BEG + (ushort) target_ix));
10117 if ((cur_dvc_qng > 0) &&
10118 (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
10120 scsi_busy = AscReadLramByte(iop_base,
10121 (ushort) ASCV_SCSIBUSY_B);
10122 scsi_busy |= target_id;
10123 AscWriteLramByte(iop_base,
10124 (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10125 asc_dvc->queue_full_or_busy |= target_id;
10127 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
10128 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
10129 cur_dvc_qng -= 1;
10130 asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
10132 AscWriteLramByte(iop_base,
10133 (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG +
10134 (ushort) tid_no),
10135 cur_dvc_qng);
10138 * Set the device queue depth to the number of
10139 * active requests when the QUEUE FULL condition
10140 * was encountered.
10142 boardp->queue_full |= target_id;
10143 boardp->queue_full_cnt[tid_no] = cur_dvc_qng;
10147 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10148 return (0);
10150 #if CC_VERY_LONG_SG_LIST
10151 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC)
10153 uchar q_no;
10154 ushort q_addr;
10155 uchar sg_wk_q_no;
10156 uchar first_sg_wk_q_no;
10157 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
10158 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
10159 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
10160 ushort sg_list_dwords;
10161 ushort sg_entry_cnt;
10162 uchar next_qp;
10163 int i;
10165 q_no = AscReadLramByte(iop_base, (ushort) ASCV_REQ_SG_LIST_QP);
10166 if (q_no == ASC_QLINK_END)
10168 return(0);
10171 q_addr = ASC_QNO_TO_QADDR(q_no);
10174 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
10175 * structure pointer using a macro provided by the driver.
10176 * The ASC_SCSI_REQ pointer provides a pointer to the
10177 * host ASC_SG_HEAD structure.
10179 /* Read request's SRB pointer. */
10180 scsiq = (ASC_SCSI_Q *)
10181 ASC_SRB2SCSIQ(
10182 ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
10183 (ushort) (q_addr + ASC_SCSIQ_D_SRBPTR))));
10186 * Get request's first and working SG queue.
10188 sg_wk_q_no = AscReadLramByte(iop_base,
10189 (ushort) (q_addr + ASC_SCSIQ_B_SG_WK_QP));
10191 first_sg_wk_q_no = AscReadLramByte(iop_base,
10192 (ushort) (q_addr + ASC_SCSIQ_B_FIRST_SG_WK_QP));
10195 * Reset request's working SG queue back to the
10196 * first SG queue.
10198 AscWriteLramByte(iop_base,
10199 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SG_WK_QP),
10200 first_sg_wk_q_no);
10202 sg_head = scsiq->sg_head;
10205 * Set sg_entry_cnt to the number of SG elements
10206 * that will be completed on this interrupt.
10208 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
10209 * SG elements. The data_cnt and data_addr fields which
10210 * add 1 to the SG element capacity are not used when
10211 * restarting SG handling after a halt.
10213 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1))
10215 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
10218 * Keep track of remaining number of SG elements that will
10219 * need to be handled on the next interrupt.
10221 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
10222 } else
10224 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
10225 scsiq->remain_sg_entry_cnt = 0;
10229 * Copy SG elements into the list of allocated SG queues.
10231 * Last index completed is saved in scsiq->next_sg_index.
10233 next_qp = first_sg_wk_q_no;
10234 q_addr = ASC_QNO_TO_QADDR(next_qp);
10235 scsi_sg_q.sg_head_qp = q_no;
10236 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
10237 for( i = 0; i < sg_head->queue_cnt; i++)
10239 scsi_sg_q.seq_no = i + 1;
10240 if (sg_entry_cnt > ASC_SG_LIST_PER_Q)
10242 sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
10243 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
10245 * After very first SG queue RISC FW uses next
10246 * SG queue first element then checks sg_list_cnt
10247 * against zero and then decrements, so set
10248 * sg_list_cnt 1 less than number of SG elements
10249 * in each SG queue.
10251 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
10252 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
10253 } else {
10255 * This is the last SG queue in the list of
10256 * allocated SG queues. If there are more
10257 * SG elements than will fit in the allocated
10258 * queues, then set the QCSG_SG_XFER_MORE flag.
10260 if (scsiq->remain_sg_entry_cnt != 0)
10262 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
10263 } else
10265 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
10267 /* equals sg_entry_cnt * 2 */
10268 sg_list_dwords = sg_entry_cnt << 1;
10269 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
10270 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
10271 sg_entry_cnt = 0;
10274 scsi_sg_q.q_no = next_qp;
10275 AscMemWordCopyPtrToLram(iop_base,
10276 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
10277 (uchar *) &scsi_sg_q,
10278 sizeof(ASC_SG_LIST_Q) >> 1);
10280 AscMemDWordCopyPtrToLram(iop_base,
10281 q_addr + ASC_SGQ_LIST_BEG,
10282 (uchar *) &sg_head->sg_list[scsiq->next_sg_index],
10283 sg_list_dwords);
10285 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
10288 * If the just completed SG queue contained the
10289 * last SG element, then no more SG queues need
10290 * to be written.
10292 if (scsi_sg_q.cntl & QCSG_SG_XFER_END)
10294 break;
10297 next_qp = AscReadLramByte( iop_base,
10298 ( ushort )( q_addr+ASC_SCSIQ_B_FWD ) );
10299 q_addr = ASC_QNO_TO_QADDR( next_qp );
10303 * Clear the halt condition so the RISC will be restarted
10304 * after the return.
10306 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10307 return(0);
10309 #endif /* CC_VERY_LONG_SG_LIST */
10310 return (0);
10313 STATIC uchar
10314 _AscCopyLramScsiDoneQ(
10315 PortAddr iop_base,
10316 ushort q_addr,
10317 ASC_QDONE_INFO * scsiq,
10318 ASC_DCNT max_dma_count
10321 ushort _val;
10322 uchar sg_queue_cnt;
10324 DvcGetQinfo(iop_base,
10325 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
10326 (uchar *) scsiq,
10327 (sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2);
10329 _val = AscReadLramWord(iop_base,
10330 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS));
10331 scsiq->q_status = (uchar) _val;
10332 scsiq->q_no = (uchar) (_val >> 8);
10333 _val = AscReadLramWord(iop_base,
10334 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL));
10335 scsiq->cntl = (uchar) _val;
10336 sg_queue_cnt = (uchar) (_val >> 8);
10337 _val = AscReadLramWord(iop_base,
10338 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN));
10339 scsiq->sense_len = (uchar) _val;
10340 scsiq->extra_bytes = (uchar) (_val >> 8);
10343 * Read high word of remain bytes from alternate location.
10345 scsiq->remain_bytes = (((ADV_DCNT) AscReadLramWord( iop_base,
10346 (ushort) (q_addr+ (ushort) ASC_SCSIQ_W_ALT_DC1))) << 16);
10348 * Read low word of remain bytes from original location.
10350 scsiq->remain_bytes += AscReadLramWord(iop_base,
10351 (ushort) (q_addr+ (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT));
10353 scsiq->remain_bytes &= max_dma_count;
10354 return (sg_queue_cnt);
10357 STATIC int
10358 AscIsrQDone(
10359 ASC_DVC_VAR *asc_dvc
10362 uchar next_qp;
10363 uchar n_q_used;
10364 uchar sg_list_qp;
10365 uchar sg_queue_cnt;
10366 uchar q_cnt;
10367 uchar done_q_tail;
10368 uchar tid_no;
10369 ASC_SCSI_BIT_ID_TYPE scsi_busy;
10370 ASC_SCSI_BIT_ID_TYPE target_id;
10371 PortAddr iop_base;
10372 ushort q_addr;
10373 ushort sg_q_addr;
10374 uchar cur_target_qng;
10375 ASC_QDONE_INFO scsiq_buf;
10376 ASC_QDONE_INFO *scsiq;
10377 int false_overrun;
10378 ASC_ISR_CALLBACK asc_isr_callback;
10380 iop_base = asc_dvc->iop_base;
10381 asc_isr_callback = asc_dvc->isr_callback;
10382 n_q_used = 1;
10383 scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
10384 done_q_tail = (uchar) AscGetVarDoneQTail(iop_base);
10385 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
10386 next_qp = AscReadLramByte(iop_base,
10387 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD));
10388 if (next_qp != ASC_QLINK_END) {
10389 AscPutVarDoneQTail(iop_base, next_qp);
10390 q_addr = ASC_QNO_TO_QADDR(next_qp);
10391 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
10392 asc_dvc->max_dma_count);
10393 AscWriteLramByte(iop_base,
10394 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10395 (uchar) (scsiq->q_status & (uchar) ~ (QS_READY | QS_ABORTED)));
10396 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
10397 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
10398 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
10399 sg_q_addr = q_addr;
10400 sg_list_qp = next_qp;
10401 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
10402 sg_list_qp = AscReadLramByte(iop_base,
10403 (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_FWD));
10404 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
10405 if (sg_list_qp == ASC_QLINK_END) {
10406 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_Q_LINKS);
10407 scsiq->d3.done_stat = QD_WITH_ERROR;
10408 scsiq->d3.host_stat = QHSTA_D_QDONE_SG_LIST_CORRUPTED;
10409 goto FATAL_ERR_QDONE;
10411 AscWriteLramByte(iop_base,
10412 (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10413 QS_FREE);
10415 n_q_used = sg_queue_cnt + 1;
10416 AscPutVarDoneQTail(iop_base, sg_list_qp);
10418 if (asc_dvc->queue_full_or_busy & target_id) {
10419 cur_target_qng = AscReadLramByte(iop_base,
10420 (ushort) ((ushort) ASC_QADR_BEG + (ushort) scsiq->d2.target_ix));
10421 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
10422 scsi_busy = AscReadLramByte(iop_base,
10423 (ushort) ASCV_SCSIBUSY_B);
10424 scsi_busy &= ~target_id;
10425 AscWriteLramByte(iop_base,
10426 (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10427 asc_dvc->queue_full_or_busy &= ~target_id;
10430 if (asc_dvc->cur_total_qng >= n_q_used) {
10431 asc_dvc->cur_total_qng -= n_q_used;
10432 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
10433 asc_dvc->cur_dvc_qng[tid_no]--;
10435 } else {
10436 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
10437 scsiq->d3.done_stat = QD_WITH_ERROR;
10438 goto FATAL_ERR_QDONE;
10440 if ((scsiq->d2.srb_ptr == 0UL) ||
10441 ((scsiq->q_status & QS_ABORTED) != 0)) {
10442 return (0x11);
10443 } else if (scsiq->q_status == QS_DONE) {
10444 false_overrun = FALSE;
10445 if (scsiq->extra_bytes != 0) {
10446 scsiq->remain_bytes += (ADV_DCNT) scsiq->extra_bytes;
10448 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
10449 if (scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN) {
10450 if ((scsiq->cntl & (QC_DATA_IN | QC_DATA_OUT)) == 0) {
10451 scsiq->d3.done_stat = QD_NO_ERROR;
10452 scsiq->d3.host_stat = QHSTA_NO_ERROR;
10453 } else if (false_overrun) {
10454 scsiq->d3.done_stat = QD_NO_ERROR;
10455 scsiq->d3.host_stat = QHSTA_NO_ERROR;
10457 } else if (scsiq->d3.host_stat ==
10458 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
10459 AscStopChip(iop_base);
10460 AscSetChipControl(iop_base,
10461 (uchar) (CC_SCSI_RESET | CC_HALT));
10462 DvcDelayNanoSecond(asc_dvc, 60000);
10463 AscSetChipControl(iop_base, CC_HALT);
10464 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10465 AscSetChipStatus(iop_base, 0);
10466 AscSetChipControl(iop_base, 0);
10469 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
10470 (*asc_isr_callback) (asc_dvc, scsiq);
10471 } else {
10472 if ((AscReadLramByte(iop_base,
10473 (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) ==
10474 START_STOP)) {
10475 asc_dvc->unit_not_ready &= ~target_id;
10476 if (scsiq->d3.done_stat != QD_NO_ERROR) {
10477 asc_dvc->start_motor &= ~target_id;
10481 return (1);
10482 } else {
10483 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
10484 FATAL_ERR_QDONE:
10485 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
10486 (*asc_isr_callback) (asc_dvc, scsiq);
10488 return (0x80);
10491 return (0);
10494 STATIC int
10495 AscISR(
10496 ASC_DVC_VAR *asc_dvc
10499 ASC_CS_TYPE chipstat;
10500 PortAddr iop_base;
10501 ushort saved_ram_addr;
10502 uchar ctrl_reg;
10503 uchar saved_ctrl_reg;
10504 int int_pending;
10505 int status;
10506 uchar host_flag;
10508 iop_base = asc_dvc->iop_base;
10509 int_pending = FALSE;
10511 if (AscIsIntPending(iop_base) == 0)
10513 return int_pending;
10516 if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
10517 || (asc_dvc->isr_callback == 0)
10519 return (ERR);
10521 if (asc_dvc->in_critical_cnt != 0) {
10522 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
10523 return (ERR);
10525 if (asc_dvc->is_in_int) {
10526 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
10527 return (ERR);
10529 asc_dvc->is_in_int = TRUE;
10530 ctrl_reg = AscGetChipControl(iop_base);
10531 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
10532 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
10533 chipstat = AscGetChipStatus(iop_base);
10534 if (chipstat & CSW_SCSI_RESET_LATCH) {
10535 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
10536 int i = 10;
10537 int_pending = TRUE;
10538 asc_dvc->sdtr_done = 0;
10539 saved_ctrl_reg &= (uchar) (~CC_HALT);
10540 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) &&
10541 (i-- > 0))
10543 DvcSleepMilliSecond(100);
10545 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
10546 AscSetChipControl(iop_base, CC_HALT);
10547 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10548 AscSetChipStatus(iop_base, 0);
10549 chipstat = AscGetChipStatus(iop_base);
10552 saved_ram_addr = AscGetChipLramAddr(iop_base);
10553 host_flag = AscReadLramByte(iop_base,
10554 ASCV_HOST_FLAG_B) & (uchar) (~ASC_HOST_FLAG_IN_ISR);
10555 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10556 (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR));
10557 if ((chipstat & CSW_INT_PENDING)
10558 || (int_pending)
10560 AscAckInterrupt(iop_base);
10561 int_pending = TRUE;
10562 if ((chipstat & CSW_HALTED) &&
10563 (ctrl_reg & CC_SINGLE_STEP)) {
10564 if (AscIsrChipHalted(asc_dvc) == ERR) {
10565 goto ISR_REPORT_QDONE_FATAL_ERROR;
10566 } else {
10567 saved_ctrl_reg &= (uchar) (~CC_HALT);
10569 } else {
10570 ISR_REPORT_QDONE_FATAL_ERROR:
10571 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
10572 while (((status = AscIsrQDone(asc_dvc)) & 0x01) != 0) {
10574 } else {
10575 do {
10576 if ((status = AscIsrQDone(asc_dvc)) == 1) {
10577 break;
10579 } while (status == 0x11);
10581 if ((status & 0x80) != 0)
10582 int_pending = ERR;
10585 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10586 AscSetChipLramAddr(iop_base, saved_ram_addr);
10587 AscSetChipControl(iop_base, saved_ctrl_reg);
10588 asc_dvc->is_in_int = FALSE;
10589 return (int_pending);
10592 /* Microcode buffer is kept after initialization for error recovery. */
10593 STATIC uchar _asc_mcode_buf[] =
10595 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10596 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10597 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10598 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10599 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
10600 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10601 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
10602 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00,
10603 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
10604 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2, 0xC2, 0x00, 0x92, 0x80,
10605 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80,
10606 0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
10607 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8, 0xCD, 0x04, 0x4D, 0x00,
10608 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1,
10609 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88,
10610 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00, 0x84, 0x97, 0x07, 0xA6,
10611 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00,
10612 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6,
10613 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6, 0x34, 0x01, 0x00, 0x33,
10614 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04,
10615 0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23,
10616 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01, 0x00, 0x33, 0x0A, 0x00,
10617 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04,
10618 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01,
10619 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3, 0x3C, 0x01, 0x00, 0x05,
10620 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01,
10621 0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0,
10622 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00, 0xC2, 0x88, 0x06, 0x23,
10623 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0,
10624 0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61,
10625 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC, 0x4F, 0x00, 0x84, 0x97,
10626 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80,
10627 0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
10628 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88, 0x04, 0x98, 0xF0, 0x80,
10629 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6,
10630 0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95,
10631 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02, 0x07, 0xA6, 0x5A, 0x02,
10632 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96,
10633 0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC,
10634 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01, 0x6F, 0x00, 0xA5, 0x01,
10635 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02,
10636 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02,
10637 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E, 0x80, 0x63, 0x00, 0x43,
10638 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01,
10639 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82,
10640 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8, 0x00, 0x33, 0x1F, 0x00,
10641 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6,
10642 0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6,
10643 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xEE, 0x82,
10644 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8,
10645 0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98,
10646 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6, 0x3C, 0x04, 0x06, 0xA6,
10647 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83,
10648 0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33,
10649 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05, 0xFF, 0xA2, 0x7A, 0x03,
10650 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03,
10651 0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03,
10652 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6, 0xA4, 0x03, 0x00, 0xA6,
10653 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03,
10654 0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42,
10655 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95, 0xC0, 0x83, 0x00, 0x33,
10656 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23,
10657 0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
10658 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04, 0x06, 0xA6, 0x0A, 0x04,
10659 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84,
10660 0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
10661 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6, 0x38, 0x04, 0x00, 0x33,
10662 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC,
10663 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
10664 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0xA3, 0x01,
10665 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00,
10666 0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
10667 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04, 0x08, 0x23, 0x22, 0xA3,
10668 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23,
10669 0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98,
10670 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20, 0x81, 0x62, 0xE8, 0x81,
10671 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81,
10672 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23,
10673 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3, 0xF4, 0x04, 0x00, 0x33,
10674 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01,
10675 0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
10676 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85, 0x46, 0x97, 0xCD, 0x04,
10677 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85,
10678 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
10679 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x49, 0x00, 0x81, 0x01,
10680 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01,
10681 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
10682 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63, 0x07, 0xA4, 0xF8, 0x05,
10683 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0,
10684 0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
10685 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00, 0x62, 0x97, 0x04, 0x85,
10686 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0,
10687 0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
10688 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05, 0x80, 0x67, 0x80, 0x63,
10689 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23,
10690 0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
10691 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23, 0x07, 0x41, 0x83, 0x03,
10692 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6,
10693 0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
10694 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00, 0x52, 0x00, 0x06, 0x61,
10695 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01,
10696 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
10697 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23, 0xDF, 0x00, 0x06, 0xA6,
10698 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20,
10699 0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
10700 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B, 0x40, 0x0E, 0x80, 0x63,
10701 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43,
10702 0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
10703 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x07, 0xA6, 0xD6, 0x06,
10704 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6,
10705 0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
10706 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20, 0x81, 0x62, 0x04, 0x01,
10707 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33,
10708 0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
10709 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88, 0x00, 0x00, 0x80, 0x67,
10710 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61,
10711 0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
10712 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04, 0x80, 0x05, 0x81, 0x05,
10713 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01,
10714 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
10715 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01, 0xF1, 0x00, 0x70, 0x00,
10716 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00,
10717 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
10718 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1, 0xC4, 0x07, 0x00, 0x33,
10719 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01,
10720 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
10721 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x05, 0x05, 0x00, 0x63,
10722 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02,
10723 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
10724 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63, 0xF3, 0x04,
10725 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08,
10726 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
10727 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04, 0x5A, 0x88, 0x02, 0x01,
10728 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08,
10729 0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
10730 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x38, 0x2B,
10731 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09,
10732 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
10733 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32, 0x40, 0x36, 0x40, 0x3A,
10734 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3,
10735 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
10736 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01, 0xA1, 0x23, 0xA1, 0x01,
10737 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2,
10738 0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
10741 STATIC ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
10742 STATIC ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
10744 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
10745 STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] =
10747 INQUIRY,
10748 REQUEST_SENSE,
10749 READ_CAPACITY,
10750 READ_TOC,
10751 MODE_SELECT,
10752 MODE_SENSE,
10753 MODE_SELECT_10,
10754 MODE_SENSE_10,
10755 0xFF,
10756 0xFF,
10757 0xFF,
10758 0xFF,
10759 0xFF,
10760 0xFF,
10761 0xFF,
10762 0xFF
10765 STATIC int
10766 AscExeScsiQueue(
10767 ASC_DVC_VAR *asc_dvc,
10768 ASC_SCSI_Q *scsiq
10771 PortAddr iop_base;
10772 ulong last_int_level;
10773 int sta;
10774 int n_q_required;
10775 int disable_syn_offset_one_fix;
10776 int i;
10777 ASC_PADDR addr;
10778 ASC_EXE_CALLBACK asc_exe_callback;
10779 ushort sg_entry_cnt = 0;
10780 ushort sg_entry_cnt_minus_one = 0;
10781 uchar target_ix;
10782 uchar tid_no;
10783 uchar sdtr_data;
10784 uchar extra_bytes;
10785 uchar scsi_cmd;
10786 uchar disable_cmd;
10787 ASC_SG_HEAD *sg_head;
10788 ASC_DCNT data_cnt;
10790 iop_base = asc_dvc->iop_base;
10791 sg_head = scsiq->sg_head;
10792 asc_exe_callback = asc_dvc->exe_callback;
10793 if (asc_dvc->err_code != 0)
10794 return (ERR);
10795 if (scsiq == (ASC_SCSI_Q *) 0L) {
10796 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
10797 return (ERR);
10799 scsiq->q1.q_no = 0;
10800 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
10801 scsiq->q1.extra_bytes = 0;
10803 sta = 0;
10804 target_ix = scsiq->q2.target_ix;
10805 tid_no = ASC_TIX_TO_TID(target_ix);
10806 n_q_required = 1;
10807 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
10808 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
10809 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
10810 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10811 AscMsgOutSDTR(asc_dvc,
10812 asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
10813 (uchar) (asc_dvc->max_sdtr_index - 1)],
10814 (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
10815 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
10818 last_int_level = DvcEnterCritical();
10819 if (asc_dvc->in_critical_cnt != 0) {
10820 DvcLeaveCritical(last_int_level);
10821 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
10822 return (ERR);
10824 asc_dvc->in_critical_cnt++;
10825 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10826 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
10827 asc_dvc->in_critical_cnt--;
10828 DvcLeaveCritical(last_int_level);
10829 return (ERR);
10831 #if !CC_VERY_LONG_SG_LIST
10832 if (sg_entry_cnt > ASC_MAX_SG_LIST)
10834 asc_dvc->in_critical_cnt--;
10835 DvcLeaveCritical(last_int_level);
10836 return(ERR);
10838 #endif /* !CC_VERY_LONG_SG_LIST */
10839 if (sg_entry_cnt == 1) {
10840 scsiq->q1.data_addr = (ADV_PADDR) sg_head->sg_list[0].addr;
10841 scsiq->q1.data_cnt = (ADV_DCNT) sg_head->sg_list[0].bytes;
10842 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
10844 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
10846 scsi_cmd = scsiq->cdbptr[0];
10847 disable_syn_offset_one_fix = FALSE;
10848 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
10849 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
10850 if (scsiq->q1.cntl & QC_SG_HEAD) {
10851 data_cnt = 0;
10852 for (i = 0; i < sg_entry_cnt; i++) {
10853 data_cnt += (ADV_DCNT) le32_to_cpu(sg_head->sg_list[i].bytes);
10855 } else {
10856 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
10858 if (data_cnt != 0UL) {
10859 if (data_cnt < 512UL) {
10860 disable_syn_offset_one_fix = TRUE;
10861 } else {
10862 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST; i++) {
10863 disable_cmd = _syn_offset_one_disable_cmd[i];
10864 if (disable_cmd == 0xFF) {
10865 break;
10867 if (scsi_cmd == disable_cmd) {
10868 disable_syn_offset_one_fix = TRUE;
10869 break;
10875 if (disable_syn_offset_one_fix) {
10876 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
10877 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
10878 ASC_TAG_FLAG_DISABLE_DISCONNECT);
10879 } else {
10880 scsiq->q2.tag_code &= 0x27;
10882 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10883 if (asc_dvc->bug_fix_cntl) {
10884 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10885 if ((scsi_cmd == READ_6) ||
10886 (scsi_cmd == READ_10)) {
10887 addr =
10888 (ADV_PADDR) le32_to_cpu(
10889 sg_head->sg_list[sg_entry_cnt_minus_one].addr) +
10890 (ADV_DCNT) le32_to_cpu(
10891 sg_head->sg_list[sg_entry_cnt_minus_one].bytes);
10892 extra_bytes = (uchar) ((ushort) addr & 0x0003);
10893 if ((extra_bytes != 0) &&
10894 ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
10895 == 0)) {
10896 scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
10897 scsiq->q1.extra_bytes = extra_bytes;
10898 data_cnt = le32_to_cpu(
10899 sg_head->sg_list[sg_entry_cnt_minus_one].bytes);
10900 data_cnt -= (ASC_DCNT) extra_bytes;
10901 sg_head->sg_list[sg_entry_cnt_minus_one].bytes =
10902 cpu_to_le32(data_cnt);
10907 sg_head->entry_to_copy = sg_head->entry_cnt;
10908 #if CC_VERY_LONG_SG_LIST
10910 * Set the sg_entry_cnt to the maximum possible. The rest of
10911 * the SG elements will be copied when the RISC completes the
10912 * SG elements that fit and halts.
10914 if (sg_entry_cnt > ASC_MAX_SG_LIST)
10916 sg_entry_cnt = ASC_MAX_SG_LIST;
10918 #endif /* CC_VERY_LONG_SG_LIST */
10919 n_q_required = AscSgListToQueue(sg_entry_cnt);
10920 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
10921 (uint) n_q_required) || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
10922 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
10923 n_q_required)) == 1) {
10924 asc_dvc->in_critical_cnt--;
10925 if (asc_exe_callback != 0) {
10926 (*asc_exe_callback) (asc_dvc, scsiq);
10928 DvcLeaveCritical(last_int_level);
10929 return (sta);
10932 } else {
10933 if (asc_dvc->bug_fix_cntl) {
10934 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10935 if ((scsi_cmd == READ_6) ||
10936 (scsi_cmd == READ_10)) {
10937 addr = le32_to_cpu(scsiq->q1.data_addr) +
10938 le32_to_cpu(scsiq->q1.data_cnt);
10939 extra_bytes = (uchar) ((ushort) addr & 0x0003);
10940 if ((extra_bytes != 0) &&
10941 ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
10942 == 0)) {
10943 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
10944 if (((ushort) data_cnt & 0x01FF) == 0) {
10945 scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
10946 data_cnt -= (ASC_DCNT) extra_bytes;
10947 scsiq->q1.data_cnt = cpu_to_le32(data_cnt);
10948 scsiq->q1.extra_bytes = extra_bytes;
10954 n_q_required = 1;
10955 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
10956 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
10957 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
10958 n_q_required)) == 1) {
10959 asc_dvc->in_critical_cnt--;
10960 if (asc_exe_callback != 0) {
10961 (*asc_exe_callback) (asc_dvc, scsiq);
10963 DvcLeaveCritical(last_int_level);
10964 return (sta);
10968 asc_dvc->in_critical_cnt--;
10969 DvcLeaveCritical(last_int_level);
10970 return (sta);
10973 STATIC int
10974 AscSendScsiQueue(
10975 ASC_DVC_VAR *asc_dvc,
10976 ASC_SCSI_Q *scsiq,
10977 uchar n_q_required
10980 PortAddr iop_base;
10981 uchar free_q_head;
10982 uchar next_qp;
10983 uchar tid_no;
10984 uchar target_ix;
10985 int sta;
10987 iop_base = asc_dvc->iop_base;
10988 target_ix = scsiq->q2.target_ix;
10989 tid_no = ASC_TIX_TO_TID(target_ix);
10990 sta = 0;
10991 free_q_head = (uchar) AscGetVarFreeQHead(iop_base);
10992 if (n_q_required > 1) {
10993 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
10994 free_q_head, (uchar) (n_q_required)))
10995 != (uchar) ASC_QLINK_END) {
10996 asc_dvc->last_q_shortage = 0;
10997 scsiq->sg_head->queue_cnt = n_q_required - 1;
10998 scsiq->q1.q_no = free_q_head;
10999 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
11000 free_q_head)) == 1) {
11001 AscPutVarFreeQHead(iop_base, next_qp);
11002 asc_dvc->cur_total_qng += (uchar) (n_q_required);
11003 asc_dvc->cur_dvc_qng[tid_no]++;
11005 return (sta);
11007 } else if (n_q_required == 1) {
11008 if ((next_qp = AscAllocFreeQueue(iop_base,
11009 free_q_head)) != ASC_QLINK_END) {
11010 scsiq->q1.q_no = free_q_head;
11011 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
11012 free_q_head)) == 1) {
11013 AscPutVarFreeQHead(iop_base, next_qp);
11014 asc_dvc->cur_total_qng++;
11015 asc_dvc->cur_dvc_qng[tid_no]++;
11017 return (sta);
11020 return (sta);
11023 STATIC int
11024 AscSgListToQueue(
11025 int sg_list
11028 int n_sg_list_qs;
11030 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
11031 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
11032 n_sg_list_qs++;
11033 return (n_sg_list_qs + 1);
11037 STATIC uint
11038 AscGetNumOfFreeQueue(
11039 ASC_DVC_VAR *asc_dvc,
11040 uchar target_ix,
11041 uchar n_qs
11044 uint cur_used_qs;
11045 uint cur_free_qs;
11046 ASC_SCSI_BIT_ID_TYPE target_id;
11047 uchar tid_no;
11049 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
11050 tid_no = ASC_TIX_TO_TID(target_ix);
11051 if ((asc_dvc->unit_not_ready & target_id) ||
11052 (asc_dvc->queue_full_or_busy & target_id)) {
11053 return (0);
11055 if (n_qs == 1) {
11056 cur_used_qs = (uint) asc_dvc->cur_total_qng +
11057 (uint) asc_dvc->last_q_shortage +
11058 (uint) ASC_MIN_FREE_Q;
11059 } else {
11060 cur_used_qs = (uint) asc_dvc->cur_total_qng +
11061 (uint) ASC_MIN_FREE_Q;
11063 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
11064 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
11065 if (asc_dvc->cur_dvc_qng[tid_no] >=
11066 asc_dvc->max_dvc_qng[tid_no]) {
11067 return (0);
11069 return (cur_free_qs);
11071 if (n_qs > 1) {
11072 if ((n_qs > asc_dvc->last_q_shortage) && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
11073 asc_dvc->last_q_shortage = n_qs;
11076 return (0);
11079 STATIC int
11080 AscPutReadyQueue(
11081 ASC_DVC_VAR *asc_dvc,
11082 ASC_SCSI_Q *scsiq,
11083 uchar q_no
11086 ushort q_addr;
11087 uchar tid_no;
11088 uchar sdtr_data;
11089 uchar syn_period_ix;
11090 uchar syn_offset;
11091 PortAddr iop_base;
11093 iop_base = asc_dvc->iop_base;
11094 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
11095 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
11096 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
11097 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
11098 syn_period_ix = (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
11099 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
11100 AscMsgOutSDTR(asc_dvc,
11101 asc_dvc->sdtr_period_tbl[syn_period_ix],
11102 syn_offset);
11103 scsiq->q1.cntl |= QC_MSG_OUT;
11105 q_addr = ASC_QNO_TO_QADDR(q_no);
11106 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
11107 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG ;
11109 scsiq->q1.status = QS_FREE;
11110 AscMemWordCopyPtrToLram(iop_base,
11111 q_addr + ASC_SCSIQ_CDB_BEG,
11112 (uchar *) scsiq->cdbptr,
11113 scsiq->q2.cdb_len >> 1);
11115 DvcPutScsiQ(iop_base,
11116 q_addr + ASC_SCSIQ_CPY_BEG,
11117 (uchar *) &scsiq->q1.cntl,
11118 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
11119 AscWriteLramWord(iop_base,
11120 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
11121 (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY));
11122 return (1);
11125 STATIC int
11126 AscPutReadySgListQueue(
11127 ASC_DVC_VAR *asc_dvc,
11128 ASC_SCSI_Q *scsiq,
11129 uchar q_no
11132 int sta;
11133 int i;
11134 ASC_SG_HEAD *sg_head;
11135 ASC_SG_LIST_Q scsi_sg_q;
11136 ASC_DCNT saved_data_addr;
11137 ASC_DCNT saved_data_cnt;
11138 PortAddr iop_base;
11139 ushort sg_list_dwords;
11140 ushort sg_index;
11141 ushort sg_entry_cnt;
11142 ushort q_addr;
11143 uchar next_qp;
11145 iop_base = asc_dvc->iop_base;
11146 sg_head = scsiq->sg_head;
11147 saved_data_addr = scsiq->q1.data_addr;
11148 saved_data_cnt = scsiq->q1.data_cnt;
11149 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
11150 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
11151 #if CC_VERY_LONG_SG_LIST
11153 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
11154 * then not all SG elements will fit in the allocated queues.
11155 * The rest of the SG elements will be copied when the RISC
11156 * completes the SG elements that fit and halts.
11158 if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
11161 * Set sg_entry_cnt to be the number of SG elements that
11162 * will fit in the allocated SG queues. It is minus 1, because
11163 * the first SG element is handled above. ASC_MAX_SG_LIST is
11164 * already inflated by 1 to account for this. For example it
11165 * may be 50 which is 1 + 7 queues * 7 SG elements.
11167 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
11170 * Keep track of remaining number of SG elements that will
11171 * need to be handled from a_isr.c.
11173 scsiq->remain_sg_entry_cnt = sg_head->entry_cnt - ASC_MAX_SG_LIST;
11174 } else
11176 #endif /* CC_VERY_LONG_SG_LIST */
11178 * Set sg_entry_cnt to be the number of SG elements that
11179 * will fit in the allocated SG queues. It is minus 1, because
11180 * the first SG element is handled above.
11182 sg_entry_cnt = sg_head->entry_cnt - 1;
11183 #if CC_VERY_LONG_SG_LIST
11185 #endif /* CC_VERY_LONG_SG_LIST */
11186 if (sg_entry_cnt != 0) {
11187 scsiq->q1.cntl |= QC_SG_HEAD;
11188 q_addr = ASC_QNO_TO_QADDR(q_no);
11189 sg_index = 1;
11190 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
11191 scsi_sg_q.sg_head_qp = q_no;
11192 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
11193 for (i = 0; i < sg_head->queue_cnt; i++) {
11194 scsi_sg_q.seq_no = i + 1;
11195 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
11196 sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
11197 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
11198 if (i == 0) {
11199 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q;
11200 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q;
11201 } else {
11202 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
11203 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
11205 } else {
11206 #if CC_VERY_LONG_SG_LIST
11208 * This is the last SG queue in the list of
11209 * allocated SG queues. If there are more
11210 * SG elements than will fit in the allocated
11211 * queues, then set the QCSG_SG_XFER_MORE flag.
11213 if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
11215 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
11216 } else
11218 #endif /* CC_VERY_LONG_SG_LIST */
11219 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
11220 #if CC_VERY_LONG_SG_LIST
11222 #endif /* CC_VERY_LONG_SG_LIST */
11223 sg_list_dwords = sg_entry_cnt << 1;
11224 if (i == 0) {
11225 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
11226 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt;
11227 } else {
11228 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
11229 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
11231 sg_entry_cnt = 0;
11233 next_qp = AscReadLramByte(iop_base,
11234 (ushort) (q_addr + ASC_SCSIQ_B_FWD));
11235 scsi_sg_q.q_no = next_qp;
11236 q_addr = ASC_QNO_TO_QADDR(next_qp);
11237 AscMemWordCopyPtrToLram(iop_base,
11238 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
11239 (uchar *) &scsi_sg_q,
11240 sizeof(ASC_SG_LIST_Q) >> 1);
11241 AscMemDWordCopyPtrToLram(iop_base,
11242 q_addr + ASC_SGQ_LIST_BEG,
11243 (uchar *) &sg_head->sg_list[sg_index],
11244 sg_list_dwords);
11245 sg_index += ASC_SG_LIST_PER_Q;
11246 scsiq->next_sg_index = sg_index;
11248 } else {
11249 scsiq->q1.cntl &= ~QC_SG_HEAD;
11251 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
11252 scsiq->q1.data_addr = saved_data_addr;
11253 scsiq->q1.data_cnt = saved_data_cnt;
11254 return (sta);
11257 STATIC int
11258 AscSetRunChipSynRegAtID(
11259 PortAddr iop_base,
11260 uchar tid_no,
11261 uchar sdtr_data
11264 int sta = FALSE;
11266 if (AscHostReqRiscHalt(iop_base)) {
11267 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
11268 AscStartChip(iop_base);
11269 return (sta);
11271 return (sta);
11274 STATIC int
11275 AscSetChipSynRegAtID(
11276 PortAddr iop_base,
11277 uchar id,
11278 uchar sdtr_data
11281 ASC_SCSI_BIT_ID_TYPE org_id;
11282 int i;
11283 int sta = TRUE;
11285 AscSetBank(iop_base, 1);
11286 org_id = AscReadChipDvcID(iop_base);
11287 for (i = 0; i <= ASC_MAX_TID; i++) {
11288 if (org_id == (0x01 << i))
11289 break;
11291 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
11292 AscWriteChipDvcID(iop_base, id);
11293 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
11294 AscSetBank(iop_base, 0);
11295 AscSetChipSyn(iop_base, sdtr_data);
11296 if (AscGetChipSyn(iop_base) != sdtr_data) {
11297 sta = FALSE;
11299 } else {
11300 sta = FALSE;
11302 AscSetBank(iop_base, 1);
11303 AscWriteChipDvcID(iop_base, org_id);
11304 AscSetBank(iop_base, 0);
11305 return (sta);
11308 STATIC ushort
11309 AscInitLram(
11310 ASC_DVC_VAR *asc_dvc
11313 uchar i;
11314 ushort s_addr;
11315 PortAddr iop_base;
11316 ushort warn_code;
11318 iop_base = asc_dvc->iop_base;
11319 warn_code = 0;
11320 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
11321 (ushort) (((int) (asc_dvc->max_total_qng + 2 + 1) * 64) >> 1)
11323 i = ASC_MIN_ACTIVE_QNO;
11324 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
11325 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11326 (uchar) (i + 1));
11327 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11328 (uchar) (asc_dvc->max_total_qng));
11329 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11330 (uchar) i);
11331 i++;
11332 s_addr += ASC_QBLK_SIZE;
11333 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
11334 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11335 (uchar) (i + 1));
11336 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11337 (uchar) (i - 1));
11338 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11339 (uchar) i);
11341 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11342 (uchar) ASC_QLINK_END);
11343 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11344 (uchar) (asc_dvc->max_total_qng - 1));
11345 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11346 (uchar) asc_dvc->max_total_qng);
11347 i++;
11348 s_addr += ASC_QBLK_SIZE;
11349 for (; i <= (uchar) (asc_dvc->max_total_qng + 3);
11350 i++, s_addr += ASC_QBLK_SIZE) {
11351 AscWriteLramByte(iop_base,
11352 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_FWD), i);
11353 AscWriteLramByte(iop_base,
11354 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_BWD), i);
11355 AscWriteLramByte(iop_base,
11356 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_QNO), i);
11358 return (warn_code);
11361 STATIC ushort
11362 AscInitQLinkVar(
11363 ASC_DVC_VAR *asc_dvc
11366 PortAddr iop_base;
11367 int i;
11368 ushort lram_addr;
11370 iop_base = asc_dvc->iop_base;
11371 AscPutRiscVarFreeQHead(iop_base, 1);
11372 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
11373 AscPutVarFreeQHead(iop_base, 1);
11374 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
11375 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
11376 (uchar) ((int) asc_dvc->max_total_qng + 1));
11377 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
11378 (uchar) ((int) asc_dvc->max_total_qng + 2));
11379 AscWriteLramByte(iop_base, (ushort) ASCV_TOTAL_READY_Q_B,
11380 asc_dvc->max_total_qng);
11381 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
11382 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
11383 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
11384 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
11385 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
11386 AscPutQDoneInProgress(iop_base, 0);
11387 lram_addr = ASC_QADR_BEG;
11388 for (i = 0; i < 32; i++, lram_addr += 2) {
11389 AscWriteLramWord(iop_base, lram_addr, 0);
11391 return (0);
11394 STATIC int
11395 AscSetLibErrorCode(
11396 ASC_DVC_VAR *asc_dvc,
11397 ushort err_code
11400 if (asc_dvc->err_code == 0) {
11401 asc_dvc->err_code = err_code;
11402 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
11403 err_code);
11405 return (err_code);
11409 STATIC uchar
11410 AscMsgOutSDTR(
11411 ASC_DVC_VAR *asc_dvc,
11412 uchar sdtr_period,
11413 uchar sdtr_offset
11416 EXT_MSG sdtr_buf;
11417 uchar sdtr_period_index;
11418 PortAddr iop_base;
11420 iop_base = asc_dvc->iop_base;
11421 sdtr_buf.msg_type = MS_EXTEND;
11422 sdtr_buf.msg_len = MS_SDTR_LEN;
11423 sdtr_buf.msg_req = MS_SDTR_CODE;
11424 sdtr_buf.xfer_period = sdtr_period;
11425 sdtr_offset &= ASC_SYN_MAX_OFFSET;
11426 sdtr_buf.req_ack_offset = sdtr_offset;
11427 if ((sdtr_period_index =
11428 AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
11429 asc_dvc->max_sdtr_index) {
11430 AscMemWordCopyPtrToLram(iop_base,
11431 ASCV_MSGOUT_BEG,
11432 (uchar *) &sdtr_buf,
11433 sizeof (EXT_MSG) >> 1);
11434 return ((sdtr_period_index << 4) | sdtr_offset);
11435 } else {
11437 sdtr_buf.req_ack_offset = 0;
11438 AscMemWordCopyPtrToLram(iop_base,
11439 ASCV_MSGOUT_BEG,
11440 (uchar *) &sdtr_buf,
11441 sizeof (EXT_MSG) >> 1);
11442 return (0);
11446 STATIC uchar
11447 AscCalSDTRData(
11448 ASC_DVC_VAR *asc_dvc,
11449 uchar sdtr_period,
11450 uchar syn_offset
11453 uchar byte;
11454 uchar sdtr_period_ix;
11456 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
11457 if (
11458 (sdtr_period_ix > asc_dvc->max_sdtr_index)
11460 return (0xFF);
11462 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
11463 return (byte);
11466 STATIC void
11467 AscSetChipSDTR(
11468 PortAddr iop_base,
11469 uchar sdtr_data,
11470 uchar tid_no
11473 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
11474 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
11475 return;
11478 STATIC uchar
11479 AscGetSynPeriodIndex(
11480 ASC_DVC_VAR *asc_dvc,
11481 uchar syn_time
11484 uchar *period_table;
11485 int max_index;
11486 int min_index;
11487 int i;
11489 period_table = asc_dvc->sdtr_period_tbl;
11490 max_index = (int) asc_dvc->max_sdtr_index;
11491 min_index = (int)asc_dvc->host_init_sdtr_index;
11492 if ((syn_time <= period_table[max_index])) {
11493 for (i = min_index; i < (max_index - 1); i++) {
11494 if (syn_time <= period_table[i]) {
11495 return ((uchar) i);
11498 return ((uchar) max_index);
11499 } else {
11500 return ((uchar) (max_index + 1));
11504 STATIC uchar
11505 AscAllocFreeQueue(
11506 PortAddr iop_base,
11507 uchar free_q_head
11510 ushort q_addr;
11511 uchar next_qp;
11512 uchar q_status;
11514 q_addr = ASC_QNO_TO_QADDR(free_q_head);
11515 q_status = (uchar) AscReadLramByte(iop_base,
11516 (ushort) (q_addr + ASC_SCSIQ_B_STATUS));
11517 next_qp = AscReadLramByte(iop_base,
11518 (ushort) (q_addr + ASC_SCSIQ_B_FWD));
11519 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
11520 return (next_qp);
11522 return (ASC_QLINK_END);
11525 STATIC uchar
11526 AscAllocMultipleFreeQueue(
11527 PortAddr iop_base,
11528 uchar free_q_head,
11529 uchar n_free_q
11532 uchar i;
11534 for (i = 0; i < n_free_q; i++) {
11535 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
11536 == ASC_QLINK_END) {
11537 return (ASC_QLINK_END);
11540 return (free_q_head);
11543 STATIC int
11544 AscHostReqRiscHalt(
11545 PortAddr iop_base
11548 int count = 0;
11549 int sta = 0;
11550 uchar saved_stop_code;
11552 if (AscIsChipHalted(iop_base))
11553 return (1);
11554 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
11555 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11556 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP
11558 do {
11559 if (AscIsChipHalted(iop_base)) {
11560 sta = 1;
11561 break;
11563 DvcSleepMilliSecond(100);
11564 } while (count++ < 20);
11565 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
11566 return (sta);
11569 STATIC int
11570 AscStopQueueExe(
11571 PortAddr iop_base
11574 int count = 0;
11576 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
11577 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11578 ASC_STOP_REQ_RISC_STOP);
11579 do {
11580 if (
11581 AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
11582 ASC_STOP_ACK_RISC_STOP) {
11583 return (1);
11585 DvcSleepMilliSecond(100);
11586 } while (count++ < 20);
11588 return (0);
11591 STATIC void
11592 DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
11594 udelay(micro_sec);
11597 STATIC void
11598 DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
11600 udelay((nano_sec + 999)/1000);
11603 #ifdef CONFIG_ISA
11604 STATIC ASC_DCNT __init
11605 AscGetEisaProductID(
11606 PortAddr iop_base)
11608 PortAddr eisa_iop;
11609 ushort product_id_high, product_id_low;
11610 ASC_DCNT product_id;
11612 eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
11613 product_id_low = inpw(eisa_iop);
11614 product_id_high = inpw(eisa_iop + 2);
11615 product_id = ((ASC_DCNT) product_id_high << 16) |
11616 (ASC_DCNT) product_id_low;
11617 return (product_id);
11620 STATIC PortAddr __init
11621 AscSearchIOPortAddrEISA(
11622 PortAddr iop_base)
11624 ASC_DCNT eisa_product_id;
11626 if (iop_base == 0) {
11627 iop_base = ASC_EISA_MIN_IOP_ADDR;
11628 } else {
11629 if (iop_base == ASC_EISA_MAX_IOP_ADDR)
11630 return (0);
11631 if ((iop_base & 0x0050) == 0x0050) {
11632 iop_base += ASC_EISA_BIG_IOP_GAP;
11633 } else {
11634 iop_base += ASC_EISA_SMALL_IOP_GAP;
11637 while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
11638 eisa_product_id = AscGetEisaProductID(iop_base);
11639 if ((eisa_product_id == ASC_EISA_ID_740) ||
11640 (eisa_product_id == ASC_EISA_ID_750)) {
11641 if (AscFindSignature(iop_base)) {
11642 inpw(iop_base + 4);
11643 return (iop_base);
11646 if (iop_base == ASC_EISA_MAX_IOP_ADDR)
11647 return (0);
11648 if ((iop_base & 0x0050) == 0x0050) {
11649 iop_base += ASC_EISA_BIG_IOP_GAP;
11650 } else {
11651 iop_base += ASC_EISA_SMALL_IOP_GAP;
11654 return (0);
11656 #endif /* CONFIG_ISA */
11658 STATIC int
11659 AscStartChip(
11660 PortAddr iop_base
11663 AscSetChipControl(iop_base, 0);
11664 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
11665 return (0);
11667 return (1);
11670 STATIC int
11671 AscStopChip(
11672 PortAddr iop_base
11675 uchar cc_val;
11677 cc_val = AscGetChipControl(iop_base) & (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
11678 AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT));
11679 AscSetChipIH(iop_base, INS_HALT);
11680 AscSetChipIH(iop_base, INS_RFLAG_WTM);
11681 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
11682 return (0);
11684 return (1);
11687 STATIC int
11688 AscIsChipHalted(
11689 PortAddr iop_base
11692 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
11693 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
11694 return (1);
11697 return (0);
11700 STATIC void
11701 AscSetChipIH(
11702 PortAddr iop_base,
11703 ushort ins_code
11706 AscSetBank(iop_base, 1);
11707 AscWriteChipIH(iop_base, ins_code);
11708 AscSetBank(iop_base, 0);
11709 return;
11712 STATIC void
11713 AscAckInterrupt(
11714 PortAddr iop_base
11717 uchar host_flag;
11718 uchar risc_flag;
11719 ushort loop;
11721 loop = 0;
11722 do {
11723 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
11724 if (loop++ > 0x7FFF) {
11725 break;
11727 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
11728 host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
11729 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
11730 (uchar) (host_flag | ASC_HOST_FLAG_ACK_INT));
11731 AscSetChipStatus(iop_base, CIW_INT_ACK);
11732 loop = 0;
11733 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
11734 AscSetChipStatus(iop_base, CIW_INT_ACK);
11735 if (loop++ > 3) {
11736 break;
11739 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
11740 return;
11743 STATIC void
11744 AscDisableInterrupt(
11745 PortAddr iop_base
11748 ushort cfg;
11750 cfg = AscGetChipCfgLsw(iop_base);
11751 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
11752 return;
11755 STATIC void
11756 AscEnableInterrupt(
11757 PortAddr iop_base
11760 ushort cfg;
11762 cfg = AscGetChipCfgLsw(iop_base);
11763 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
11764 return;
11769 STATIC void
11770 AscSetBank(
11771 PortAddr iop_base,
11772 uchar bank
11775 uchar val;
11777 val = AscGetChipControl(iop_base) &
11778 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | CC_CHIP_RESET));
11779 if (bank == 1) {
11780 val |= CC_BANK_ONE;
11781 } else if (bank == 2) {
11782 val |= CC_DIAG | CC_BANK_ONE;
11783 } else {
11784 val &= ~CC_BANK_ONE;
11786 AscSetChipControl(iop_base, val);
11787 return;
11790 STATIC int
11791 AscResetChipAndScsiBus(
11792 ASC_DVC_VAR *asc_dvc
11795 PortAddr iop_base;
11796 int i = 10;
11798 iop_base = asc_dvc->iop_base;
11799 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) && (i-- > 0))
11801 DvcSleepMilliSecond(100);
11803 AscStopChip(iop_base);
11804 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
11805 DvcDelayNanoSecond(asc_dvc, 60000);
11806 AscSetChipIH(iop_base, INS_RFLAG_WTM);
11807 AscSetChipIH(iop_base, INS_HALT);
11808 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
11809 AscSetChipControl(iop_base, CC_HALT);
11810 DvcSleepMilliSecond(200);
11811 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
11812 AscSetChipStatus(iop_base, 0);
11813 return (AscIsChipHalted(iop_base));
11816 STATIC ASC_DCNT __init
11817 AscGetMaxDmaCount(
11818 ushort bus_type)
11820 if (bus_type & ASC_IS_ISA)
11821 return (ASC_MAX_ISA_DMA_COUNT);
11822 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
11823 return (ASC_MAX_VL_DMA_COUNT);
11824 return (ASC_MAX_PCI_DMA_COUNT);
11827 #ifdef CONFIG_ISA
11828 STATIC ushort __init
11829 AscGetIsaDmaChannel(
11830 PortAddr iop_base)
11832 ushort channel;
11834 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
11835 if (channel == 0x03)
11836 return (0);
11837 else if (channel == 0x00)
11838 return (7);
11839 return (channel + 4);
11842 STATIC ushort __init
11843 AscSetIsaDmaChannel(
11844 PortAddr iop_base,
11845 ushort dma_channel)
11847 ushort cfg_lsw;
11848 uchar value;
11850 if ((dma_channel >= 5) && (dma_channel <= 7)) {
11851 if (dma_channel == 7)
11852 value = 0x00;
11853 else
11854 value = dma_channel - 4;
11855 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
11856 cfg_lsw |= value;
11857 AscSetChipCfgLsw(iop_base, cfg_lsw);
11858 return (AscGetIsaDmaChannel(iop_base));
11860 return (0);
11863 STATIC uchar __init
11864 AscSetIsaDmaSpeed(
11865 PortAddr iop_base,
11866 uchar speed_value)
11868 speed_value &= 0x07;
11869 AscSetBank(iop_base, 1);
11870 AscWriteChipDmaSpeed(iop_base, speed_value);
11871 AscSetBank(iop_base, 0);
11872 return (AscGetIsaDmaSpeed(iop_base));
11875 STATIC uchar __init
11876 AscGetIsaDmaSpeed(
11877 PortAddr iop_base
11880 uchar speed_value;
11882 AscSetBank(iop_base, 1);
11883 speed_value = AscReadChipDmaSpeed(iop_base);
11884 speed_value &= 0x07;
11885 AscSetBank(iop_base, 0);
11886 return (speed_value);
11888 #endif /* CONFIG_ISA */
11890 STATIC ushort __init
11891 AscReadPCIConfigWord(
11892 ASC_DVC_VAR *asc_dvc,
11893 ushort pci_config_offset)
11895 uchar lsb, msb;
11897 lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
11898 msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
11899 return ((ushort) ((msb << 8) | lsb));
11902 STATIC ushort __init
11903 AscInitGetConfig(
11904 ASC_DVC_VAR *asc_dvc
11907 ushort warn_code;
11908 PortAddr iop_base;
11909 ushort PCIDeviceID;
11910 ushort PCIVendorID;
11911 uchar PCIRevisionID;
11912 uchar prevCmdRegBits;
11914 warn_code = 0;
11915 iop_base = asc_dvc->iop_base;
11916 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
11917 if (asc_dvc->err_code != 0) {
11918 return (UW_ERR);
11920 if (asc_dvc->bus_type == ASC_IS_PCI) {
11921 PCIVendorID = AscReadPCIConfigWord(asc_dvc,
11922 AscPCIConfigVendorIDRegister);
11924 PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
11925 AscPCIConfigDeviceIDRegister);
11927 PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
11928 AscPCIConfigRevisionIDRegister);
11930 if (PCIVendorID != ASC_PCI_VENDORID) {
11931 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
11933 prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
11934 AscPCIConfigCommandRegister);
11936 if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
11937 AscPCICmdRegBits_IOMemBusMaster) {
11938 DvcWritePCIConfigByte(asc_dvc,
11939 AscPCIConfigCommandRegister,
11940 (prevCmdRegBits |
11941 AscPCICmdRegBits_IOMemBusMaster));
11943 if ((DvcReadPCIConfigByte(asc_dvc,
11944 AscPCIConfigCommandRegister)
11945 & AscPCICmdRegBits_IOMemBusMaster)
11946 != AscPCICmdRegBits_IOMemBusMaster) {
11947 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
11950 if ((PCIDeviceID == ASC_PCI_DEVICEID_1200A) ||
11951 (PCIDeviceID == ASC_PCI_DEVICEID_1200B)) {
11952 DvcWritePCIConfigByte(asc_dvc,
11953 AscPCIConfigLatencyTimer, 0x00);
11954 if (DvcReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer)
11955 != 0x00) {
11956 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
11958 } else if (PCIDeviceID == ASC_PCI_DEVICEID_ULTRA) {
11959 if (DvcReadPCIConfigByte(asc_dvc,
11960 AscPCIConfigLatencyTimer) < 0x20) {
11961 DvcWritePCIConfigByte(asc_dvc,
11962 AscPCIConfigLatencyTimer, 0x20);
11964 if (DvcReadPCIConfigByte(asc_dvc,
11965 AscPCIConfigLatencyTimer) < 0x20) {
11966 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
11972 if (AscFindSignature(iop_base)) {
11973 warn_code |= AscInitAscDvcVar(asc_dvc);
11974 warn_code |= AscInitFromEEP(asc_dvc);
11975 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
11976 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
11977 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
11979 } else {
11980 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11982 return(warn_code);
11985 STATIC ushort __init
11986 AscInitSetConfig(
11987 ASC_DVC_VAR *asc_dvc
11990 ushort warn_code = 0;
11992 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
11993 if (asc_dvc->err_code != 0)
11994 return (UW_ERR);
11995 if (AscFindSignature(asc_dvc->iop_base)) {
11996 warn_code |= AscInitFromAscDvcVar(asc_dvc);
11997 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
11998 } else {
11999 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12001 return (warn_code);
12004 STATIC ushort __init
12005 AscInitFromAscDvcVar(
12006 ASC_DVC_VAR *asc_dvc
12009 PortAddr iop_base;
12010 ushort cfg_msw;
12011 ushort warn_code;
12012 ushort pci_device_id = 0;
12014 iop_base = asc_dvc->iop_base;
12015 #ifdef CONFIG_PCI
12016 if (asc_dvc->cfg->dev)
12017 pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device;
12018 #endif
12019 warn_code = 0;
12020 cfg_msw = AscGetChipCfgMsw(iop_base);
12021 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12022 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
12023 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12024 AscSetChipCfgMsw(iop_base, cfg_msw);
12026 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
12027 asc_dvc->cfg->cmd_qng_enabled) {
12028 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
12029 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12031 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12032 warn_code |= ASC_WARN_AUTO_CONFIG;
12034 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
12035 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
12036 != asc_dvc->irq_no) {
12037 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
12040 if (asc_dvc->bus_type & ASC_IS_PCI) {
12041 cfg_msw &= 0xFFC0;
12042 AscSetChipCfgMsw(iop_base, cfg_msw);
12043 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
12044 } else {
12045 if ((pci_device_id == ASC_PCI_DEVICE_ID_REV_A) ||
12046 (pci_device_id == ASC_PCI_DEVICE_ID_REV_B)) {
12047 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
12048 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
12051 } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
12052 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
12053 == ASC_CHIP_VER_ASYN_BUG) {
12054 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
12057 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
12058 asc_dvc->cfg->chip_scsi_id) {
12059 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
12061 #ifdef CONFIG_ISA
12062 if (asc_dvc->bus_type & ASC_IS_ISA) {
12063 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
12064 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
12066 #endif /* CONFIG_ISA */
12067 return (warn_code);
12070 STATIC ushort
12071 AscInitAsc1000Driver(
12072 ASC_DVC_VAR *asc_dvc
12075 ushort warn_code;
12076 PortAddr iop_base;
12078 iop_base = asc_dvc->iop_base;
12079 warn_code = 0;
12080 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
12081 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
12082 AscResetChipAndScsiBus(asc_dvc);
12083 DvcSleepMilliSecond((ASC_DCNT)
12084 ((ushort) asc_dvc->scsi_reset_wait * 1000));
12086 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
12087 if (asc_dvc->err_code != 0)
12088 return (UW_ERR);
12089 if (!AscFindSignature(asc_dvc->iop_base)) {
12090 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12091 return (warn_code);
12093 AscDisableInterrupt(iop_base);
12094 warn_code |= AscInitLram(asc_dvc);
12095 if (asc_dvc->err_code != 0)
12096 return (UW_ERR);
12097 ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
12098 (ulong) _asc_mcode_chksum);
12099 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
12100 _asc_mcode_size) != _asc_mcode_chksum) {
12101 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
12102 return (warn_code);
12104 warn_code |= AscInitMicroCodeVar(asc_dvc);
12105 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
12106 AscEnableInterrupt(iop_base);
12107 return (warn_code);
12110 STATIC ushort __init
12111 AscInitAscDvcVar(
12112 ASC_DVC_VAR *asc_dvc)
12114 int i;
12115 PortAddr iop_base;
12116 ushort warn_code;
12117 uchar chip_version;
12119 iop_base = asc_dvc->iop_base;
12120 warn_code = 0;
12121 asc_dvc->err_code = 0;
12122 if ((asc_dvc->bus_type &
12123 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
12124 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
12126 AscSetChipControl(iop_base, CC_HALT);
12127 AscSetChipStatus(iop_base, 0);
12128 asc_dvc->bug_fix_cntl = 0;
12129 asc_dvc->pci_fix_asyn_xfer = 0;
12130 asc_dvc->pci_fix_asyn_xfer_always = 0;
12131 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
12132 asc_dvc->sdtr_done = 0;
12133 asc_dvc->cur_total_qng = 0;
12134 asc_dvc->is_in_int = 0;
12135 asc_dvc->in_critical_cnt = 0;
12136 asc_dvc->last_q_shortage = 0;
12137 asc_dvc->use_tagged_qng = 0;
12138 asc_dvc->no_scam = 0;
12139 asc_dvc->unit_not_ready = 0;
12140 asc_dvc->queue_full_or_busy = 0;
12141 asc_dvc->redo_scam = 0;
12142 asc_dvc->res2 = 0;
12143 asc_dvc->host_init_sdtr_index = 0;
12144 asc_dvc->cfg->can_tagged_qng = 0;
12145 asc_dvc->cfg->cmd_qng_enabled = 0;
12146 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
12147 asc_dvc->init_sdtr = 0;
12148 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
12149 asc_dvc->scsi_reset_wait = 3;
12150 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
12151 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
12152 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
12153 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
12154 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
12155 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
12156 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
12157 ASC_LIB_VERSION_MINOR;
12158 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
12159 asc_dvc->cfg->chip_version = chip_version;
12160 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
12161 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
12162 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
12163 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
12164 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
12165 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
12166 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
12167 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
12168 asc_dvc->max_sdtr_index = 7;
12169 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
12170 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
12171 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
12172 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
12173 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
12174 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
12175 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
12176 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
12177 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
12178 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
12179 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
12180 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
12181 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
12182 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
12183 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
12184 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
12185 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
12186 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
12187 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
12188 asc_dvc->max_sdtr_index = 15;
12189 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150)
12191 AscSetExtraControl(iop_base,
12192 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
12193 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
12194 AscSetExtraControl(iop_base,
12195 (SEC_ACTIVE_NEGATE | SEC_ENABLE_FILTER));
12198 if (asc_dvc->bus_type == ASC_IS_PCI) {
12199 AscSetExtraControl(iop_base, (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
12202 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
12203 if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
12204 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
12205 asc_dvc->bus_type = ASC_IS_ISAPNP;
12207 #ifdef CONFIG_ISA
12208 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
12209 asc_dvc->cfg->isa_dma_channel = (uchar) AscGetIsaDmaChannel(iop_base);
12211 #endif /* CONFIG_ISA */
12212 for (i = 0; i <= ASC_MAX_TID; i++) {
12213 asc_dvc->cur_dvc_qng[i] = 0;
12214 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
12215 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *) 0L;
12216 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *) 0L;
12217 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
12219 return (warn_code);
12222 STATIC ushort __init
12223 AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
12225 ASCEEP_CONFIG eep_config_buf;
12226 ASCEEP_CONFIG *eep_config;
12227 PortAddr iop_base;
12228 ushort chksum;
12229 ushort warn_code;
12230 ushort cfg_msw, cfg_lsw;
12231 int i;
12232 int write_eep = 0;
12234 iop_base = asc_dvc->iop_base;
12235 warn_code = 0;
12236 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
12237 AscStopQueueExe(iop_base);
12238 if ((AscStopChip(iop_base) == FALSE) ||
12239 (AscGetChipScsiCtrl(iop_base) != 0)) {
12240 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
12241 AscResetChipAndScsiBus(asc_dvc);
12242 DvcSleepMilliSecond((ASC_DCNT)
12243 ((ushort) asc_dvc->scsi_reset_wait * 1000));
12245 if (AscIsChipHalted(iop_base) == FALSE) {
12246 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
12247 return (warn_code);
12249 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
12250 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
12251 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
12252 return (warn_code);
12254 eep_config = (ASCEEP_CONFIG *) &eep_config_buf;
12255 cfg_msw = AscGetChipCfgMsw(iop_base);
12256 cfg_lsw = AscGetChipCfgLsw(iop_base);
12257 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12258 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
12259 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12260 AscSetChipCfgMsw(iop_base, cfg_msw);
12262 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
12263 ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
12264 if (chksum == 0) {
12265 chksum = 0xaa55;
12267 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12268 warn_code |= ASC_WARN_AUTO_CONFIG;
12269 if (asc_dvc->cfg->chip_version == 3) {
12270 if (eep_config->cfg_lsw != cfg_lsw) {
12271 warn_code |= ASC_WARN_EEPROM_RECOVER;
12272 eep_config->cfg_lsw = AscGetChipCfgLsw(iop_base);
12274 if (eep_config->cfg_msw != cfg_msw) {
12275 warn_code |= ASC_WARN_EEPROM_RECOVER;
12276 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
12280 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
12281 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
12282 ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
12283 eep_config->chksum);
12284 if (chksum != eep_config->chksum) {
12285 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
12286 ASC_CHIP_VER_PCI_ULTRA_3050 )
12288 ASC_DBG(1,
12289 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
12290 eep_config->init_sdtr = 0xFF;
12291 eep_config->disc_enable = 0xFF;
12292 eep_config->start_motor = 0xFF;
12293 eep_config->use_cmd_qng = 0;
12294 eep_config->max_total_qng = 0xF0;
12295 eep_config->max_tag_qng = 0x20;
12296 eep_config->cntl = 0xBFFF;
12297 ASC_EEP_SET_CHIP_ID(eep_config, 7);
12298 eep_config->no_scam = 0;
12299 eep_config->adapter_info[0] = 0;
12300 eep_config->adapter_info[1] = 0;
12301 eep_config->adapter_info[2] = 0;
12302 eep_config->adapter_info[3] = 0;
12303 eep_config->adapter_info[4] = 0;
12304 /* Indicate EEPROM-less board. */
12305 eep_config->adapter_info[5] = 0xBB;
12306 } else {
12307 ASC_PRINT(
12308 "AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
12309 write_eep = 1;
12310 warn_code |= ASC_WARN_EEPROM_CHKSUM;
12313 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
12314 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
12315 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
12316 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
12317 asc_dvc->start_motor = eep_config->start_motor;
12318 asc_dvc->dvc_cntl = eep_config->cntl;
12319 asc_dvc->no_scam = eep_config->no_scam;
12320 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
12321 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
12322 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
12323 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
12324 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
12325 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
12326 if (!AscTestExternalLram(asc_dvc)) {
12327 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA)) {
12328 eep_config->max_total_qng = ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
12329 eep_config->max_tag_qng = ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
12330 } else {
12331 eep_config->cfg_msw |= 0x0800;
12332 cfg_msw |= 0x0800;
12333 AscSetChipCfgMsw(iop_base, cfg_msw);
12334 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
12335 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
12337 } else {
12339 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
12340 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
12342 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
12343 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
12345 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
12346 eep_config->max_tag_qng = eep_config->max_total_qng;
12348 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
12349 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
12351 asc_dvc->max_total_qng = eep_config->max_total_qng;
12352 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
12353 eep_config->use_cmd_qng) {
12354 eep_config->disc_enable = eep_config->use_cmd_qng;
12355 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12357 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
12358 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
12360 ASC_EEP_SET_CHIP_ID(eep_config, ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
12361 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
12362 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
12363 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
12364 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
12367 for (i = 0; i <= ASC_MAX_TID; i++) {
12368 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
12369 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
12370 asc_dvc->cfg->sdtr_period_offset[i] =
12371 (uchar) (ASC_DEF_SDTR_OFFSET |
12372 (asc_dvc->host_init_sdtr_index << 4));
12374 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
12375 if (write_eep) {
12376 if ((i = AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type)) !=
12377 0) {
12378 ASC_PRINT1(
12379 "AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n", i);
12380 } else {
12381 ASC_PRINT("AscInitFromEEP: Succesfully re-wrote EEPROM.");
12384 return (warn_code);
12387 STATIC ushort
12388 AscInitMicroCodeVar(
12389 ASC_DVC_VAR *asc_dvc
12392 int i;
12393 ushort warn_code;
12394 PortAddr iop_base;
12395 ASC_PADDR phy_addr;
12396 ASC_DCNT phy_size;
12398 iop_base = asc_dvc->iop_base;
12399 warn_code = 0;
12400 for (i = 0; i <= ASC_MAX_TID; i++) {
12401 AscPutMCodeInitSDTRAtID(iop_base, i,
12402 asc_dvc->cfg->sdtr_period_offset[i]
12406 AscInitQLinkVar(asc_dvc);
12407 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
12408 asc_dvc->cfg->disc_enable);
12409 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
12410 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
12412 /* Align overrun buffer on an 8 byte boundary. */
12413 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
12414 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
12415 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
12416 (uchar *) &phy_addr, 1);
12417 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
12418 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
12419 (uchar *) &phy_size, 1);
12421 asc_dvc->cfg->mcode_date =
12422 AscReadLramWord(iop_base, (ushort) ASCV_MC_DATE_W);
12423 asc_dvc->cfg->mcode_version =
12424 AscReadLramWord(iop_base, (ushort) ASCV_MC_VER_W);
12426 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
12427 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
12428 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
12429 return (warn_code);
12431 if (AscStartChip(iop_base) != 1) {
12432 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
12433 return (warn_code);
12436 return (warn_code);
12439 STATIC int __init
12440 AscTestExternalLram(
12441 ASC_DVC_VAR *asc_dvc)
12443 PortAddr iop_base;
12444 ushort q_addr;
12445 ushort saved_word;
12446 int sta;
12448 iop_base = asc_dvc->iop_base;
12449 sta = 0;
12450 q_addr = ASC_QNO_TO_QADDR(241);
12451 saved_word = AscReadLramWord(iop_base, q_addr);
12452 AscSetChipLramAddr(iop_base, q_addr);
12453 AscSetChipLramData(iop_base, 0x55AA);
12454 DvcSleepMilliSecond(10);
12455 AscSetChipLramAddr(iop_base, q_addr);
12456 if (AscGetChipLramData(iop_base) == 0x55AA) {
12457 sta = 1;
12458 AscWriteLramWord(iop_base, q_addr, saved_word);
12460 return (sta);
12463 STATIC int __init
12464 AscWriteEEPCmdReg(
12465 PortAddr iop_base,
12466 uchar cmd_reg
12469 uchar read_back;
12470 int retry;
12472 retry = 0;
12473 while (TRUE) {
12474 AscSetChipEEPCmd(iop_base, cmd_reg);
12475 DvcSleepMilliSecond(1);
12476 read_back = AscGetChipEEPCmd(iop_base);
12477 if (read_back == cmd_reg) {
12478 return (1);
12480 if (retry++ > ASC_EEP_MAX_RETRY) {
12481 return (0);
12486 STATIC int __init
12487 AscWriteEEPDataReg(
12488 PortAddr iop_base,
12489 ushort data_reg
12492 ushort read_back;
12493 int retry;
12495 retry = 0;
12496 while (TRUE) {
12497 AscSetChipEEPData(iop_base, data_reg);
12498 DvcSleepMilliSecond(1);
12499 read_back = AscGetChipEEPData(iop_base);
12500 if (read_back == data_reg) {
12501 return (1);
12503 if (retry++ > ASC_EEP_MAX_RETRY) {
12504 return (0);
12509 STATIC void __init
12510 AscWaitEEPRead(void)
12512 DvcSleepMilliSecond(1);
12513 return;
12516 STATIC void __init
12517 AscWaitEEPWrite(void)
12519 DvcSleepMilliSecond(20);
12520 return;
12523 STATIC ushort __init
12524 AscReadEEPWord(
12525 PortAddr iop_base,
12526 uchar addr)
12528 ushort read_wval;
12529 uchar cmd_reg;
12531 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
12532 AscWaitEEPRead();
12533 cmd_reg = addr | ASC_EEP_CMD_READ;
12534 AscWriteEEPCmdReg(iop_base, cmd_reg);
12535 AscWaitEEPRead();
12536 read_wval = AscGetChipEEPData(iop_base);
12537 AscWaitEEPRead();
12538 return (read_wval);
12541 STATIC ushort __init
12542 AscWriteEEPWord(
12543 PortAddr iop_base,
12544 uchar addr,
12545 ushort word_val)
12547 ushort read_wval;
12549 read_wval = AscReadEEPWord(iop_base, addr);
12550 if (read_wval != word_val) {
12551 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
12552 AscWaitEEPRead();
12553 AscWriteEEPDataReg(iop_base, word_val);
12554 AscWaitEEPRead();
12555 AscWriteEEPCmdReg(iop_base,
12556 (uchar) ((uchar) ASC_EEP_CMD_WRITE | addr));
12557 AscWaitEEPWrite();
12558 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
12559 AscWaitEEPRead();
12560 return (AscReadEEPWord(iop_base, addr));
12562 return (read_wval);
12565 STATIC ushort __init
12566 AscGetEEPConfig(
12567 PortAddr iop_base,
12568 ASCEEP_CONFIG * cfg_buf, ushort bus_type)
12570 ushort wval;
12571 ushort sum;
12572 ushort *wbuf;
12573 int cfg_beg;
12574 int cfg_end;
12575 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
12576 int s_addr;
12578 wbuf = (ushort *) cfg_buf;
12579 sum = 0;
12580 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
12581 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12582 *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
12583 sum += *wbuf;
12585 if (bus_type & ASC_IS_VL) {
12586 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
12587 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
12588 } else {
12589 cfg_beg = ASC_EEP_DVC_CFG_BEG;
12590 cfg_end = ASC_EEP_MAX_DVC_ADDR;
12592 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
12593 wval = AscReadEEPWord( iop_base, ( uchar )s_addr ) ;
12594 if (s_addr <= uchar_end_in_config) {
12596 * Swap all char fields - must unswap bytes already swapped
12597 * by AscReadEEPWord().
12599 *wbuf = le16_to_cpu(wval);
12600 } else {
12601 /* Don't swap word field at the end - cntl field. */
12602 *wbuf = wval;
12604 sum += wval; /* Checksum treats all EEPROM data as words. */
12607 * Read the checksum word which will be compared against 'sum'
12608 * by the caller. Word field already swapped.
12610 *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
12611 return (sum);
12614 STATIC int __init
12615 AscSetEEPConfigOnce(
12616 PortAddr iop_base,
12617 ASCEEP_CONFIG * cfg_buf, ushort bus_type)
12619 int n_error;
12620 ushort *wbuf;
12621 ushort word;
12622 ushort sum;
12623 int s_addr;
12624 int cfg_beg;
12625 int cfg_end;
12626 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
12629 wbuf = (ushort *) cfg_buf;
12630 n_error = 0;
12631 sum = 0;
12632 /* Write two config words; AscWriteEEPWord() will swap bytes. */
12633 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12634 sum += *wbuf;
12635 if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
12636 n_error++;
12639 if (bus_type & ASC_IS_VL) {
12640 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
12641 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
12642 } else {
12643 cfg_beg = ASC_EEP_DVC_CFG_BEG;
12644 cfg_end = ASC_EEP_MAX_DVC_ADDR;
12646 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
12647 if (s_addr <= uchar_end_in_config) {
12649 * This is a char field. Swap char fields before they are
12650 * swapped again by AscWriteEEPWord().
12652 word = cpu_to_le16(*wbuf);
12653 if (word != AscWriteEEPWord( iop_base, (uchar) s_addr, word)) {
12654 n_error++;
12656 } else {
12657 /* Don't swap word field at the end - cntl field. */
12658 if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
12659 n_error++;
12662 sum += *wbuf; /* Checksum calculated from word values. */
12664 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
12665 *wbuf = sum;
12666 if (sum != AscWriteEEPWord(iop_base, (uchar) s_addr, sum)) {
12667 n_error++;
12670 /* Read EEPROM back again. */
12671 wbuf = (ushort *) cfg_buf;
12673 * Read two config words; Byte-swapping done by AscReadEEPWord().
12675 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12676 if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
12677 n_error++;
12680 if (bus_type & ASC_IS_VL) {
12681 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
12682 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
12683 } else {
12684 cfg_beg = ASC_EEP_DVC_CFG_BEG;
12685 cfg_end = ASC_EEP_MAX_DVC_ADDR;
12687 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
12688 if (s_addr <= uchar_end_in_config) {
12690 * Swap all char fields. Must unswap bytes already swapped
12691 * by AscReadEEPWord().
12693 word = le16_to_cpu(AscReadEEPWord(iop_base, (uchar) s_addr));
12694 } else {
12695 /* Don't swap word field at the end - cntl field. */
12696 word = AscReadEEPWord(iop_base, (uchar) s_addr);
12698 if (*wbuf != word) {
12699 n_error++;
12702 /* Read checksum; Byte swapping not needed. */
12703 if (AscReadEEPWord(iop_base, (uchar) s_addr) != sum) {
12704 n_error++;
12706 return (n_error);
12709 STATIC int __init
12710 AscSetEEPConfig(
12711 PortAddr iop_base,
12712 ASCEEP_CONFIG * cfg_buf, ushort bus_type
12715 int retry;
12716 int n_error;
12718 retry = 0;
12719 while (TRUE) {
12720 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
12721 bus_type)) == 0) {
12722 break;
12724 if (++retry > ASC_EEP_MAX_RETRY) {
12725 break;
12728 return (n_error);
12731 STATIC void
12732 AscAsyncFix(
12733 ASC_DVC_VAR *asc_dvc,
12734 uchar tid_no,
12735 ASC_SCSI_INQUIRY *inq)
12737 uchar dvc_type;
12738 ASC_SCSI_BIT_ID_TYPE tid_bits;
12740 dvc_type = ASC_INQ_DVC_TYPE(inq);
12741 tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
12743 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN)
12745 if (!(asc_dvc->init_sdtr & tid_bits))
12747 if ((dvc_type == TYPE_ROM) &&
12748 (AscCompareString((uchar *) inq->vendor_id,
12749 (uchar *) "HP ", 3) == 0))
12751 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
12753 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
12754 if ((dvc_type == TYPE_PROCESSOR) ||
12755 (dvc_type == TYPE_SCANNER) ||
12756 (dvc_type == TYPE_ROM) ||
12757 (dvc_type == TYPE_TAPE))
12759 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
12762 if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
12764 AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no,
12765 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
12769 return;
12772 STATIC int
12773 AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
12775 if ((inq->add_len >= 32) &&
12776 (AscCompareString((uchar *) inq->vendor_id,
12777 (uchar *) "QUANTUM XP34301", 15) == 0) &&
12778 (AscCompareString((uchar *) inq->product_rev_level,
12779 (uchar *) "1071", 4) == 0))
12781 return 0;
12783 return 1;
12786 STATIC void
12787 AscInquiryHandling(ASC_DVC_VAR *asc_dvc,
12788 uchar tid_no, ASC_SCSI_INQUIRY *inq)
12790 ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
12791 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
12793 orig_init_sdtr = asc_dvc->init_sdtr;
12794 orig_use_tagged_qng = asc_dvc->use_tagged_qng;
12796 asc_dvc->init_sdtr &= ~tid_bit;
12797 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
12798 asc_dvc->use_tagged_qng &= ~tid_bit;
12800 if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) {
12801 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) {
12802 asc_dvc->init_sdtr |= tid_bit;
12804 if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) &&
12805 ASC_INQ_CMD_QUEUE(inq)) {
12806 if (AscTagQueuingSafe(inq)) {
12807 asc_dvc->use_tagged_qng |= tid_bit;
12808 asc_dvc->cfg->can_tagged_qng |= tid_bit;
12812 if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
12813 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
12814 asc_dvc->cfg->disc_enable);
12815 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
12816 asc_dvc->use_tagged_qng);
12817 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
12818 asc_dvc->cfg->can_tagged_qng);
12820 asc_dvc->max_dvc_qng[tid_no] =
12821 asc_dvc->cfg->max_tag_qng[tid_no];
12822 AscWriteLramByte(asc_dvc->iop_base,
12823 (ushort) (ASCV_MAX_DVC_QNG_BEG + tid_no),
12824 asc_dvc->max_dvc_qng[tid_no]);
12826 if (orig_init_sdtr != asc_dvc->init_sdtr) {
12827 AscAsyncFix(asc_dvc, tid_no, inq);
12829 return;
12832 STATIC int
12833 AscCompareString(
12834 uchar *str1,
12835 uchar *str2,
12836 int len
12839 int i;
12840 int diff;
12842 for (i = 0; i < len; i++) {
12843 diff = (int) (str1[i] - str2[i]);
12844 if (diff != 0)
12845 return (diff);
12847 return (0);
12850 STATIC uchar
12851 AscReadLramByte(
12852 PortAddr iop_base,
12853 ushort addr
12856 uchar byte_data;
12857 ushort word_data;
12859 if (isodd_word(addr)) {
12860 AscSetChipLramAddr(iop_base, addr - 1);
12861 word_data = AscGetChipLramData(iop_base);
12862 byte_data = (uchar) ((word_data >> 8) & 0xFF);
12863 } else {
12864 AscSetChipLramAddr(iop_base, addr);
12865 word_data = AscGetChipLramData(iop_base);
12866 byte_data = (uchar) (word_data & 0xFF);
12868 return (byte_data);
12870 STATIC ushort
12871 AscReadLramWord(
12872 PortAddr iop_base,
12873 ushort addr
12876 ushort word_data;
12878 AscSetChipLramAddr(iop_base, addr);
12879 word_data = AscGetChipLramData(iop_base);
12880 return (word_data);
12883 #if CC_VERY_LONG_SG_LIST
12884 STATIC ASC_DCNT
12885 AscReadLramDWord(
12886 PortAddr iop_base,
12887 ushort addr
12890 ushort val_low, val_high;
12891 ASC_DCNT dword_data;
12893 AscSetChipLramAddr(iop_base, addr);
12894 val_low = AscGetChipLramData(iop_base);
12895 val_high = AscGetChipLramData(iop_base);
12896 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
12897 return (dword_data);
12899 #endif /* CC_VERY_LONG_SG_LIST */
12901 STATIC void
12902 AscWriteLramWord(
12903 PortAddr iop_base,
12904 ushort addr,
12905 ushort word_val
12908 AscSetChipLramAddr(iop_base, addr);
12909 AscSetChipLramData(iop_base, word_val);
12910 return;
12913 STATIC void
12914 AscWriteLramByte(
12915 PortAddr iop_base,
12916 ushort addr,
12917 uchar byte_val
12920 ushort word_data;
12922 if (isodd_word(addr)) {
12923 addr--;
12924 word_data = AscReadLramWord(iop_base, addr);
12925 word_data &= 0x00FF;
12926 word_data |= (((ushort) byte_val << 8) & 0xFF00);
12927 } else {
12928 word_data = AscReadLramWord(iop_base, addr);
12929 word_data &= 0xFF00;
12930 word_data |= ((ushort) byte_val & 0x00FF);
12932 AscWriteLramWord(iop_base, addr, word_data);
12933 return;
12937 * Copy 2 bytes to LRAM.
12939 * The source data is assumed to be in little-endian order in memory
12940 * and is maintained in little-endian order when written to LRAM.
12942 STATIC void
12943 AscMemWordCopyPtrToLram(
12944 PortAddr iop_base,
12945 ushort s_addr,
12946 uchar *s_buffer,
12947 int words
12950 int i;
12952 AscSetChipLramAddr(iop_base, s_addr);
12953 for (i = 0; i < 2 * words; i += 2) {
12955 * On a little-endian system the second argument below
12956 * produces a little-endian ushort which is written to
12957 * LRAM in little-endian order. On a big-endian system
12958 * the second argument produces a big-endian ushort which
12959 * is "transparently" byte-swapped by outpw() and written
12960 * in little-endian order to LRAM.
12962 outpw(iop_base + IOP_RAM_DATA,
12963 ((ushort) s_buffer[i + 1] << 8) | s_buffer[i]);
12965 return;
12969 * Copy 4 bytes to LRAM.
12971 * The source data is assumed to be in little-endian order in memory
12972 * and is maintained in little-endian order when writen to LRAM.
12974 STATIC void
12975 AscMemDWordCopyPtrToLram(
12976 PortAddr iop_base,
12977 ushort s_addr,
12978 uchar *s_buffer,
12979 int dwords
12982 int i;
12984 AscSetChipLramAddr(iop_base, s_addr);
12985 for (i = 0; i < 4 * dwords; i += 4) {
12986 outpw(iop_base + IOP_RAM_DATA,
12987 ((ushort) s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
12988 outpw(iop_base + IOP_RAM_DATA,
12989 ((ushort) s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
12991 return;
12995 * Copy 2 bytes from LRAM.
12997 * The source data is assumed to be in little-endian order in LRAM
12998 * and is maintained in little-endian order when written to memory.
13000 STATIC void
13001 AscMemWordCopyPtrFromLram(
13002 PortAddr iop_base,
13003 ushort s_addr,
13004 uchar *d_buffer,
13005 int words
13008 int i;
13009 ushort word;
13011 AscSetChipLramAddr(iop_base, s_addr);
13012 for (i = 0; i < 2 * words; i += 2) {
13013 word = inpw(iop_base + IOP_RAM_DATA);
13014 d_buffer[i] = word & 0xff;
13015 d_buffer[i + 1] = (word >> 8) & 0xff;
13017 return;
13020 STATIC ASC_DCNT
13021 AscMemSumLramWord(
13022 PortAddr iop_base,
13023 ushort s_addr,
13024 int words
13027 ASC_DCNT sum;
13028 int i;
13030 sum = 0L;
13031 for (i = 0; i < words; i++, s_addr += 2) {
13032 sum += AscReadLramWord(iop_base, s_addr);
13034 return (sum);
13037 STATIC void
13038 AscMemWordSetLram(
13039 PortAddr iop_base,
13040 ushort s_addr,
13041 ushort set_wval,
13042 int words
13045 int i;
13047 AscSetChipLramAddr(iop_base, s_addr);
13048 for (i = 0; i < words; i++) {
13049 AscSetChipLramData(iop_base, set_wval);
13051 return;
13056 * --- Adv Library Functions
13059 /* a_mcode.h */
13061 /* Microcode buffer is kept after initialization for error recovery. */
13062 STATIC unsigned char _adv_asc3550_buf[] = {
13063 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc, 0x01, 0x00, 0x48, 0xe4,
13064 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7,
13065 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6,
13066 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00, 0x00, 0xec, 0x85, 0xf0,
13067 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00,
13068 0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80,
13069 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea,
13070 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00,
13071 0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54,
13072 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00, 0x3e, 0x00, 0x80, 0x00,
13073 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01,
13074 0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55,
13075 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
13076 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15,
13077 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0,
13078 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01,
13079 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c,
13080 0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0,
13081 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00,
13082 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10,
13083 0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15,
13084 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45,
13085 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6,
13086 0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa,
13087 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00, 0x9e, 0x00, 0xa8, 0x00,
13088 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01,
13089 0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08,
13090 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x06, 0x12,
13091 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17,
13092 0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47,
13093 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55, 0x14, 0x56, 0x77, 0x57,
13094 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe,
13095 0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff,
13096 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, 0x00, 0xfe, 0x57, 0x24,
13097 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08,
13098 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f,
13099 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xcf,
13100 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe,
13101 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe,
13102 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b, 0x02, 0xfe, 0xd4, 0x0c,
13103 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6,
13104 0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02,
13105 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02, 0xfe, 0x46, 0xf0, 0xfe,
13106 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44,
13107 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18,
13108 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9,
13109 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e,
13110 0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd,
13111 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, 0x1c, 0x17, 0x06,
13112 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe,
13113 0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f,
13114 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe, 0x69, 0x10, 0x17, 0x06,
13115 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe,
13116 0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40,
13117 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0x99, 0x01,
13118 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02,
13119 0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b,
13120 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0, 0xfe, 0x56, 0x03, 0xfe,
13121 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe,
13122 0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04,
13123 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40, 0x01, 0x0e, 0xac, 0x75,
13124 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe,
13125 0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4,
13126 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe, 0x0a, 0xf0, 0xfe, 0x7a,
13127 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe,
13128 0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c,
13129 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3, 0x0a, 0xca, 0x01, 0x0e,
13130 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f,
13131 0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f,
13132 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2b, 0xff, 0x02,
13133 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5,
13134 0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
13135 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d, 0xfe, 0x2a, 0x13, 0x2f,
13136 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86,
13137 0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12,
13138 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22,
13139 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29,
13140 0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4,
13141 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a, 0xfe, 0x70, 0x12, 0x49,
13142 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31,
13143 0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12,
13144 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05, 0x11, 0xfe, 0xe3, 0x00,
13145 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24,
13146 0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08,
13147 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01, 0x86, 0x24, 0x06, 0x12,
13148 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92,
13149 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe,
13150 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13, 0x47, 0x01, 0xa7, 0x26,
13151 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14,
13152 0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c,
13153 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x14,
13154 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57,
13155 0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04,
13156 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68, 0x06, 0x11, 0x9a, 0x01,
13157 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72,
13158 0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe,
13159 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07, 0x8d, 0x81, 0x02, 0x22,
13160 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00,
13161 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32,
13162 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15, 0xfe, 0x1b, 0x00, 0x01,
13163 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01,
13164 0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d,
13165 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12,
13166 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d,
13167 0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02,
13168 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x77, 0xfe, 0xca,
13169 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12,
13170 0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1,
13171 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f, 0x40, 0x12, 0x58, 0x01,
13172 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe,
13173 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe,
13174 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a, 0xfe, 0x2a, 0x12, 0xfe,
13175 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe,
13176 0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe,
13177 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x39, 0x18, 0x3a,
13178 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48,
13179 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80,
13180 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x7a, 0x08, 0x8d,
13181 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06,
13182 0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c,
13183 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe, 0x52, 0x12, 0xfe, 0x2c,
13184 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10,
13185 0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe,
13186 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xb5, 0xfe,
13187 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d,
13188 0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33,
13189 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a, 0xfe, 0x74, 0x18, 0x1c,
13190 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27,
13191 0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe,
13192 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc, 0xfe, 0x83, 0x80, 0xfe,
13193 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59,
13194 0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf,
13195 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e, 0x79, 0x56, 0x68, 0x57,
13196 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b,
13197 0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39,
13198 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x10, 0x58, 0xfe,
13199 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09,
13200 0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe,
13201 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08, 0x11, 0x9b, 0x09, 0x04,
13202 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe,
13203 0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12,
13204 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9, 0x14, 0x7a, 0x01, 0x33,
13205 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf,
13206 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10,
13207 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x84, 0x05, 0xcb, 0x1c,
13208 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a,
13209 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca,
13210 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe, 0x22, 0x00, 0x02, 0x5a,
13211 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe,
13212 0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10,
13213 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00, 0x2a, 0x13, 0xfe, 0x4e,
13214 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73,
13215 0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48,
13216 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xdb, 0x10, 0x11, 0xfe,
13217 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8,
13218 0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42,
13219 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c, 0x09, 0x04, 0x0b, 0xfe,
13220 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6,
13221 0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01,
13222 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x02, 0x29,
13223 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b,
13224 0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe,
13225 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01, 0xe8, 0x59, 0x11, 0x2d,
13226 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e,
13227 0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe,
13228 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d,
13229 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe,
13230 0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00,
13231 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa, 0xab, 0x70, 0x05, 0x6b,
13232 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01,
13233 0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01,
13234 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e, 0x1d, 0xfe, 0xce, 0x45,
13235 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe,
13236 0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d,
13237 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe,
13238 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee,
13239 0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e,
13240 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12, 0xce, 0x1e, 0x2d, 0x47,
13241 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe,
13242 0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02,
13243 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
13244 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea,
13245 0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01,
13246 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01,
13247 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e,
13248 0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24,
13249 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57,
13250 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe,
13251 0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04,
13252 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xe1,
13253 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c,
13254 0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d,
13255 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01, 0xe8, 0x11, 0xfe, 0xe9,
13256 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14,
13257 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe,
13258 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80, 0x40, 0x12, 0x20, 0x63,
13259 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac,
13260 0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe,
13261 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x24, 0x69, 0x12, 0xc9,
13262 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91,
13263 0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe,
13264 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c, 0x46, 0x1e, 0x20, 0xed,
13265 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c,
13266 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d,
13267 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46, 0xfa, 0xef, 0xfe, 0x42,
13268 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0,
13269 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10,
13270 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e, 0x10, 0x07, 0x7e, 0x45,
13271 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97,
13272 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe,
13273 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b, 0xfe, 0x48, 0x12, 0x07,
13274 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07,
13275 0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe,
13276 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b, 0x01, 0x08, 0x8c, 0x43,
13277 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b,
13278 0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04,
13279 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe, 0xc6, 0x10, 0x1e, 0x58,
13280 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23,
13281 0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1,
13282 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0xfe,
13283 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57,
13284 0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
13285 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e, 0x58, 0xfe, 0x1f, 0x40,
13286 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44,
13287 0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39,
13288 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06, 0x12, 0xcd, 0x02, 0x5b,
13289 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21,
13290 0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe,
13291 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51,
13292 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32,
13293 0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01,
13294 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44, 0x01, 0x08, 0x1f, 0xa2,
13295 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49,
13296 0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda,
13297 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1, 0x05, 0xc6, 0x28, 0x84,
13298 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
13299 0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02,
13300 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06, 0x21, 0x44, 0x01, 0xfe,
13301 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b,
13302 0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05,
13303 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xd8, 0x14, 0x02, 0x5c,
13304 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72,
13305 0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01,
13306 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0xfe, 0xff, 0x7f,
13307 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c,
13308 0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
13309 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58, 0x03, 0x0a, 0x50, 0x01,
13310 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4,
13311 0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27,
13312 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe,
13313 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60,
13314 0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14,
13315 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe, 0xcc, 0x12, 0x49, 0x04,
13316 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13,
13317 0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83,
13318 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c, 0x13, 0x06, 0xfe, 0x56,
13319 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93,
13320 0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4,
13321 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90, 0x01, 0xba, 0xfe, 0x4e,
13322 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe,
13323 0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c,
13324 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba, 0xfe, 0x9c, 0x14, 0xb7,
13325 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7,
13326 0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe,
13327 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x0b, 0x01,
13328 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03,
13329 0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08,
13330 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89, 0x4a, 0x01, 0x08, 0x03,
13331 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00,
13332 0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe,
13333 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd, 0x01, 0x43, 0x1e, 0xcd,
13334 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10,
13335 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88,
13336 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3, 0x88, 0x03, 0x0a, 0x42,
13337 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2,
13338 0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17,
13339 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe,
13340 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe,
13341 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10,
13342 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58, 0x05, 0xfe, 0x66, 0x01,
13343 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66,
13344 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6,
13345 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17, 0x10, 0x71, 0xfe, 0x83,
13346 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe,
13347 0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
13348 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71, 0xfe, 0x30, 0xbc, 0xfe,
13349 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a,
13350 0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02,
13351 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc, 0xfe, 0x1d, 0xf7, 0x4f,
13352 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58,
13353 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63,
13354 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14, 0x06, 0x37, 0x95, 0xa9,
13355 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d,
13356 0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c,
13357 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x3c, 0x8a, 0x0a,
13358 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc,
13359 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f,
13360 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xf6, 0xfe, 0xd6, 0xf0,
13361 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76,
13362 0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f,
13363 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68, 0xc8, 0xfe, 0x48, 0x55,
13364 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0,
13365 0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42,
13366 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01, 0x0e, 0x73, 0x75, 0x03,
13367 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b,
13368 0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b,
13369 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05, 0xfe, 0x94, 0x00, 0xfe,
13370 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e,
13371 0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe,
13372 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1b, 0xfe, 0x5a,
13373 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07,
13374 0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14,
13375 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9, 0x03, 0x25, 0xfe, 0xca,
13376 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00,
13379 STATIC unsigned short _adv_asc3550_size =
13380 sizeof(_adv_asc3550_buf); /* 0x13AD */
13381 STATIC ADV_DCNT _adv_asc3550_chksum =
13382 0x04D52DDDUL; /* Expanded little-endian checksum. */
13384 /* Microcode buffer is kept after initialization for error recovery. */
13385 STATIC unsigned char _adv_asc38C0800_buf[] = {
13386 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4, 0x01, 0x00, 0x48, 0xe4,
13387 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6,
13388 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0,
13389 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0, 0x18, 0xf4, 0x08, 0x00,
13390 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0,
13391 0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00,
13392 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13, 0xba, 0x13, 0x18, 0x40,
13393 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01,
13394 0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
13395 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12, 0x08, 0x12, 0x02, 0x4a,
13396 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa,
13397 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
13398 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d, 0x06, 0x13, 0x4c, 0x1c,
13399 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00,
13400 0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44,
13401 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa, 0x05, 0x00, 0x34, 0x00,
13402 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f,
13403 0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54,
13404 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0,
13405 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00,
13406 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03,
13407 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13, 0x12, 0x13, 0x24, 0x14,
13408 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44,
13409 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55,
13410 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0, 0x04, 0xf8,
13411 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00,
13412 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01,
13413 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08, 0x68, 0x08, 0x69, 0x08,
13414 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10,
13415 0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14,
13416 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18, 0xca, 0x18, 0xe6, 0x19,
13417 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe,
13418 0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff,
13419 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, 0x00, 0xfe, 0x57, 0x24,
13420 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08,
13421 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11,
13422 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xd6,
13423 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe,
13424 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe,
13425 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d, 0x02, 0xfe, 0xc8, 0x0d,
13426 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6,
13427 0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02,
13428 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02, 0xfe, 0x46, 0xf0, 0xfe,
13429 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44,
13430 0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14,
13431 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9,
13432 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8,
13433 0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd,
13434 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, 0x1c, 0x18, 0x06,
13435 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe,
13436 0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10,
13437 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe, 0x69, 0x10, 0x18, 0x06,
13438 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe,
13439 0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
13440 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x09,
13441 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
13442 0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe,
13443 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x40, 0x1c, 0x1c,
13444 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0,
13445 0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02,
13446 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13, 0x21, 0x22, 0xa3, 0xb7,
13447 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9,
13448 0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27,
13449 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe, 0x06, 0xf0, 0xfe, 0xc8,
13450 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe,
13451 0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19,
13452 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x74, 0x01, 0xaf, 0x8c,
13453 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79,
13454 0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02,
13455 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d, 0xfe, 0x3c, 0x04, 0x3b,
13456 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b,
13457 0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe,
13458 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0x4f, 0x79, 0x2a,
13459 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32,
13460 0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe,
13461 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x08, 0x13, 0x32, 0x07,
13462 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d,
13463 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6,
13464 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36, 0x02, 0x2b, 0xfe, 0x42,
13465 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe,
13466 0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c,
13467 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28, 0x17, 0xfe, 0x90, 0x05,
13468 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe,
13469 0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48,
13470 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0x12, 0xfe, 0xe3, 0x00,
13471 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25,
13472 0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02,
13473 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2, 0x08, 0x53, 0x05, 0xcb,
13474 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22,
13475 0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36,
13476 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb, 0x03, 0x5c, 0x28, 0xfe,
13477 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02,
13478 0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe,
13479 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62, 0x12, 0x03, 0x45, 0x28,
13480 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc,
13481 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2,
13482 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01, 0xfe, 0xcc, 0x15, 0x1d,
13483 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45,
13484 0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb,
13485 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07, 0xfe, 0x06, 0xf0, 0xfe,
13486 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b,
13487 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01,
13488 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38, 0x12, 0x08, 0x05, 0x1a,
13489 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
13490 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe,
13491 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b, 0xfe, 0x09, 0x6f, 0xba,
13492 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c,
13493 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01,
13494 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
13495 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07,
13496 0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe,
13497 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b, 0x37, 0x01, 0xb3, 0xb8,
13498 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51,
13499 0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c,
13500 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d, 0x14, 0x3e, 0xfe, 0x4a,
13501 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14,
13502 0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe,
13503 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f,
13504 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c,
13505 0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e,
13506 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe, 0x9a, 0x08, 0xc6, 0xfe,
13507 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24,
13508 0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12,
13509 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e, 0x1c, 0x02, 0xfe, 0x18,
13510 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa,
13511 0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7,
13512 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18, 0xfe, 0xf1, 0x18, 0xfe,
13513 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95,
13514 0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5,
13515 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18, 0x0b, 0xb6, 0xfe, 0xbf,
13516 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2,
13517 0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5,
13518 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15, 0x9d, 0x01, 0x36, 0x10,
13519 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19,
13520 0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe,
13521 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0x08, 0x05,
13522 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c,
13523 0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49,
13524 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18, 0x8f, 0xfe, 0xe3, 0x54,
13525 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b,
13526 0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b,
13527 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00, 0xad, 0xfe, 0x01, 0x59,
13528 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3,
13529 0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b,
13530 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63, 0x02, 0x4a, 0x08, 0x05,
13531 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1,
13532 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a,
13533 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29, 0x61, 0x0c, 0x7f, 0x14,
13534 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c,
13535 0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef,
13536 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40, 0xe4, 0x08, 0x05, 0x1f,
13537 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f,
13538 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05,
13539 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19, 0x81, 0x50, 0xfe, 0x10,
13540 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6,
13541 0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c,
13542 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7, 0x08, 0x05, 0x0a, 0xfe,
13543 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e,
13544 0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed,
13545 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe, 0x00, 0xff, 0x35, 0xfe,
13546 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03,
13547 0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe,
13548 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0,
13549 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00,
13550 0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0,
13551 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea, 0x0b, 0x10, 0x58, 0xfe,
13552 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f,
13553 0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34,
13554 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20, 0x0c, 0x1c, 0x34, 0x94,
13555 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10,
13556 0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33,
13557 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24, 0x33, 0x31, 0xdf, 0xbc,
13558 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d,
13559 0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28,
13560 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x44, 0xfe, 0x28, 0x00,
13561 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f,
13562 0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10,
13563 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xac,
13564 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01,
13565 0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08,
13566 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05, 0x1a, 0xfe, 0x58, 0x12,
13567 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe,
13568 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10,
13569 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10, 0xfe, 0x13, 0x00, 0xfe,
13570 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5,
13571 0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe,
13572 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0, 0xb4, 0x15, 0xfe, 0x31,
13573 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44,
13574 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75,
13575 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x44, 0x48,
13576 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09,
13577 0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d,
13578 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0xce, 0x47, 0xfe, 0xad,
13579 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13,
13580 0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06,
13581 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe, 0x3a, 0x01, 0x56, 0xfe,
13582 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05,
13583 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe,
13584 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13, 0x15, 0x1a, 0x39, 0xa0,
13585 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01,
13586 0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12,
13587 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12, 0x22, 0x9f, 0xb7, 0x13,
13588 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9,
13589 0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc,
13590 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21, 0xfe, 0x00, 0xcc, 0x04,
13591 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07,
13592 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe,
13593 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x0a, 0xfe, 0x3c, 0x50,
13594 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b,
13595 0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01,
13596 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01,
13597 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01,
13598 0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79,
13599 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00,
13601 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09,
13602 0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52,
13603 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc, 0x0f, 0x44, 0x11, 0x0f,
13604 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20,
13605 0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
13606 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x04, 0x42,
13607 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01,
13608 0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f,
13609 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45,
13610 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09,
13611 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14,
13612 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d, 0xfe, 0x01, 0xec, 0xa2,
13613 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe,
13614 0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07,
13615 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17, 0xfe, 0x32, 0x12, 0x07,
13616 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12,
13617 0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d,
13618 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d, 0x32, 0x07, 0xa6, 0xfe,
13619 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12,
13620 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03,
13621 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21, 0x0c, 0x7f, 0x0c, 0x80,
13622 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55,
13623 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f,
13624 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40, 0x88, 0x9b, 0x2e, 0x9c,
13625 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14,
13626 0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61,
13627 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50,
13628 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40,
13629 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d,
13630 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23, 0x72, 0x01, 0xaf, 0x1e,
13631 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe,
13632 0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19,
13633 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31,
13634 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d,
13635 0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8,
13636 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53, 0x05, 0x1f, 0x35, 0xa9,
13637 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c,
13638 0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35,
13639 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x03, 0x5c, 0xc1, 0x0c,
13640 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c,
13641 0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1,
13642 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a, 0xf4, 0x06, 0xea, 0x32,
13643 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89,
13644 0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13,
13645 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0, 0x13, 0x1c, 0xfe, 0xd0,
13646 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02,
13647 0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f,
13648 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04,
13649 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52,
13650 0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03,
13651 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52, 0xfe, 0x00, 0x7d, 0xfe,
13652 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f,
13653 0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01,
13654 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33,
13655 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59,
13656 0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee,
13657 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c, 0x30, 0xfe, 0x78, 0x10,
13658 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00,
13659 0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00,
13660 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28, 0x10, 0x69, 0x06, 0xfe,
13661 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06,
13662 0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe,
13663 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4, 0x9e, 0xfe, 0xf3, 0x10,
13664 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
13665 0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
13666 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d, 0xf4, 0x00, 0xe9, 0x91,
13667 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01,
13668 0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76,
13669 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x19, 0x01, 0x0b,
13670 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76,
13671 0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8,
13672 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01,
13673 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00,
13674 0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06,
13675 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e, 0x07, 0x11, 0xae, 0x09,
13676 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80,
13677 0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e,
13678 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x4c,
13679 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87,
13680 0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24,
13681 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4, 0x17, 0xad, 0x9a, 0x1b,
13682 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10,
13683 0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe,
13684 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c,
13685 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17,
13686 0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75,
13687 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x2e, 0x97, 0xfe, 0x5a,
13688 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
13689 0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe,
13690 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0xcb, 0x97, 0xfe, 0x92,
13691 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02,
13692 0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d,
13693 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x9a, 0x5b, 0x41, 0xfe,
13694 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd,
13695 0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39,
13696 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04, 0xfe, 0x7e, 0x18, 0x1e,
13697 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10,
13698 0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09,
13699 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc,
13700 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c,
13701 0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14,
13702 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c, 0xe7, 0x0a, 0x10, 0xfe,
13703 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37,
13704 0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b,
13705 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77, 0x13, 0xa3, 0x04, 0x09,
13706 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8,
13707 0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09,
13708 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe, 0x1c, 0x19, 0x03, 0xfe,
13709 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19,
13710 0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b,
13711 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe, 0x08, 0x10, 0x03, 0xfe,
13712 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7,
13713 0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00,
13714 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19, 0x04, 0x07, 0x7e, 0xfe,
13715 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a,
13716 0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07,
13717 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59, 0xa9, 0xb8, 0x04, 0x15,
13718 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c,
13719 0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0,
13720 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
13723 STATIC unsigned short _adv_asc38C0800_size =
13724 sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
13725 STATIC ADV_DCNT _adv_asc38C0800_chksum =
13726 0x050D3FD8UL; /* Expanded little-endian checksum. */
13728 /* Microcode buffer is kept after initialization for error recovery. */
13729 STATIC unsigned char _adv_asc38C1600_buf[] = {
13730 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0, 0x18, 0xe4, 0x01, 0x00,
13731 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f,
13732 0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0,
13733 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00, 0x98, 0x57, 0x01, 0xe6,
13734 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0,
13735 0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0,
13736 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01, 0x06, 0x13, 0x0c, 0x1c,
13737 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80,
13738 0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea,
13739 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x04, 0x13, 0xbb, 0x55,
13740 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00,
13741 0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c,
13742 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01,
13743 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01,
13744 0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48,
13745 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x06, 0x00,
13746 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c,
13747 0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0,
13748 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00,
13749 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09,
13750 0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16,
13751 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
13752 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00,
13753 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c,
13754 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x42, 0x1d, 0x08, 0x44,
13755 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59,
13756 0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8,
13757 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0xa8, 0x00, 0xaa, 0x00,
13758 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01,
13759 0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d,
13760 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10, 0xf3, 0x10, 0x06, 0x12,
13761 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe,
13762 0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff,
13763 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, 0x00, 0xfe, 0x57, 0x24,
13764 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08,
13765 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13,
13766 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xe8,
13767 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe,
13768 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe,
13769 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d, 0x05, 0xfe, 0x08, 0x0f,
13770 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe,
13771 0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90,
13772 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8, 0x02, 0xfe, 0x46, 0xf0,
13773 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe,
13774 0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07,
13775 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02, 0x1c, 0xf5, 0xfe, 0x1e,
13776 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01,
13777 0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe,
13778 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, 0x1c, 0x1c,
13779 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02,
13780 0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01,
13781 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09, 0x1a, 0x31, 0xfe, 0x69,
13782 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c,
13783 0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51,
13784 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00,
13785 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54,
13786 0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30,
13787 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0, 0xfe, 0xe4, 0x01, 0xfe,
13788 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66,
13789 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f,
13790 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05, 0x70, 0x37, 0xfe, 0x48,
13791 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20,
13792 0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe,
13793 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32, 0x15, 0xfe, 0xe4, 0x00,
13794 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe,
13795 0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b,
13796 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xfe, 0x46, 0x1c,
13797 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75,
13798 0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77,
13799 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02,
13800 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04,
13801 0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01,
13802 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25, 0xee, 0xfe, 0x4c, 0x44,
13803 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d,
13804 0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe,
13805 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10, 0x13, 0x34, 0xfe, 0x4c,
13806 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06,
13807 0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f,
13808 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f, 0xfe, 0xa4, 0x0e, 0x05,
13809 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b,
13810 0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46,
13811 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04, 0xfe, 0x87, 0x83, 0xfe,
13812 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20,
13813 0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06,
13814 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda, 0x05, 0xd0, 0x54, 0x01,
13815 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff,
13816 0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe,
13817 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01, 0x38, 0xfe, 0x4a, 0xf0,
13818 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e,
13819 0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0,
13820 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe, 0x1c, 0x00, 0x4d, 0x01,
13821 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12,
13822 0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42,
13823 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13, 0x03, 0xb6, 0x1e, 0xfe,
13824 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a,
13825 0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68,
13826 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x03, 0x9a, 0x1e, 0xfe,
13827 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06,
13828 0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00,
13829 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17, 0xfe, 0xea, 0x06, 0x01,
13830 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15,
13831 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae,
13832 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a, 0x1e, 0xfe, 0x1a, 0x12,
13833 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80,
13834 0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6,
13835 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x17, 0xfe,
13836 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01,
13837 0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05,
13838 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0x9c, 0x32, 0x5f,
13839 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe,
13840 0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29,
13841 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14,
13842 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe,
13843 0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13,
13844 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
13845 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe,
13846 0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c,
13847 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x53, 0x63, 0x4e,
13848 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0,
13849 0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c,
13850 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe, 0x1e, 0xfe, 0x99, 0x58,
13851 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c,
13852 0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a,
13853 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40, 0x01, 0x0c, 0x61, 0x65,
13854 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50,
13855 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e,
13856 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e, 0x01, 0xfe, 0xfe, 0x1e,
13857 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06,
13858 0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b,
13859 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04, 0xfe, 0x9f, 0x83, 0x33,
13860 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6,
13861 0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e,
13862 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90, 0x04, 0xfe, 0xc0, 0x93,
13863 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c,
13864 0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
13865 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
13866 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a,
13867 0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41,
13868 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07, 0xfe, 0x14, 0x12, 0x01,
13869 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe,
13870 0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe,
13871 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe, 0x92, 0x10, 0xc4, 0xf6,
13872 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b,
13873 0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0,
13874 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07, 0x1b, 0xbf, 0xd4, 0x5b,
13875 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f,
13876 0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74,
13877 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78, 0x0f, 0x4d, 0x01, 0xfe,
13878 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2,
13879 0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21,
13880 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe, 0x83, 0x83, 0xfe, 0xc9,
13881 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84,
13882 0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b,
13883 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0x10,
13884 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64,
13885 0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64,
13886 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97, 0x10, 0x98, 0x91, 0x6c,
13887 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01,
13888 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58,
13889 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x01, 0x0c,
13890 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04,
13891 0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe,
13892 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb, 0x01, 0x0c, 0x06, 0x0d,
13893 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d,
13894 0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e,
13895 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41,
13896 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00,
13897 0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51,
13898 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe, 0x76, 0x10, 0xac, 0xfe,
13899 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe,
13900 0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92,
13901 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2, 0x0c, 0xfe, 0x3e, 0x10,
13902 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe,
13903 0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94,
13904 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3, 0xfe, 0xcc, 0xf0, 0xef,
13905 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
13906 0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
13907 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32, 0x2f, 0xfe, 0x3e, 0x0d,
13908 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f,
13909 0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99,
13910 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8, 0x9c, 0x2f, 0xfe, 0x8c,
13911 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70,
13912 0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13,
13913 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b, 0xfe, 0xda, 0x0e, 0x0a,
13914 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4,
13915 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85,
13916 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe, 0xcc, 0x10, 0x01, 0xa7,
13917 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe,
13918 0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2,
13919 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x40, 0x15,
13920 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01,
13921 0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe,
13922 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe,
13923 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44,
13924 0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19,
13925 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19, 0xfe, 0x41, 0x00, 0xa2,
13926 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04,
13927 0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c,
13928 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01, 0xfe, 0xd4, 0x11, 0x05,
13929 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51,
13930 0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56,
13931 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01, 0x0c, 0x06, 0x28, 0xfe,
13932 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe,
13933 0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe,
13934 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x05,
13935 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c,
13936 0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b,
13937 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe, 0xf0, 0x1a, 0x03, 0xfe,
13938 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00,
13939 0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b,
13940 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02, 0xea, 0xe7, 0x53, 0x92,
13941 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23,
13942 0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e,
13943 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02, 0x26, 0x02, 0x21, 0x96,
13944 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10,
13945 0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe,
13946 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe, 0x00, 0xcc, 0x02, 0xfe,
13947 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80,
13948 0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80,
13949 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe, 0x1d, 0x80, 0x04, 0xfe,
13950 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14,
13951 0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4,
13952 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09, 0x56, 0xfb, 0x01, 0xfe,
13953 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15,
13954 0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e,
13955 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe, 0x96, 0x90, 0x04, 0xfe,
13956 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06,
13957 0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01,
13958 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40, 0x21, 0x2c, 0xfe, 0x00,
13959 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe,
13960 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00,
13961 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10, 0x66, 0x10, 0x55, 0x10,
13962 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88,
13963 0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe,
13964 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c,
13965 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe,
13966 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47,
13967 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01, 0xa7, 0x90, 0x34, 0x60,
13968 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34,
13969 0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
13970 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a,
13971 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe,
13972 0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e,
13973 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01, 0xf4, 0xfe, 0xdd, 0x10,
13974 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe,
13975 0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23,
13976 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09, 0x24, 0xfe, 0x12, 0x12,
13977 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32,
13978 0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43,
13979 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80, 0x13, 0x01, 0x0c, 0x06,
13980 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe,
13981 0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10,
13982 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49, 0x88, 0x20, 0x6e, 0x01,
13983 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa,
13984 0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe,
13985 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe, 0xe5,
13986 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01,
13987 0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50,
13988 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50, 0x03, 0x68, 0x3b,
13989 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2,
13990 0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25,
13991 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01, 0xa6, 0x23, 0x3f, 0x1b,
13992 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31,
13993 0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01,
13994 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0,
13995 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05,
13996 0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08,
13997 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03, 0xb6, 0x1e, 0x83, 0x01,
13998 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01,
13999 0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82,
14000 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e, 0x05, 0x72, 0xfe, 0xc0,
14001 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17,
14002 0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd,
14003 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe, 0xe8, 0x14, 0x01, 0xa6,
14004 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43,
14005 0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73,
14006 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd, 0x09,
14007 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8,
14008 0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72,
14009 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0xc0, 0x19, 0x05,
14010 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26,
14011 0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32,
14012 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0xfe, 0xff,
14013 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad,
14014 0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
14015 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e, 0x02, 0x13, 0x58, 0xff,
14016 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01,
14017 0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54,
14018 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07, 0x7c, 0x3a, 0x0b, 0x0e,
14019 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00,
14020 0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe,
14021 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77, 0x02, 0x01, 0xc6, 0xfe,
14022 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08,
14023 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe,
14024 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12, 0x48, 0xfe, 0x08, 0x17,
14025 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07,
14026 0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55,
14027 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x1c, 0x63, 0x13,
14028 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80,
14029 0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60,
14030 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8, 0x00, 0x1c, 0x95, 0x13,
14031 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96,
14032 0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b,
14033 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x49,
14034 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe,
14035 0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13,
14036 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xbe, 0xfe, 0x03,
14037 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16,
14038 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9,
14039 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27,
14040 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24,
14041 0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e,
14042 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10, 0xfe, 0x40, 0x5a, 0x23,
14043 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa,
14044 0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
14045 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe, 0x43, 0x48, 0x2d, 0x93,
14046 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4,
14047 0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0,
14048 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa, 0x18, 0x45, 0xfe, 0x1c,
14049 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4,
14050 0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01,
14051 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe, 0x7e, 0x01, 0xfe, 0xc8,
14052 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01,
14053 0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14,
14054 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14,
14055 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07,
14056 0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
14057 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01, 0x08, 0x02, 0x50, 0x02,
14058 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08,
14059 0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe,
14060 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17, 0x74, 0x5f, 0xcc, 0x01,
14061 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00,
14062 0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f,
14063 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13, 0x16, 0xfe, 0x64, 0x1a,
14064 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02,
14065 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01,
14066 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa, 0xfe, 0x80, 0xe7, 0x1a,
14067 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18,
14068 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80,
14069 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x0a,
14070 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
14071 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3,
14072 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe, 0xf4, 0x1a, 0xfe, 0xfa,
14073 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03,
14074 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07,
14075 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x24, 0xb1, 0xfe,
14076 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c,
14077 0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1,
14078 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe, 0xaf, 0x19, 0xfe, 0x98,
14079 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f,
14080 0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04,
14081 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a, 0x7c, 0x12, 0xfe, 0x0f,
14082 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b,
14083 0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe,
14084 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee, 0x1b, 0xfe, 0x36, 0x14,
14085 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a,
14086 0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45,
14087 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe, 0x39, 0xf0, 0x75, 0x26,
14088 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe,
14089 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13,
14090 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe,
14091 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb,
14092 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01,
14093 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14, 0x56,
14094 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15,
14095 0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80,
14096 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90,
14097 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20,
14098 0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44,
14099 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09, 0x1a, 0xa4, 0x0a, 0x67,
14100 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52,
14101 0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b,
14102 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10, 0xfe, 0x4e, 0xe4, 0xfe,
14103 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03,
14104 0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1,
14105 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe,
14106 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a,
14107 0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8,
14108 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe, 0x1a, 0x10, 0x09, 0x0d,
14109 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42,
14110 0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08,
14111 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e, 0xfe, 0x82, 0xf0, 0xfe,
14112 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18,
14113 0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82,
14114 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86, 0x83, 0x33, 0x0b, 0x0e,
14115 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04,
14116 0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80,
14117 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04, 0xfe, 0x99, 0x83, 0xfe,
14118 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47,
14119 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
14120 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x08, 0x90, 0x04,
14121 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79,
14122 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
14123 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x3c, 0x90, 0x04,
14124 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83,
14125 0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
14128 STATIC unsigned short _adv_asc38C1600_size =
14129 sizeof(_adv_asc38C1600_buf); /* 0x1673 */
14130 STATIC ADV_DCNT _adv_asc38C1600_chksum =
14131 0x0604EF77UL; /* Expanded little-endian checksum. */
14133 /* a_init.c */
14135 * EEPROM Configuration.
14137 * All drivers should use this structure to set the default EEPROM
14138 * configuration. The BIOS now uses this structure when it is built.
14139 * Additional structure information can be found in a_condor.h where
14140 * the structure is defined.
14142 * The *_Field_IsChar structs are needed to correct for endianness.
14143 * These values are read from the board 16 bits at a time directly
14144 * into the structs. Because some fields are char, the values will be
14145 * in the wrong order. The *_Field_IsChar tells when to flip the
14146 * bytes. Data read and written to PCI memory is automatically swapped
14147 * on big-endian platforms so char fields read as words are actually being
14148 * unswapped on big-endian platforms.
14150 STATIC ADVEEP_3550_CONFIG
14151 Default_3550_EEPROM_Config __initdata = {
14152 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
14153 0x0000, /* cfg_msw */
14154 0xFFFF, /* disc_enable */
14155 0xFFFF, /* wdtr_able */
14156 0xFFFF, /* sdtr_able */
14157 0xFFFF, /* start_motor */
14158 0xFFFF, /* tagqng_able */
14159 0xFFFF, /* bios_scan */
14160 0, /* scam_tolerant */
14161 7, /* adapter_scsi_id */
14162 0, /* bios_boot_delay */
14163 3, /* scsi_reset_delay */
14164 0, /* bios_id_lun */
14165 0, /* termination */
14166 0, /* reserved1 */
14167 0xFFE7, /* bios_ctrl */
14168 0xFFFF, /* ultra_able */
14169 0, /* reserved2 */
14170 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
14171 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
14172 0, /* dvc_cntl */
14173 0, /* bug_fix */
14174 0, /* serial_number_word1 */
14175 0, /* serial_number_word2 */
14176 0, /* serial_number_word3 */
14177 0, /* check_sum */
14178 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* oem_name[16] */
14179 0, /* dvc_err_code */
14180 0, /* adv_err_code */
14181 0, /* adv_err_addr */
14182 0, /* saved_dvc_err_code */
14183 0, /* saved_adv_err_code */
14184 0, /* saved_adv_err_addr */
14185 0 /* num_of_err */
14188 STATIC ADVEEP_3550_CONFIG
14189 ADVEEP_3550_Config_Field_IsChar __initdata = {
14190 0, /* cfg_lsw */
14191 0, /* cfg_msw */
14192 0, /* -disc_enable */
14193 0, /* wdtr_able */
14194 0, /* sdtr_able */
14195 0, /* start_motor */
14196 0, /* tagqng_able */
14197 0, /* bios_scan */
14198 0, /* scam_tolerant */
14199 1, /* adapter_scsi_id */
14200 1, /* bios_boot_delay */
14201 1, /* scsi_reset_delay */
14202 1, /* bios_id_lun */
14203 1, /* termination */
14204 1, /* reserved1 */
14205 0, /* bios_ctrl */
14206 0, /* ultra_able */
14207 0, /* reserved2 */
14208 1, /* max_host_qng */
14209 1, /* max_dvc_qng */
14210 0, /* dvc_cntl */
14211 0, /* bug_fix */
14212 0, /* serial_number_word1 */
14213 0, /* serial_number_word2 */
14214 0, /* serial_number_word3 */
14215 0, /* check_sum */
14216 { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* oem_name[16] */
14217 0, /* dvc_err_code */
14218 0, /* adv_err_code */
14219 0, /* adv_err_addr */
14220 0, /* saved_dvc_err_code */
14221 0, /* saved_adv_err_code */
14222 0, /* saved_adv_err_addr */
14223 0 /* num_of_err */
14226 STATIC ADVEEP_38C0800_CONFIG
14227 Default_38C0800_EEPROM_Config __initdata = {
14228 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
14229 0x0000, /* 01 cfg_msw */
14230 0xFFFF, /* 02 disc_enable */
14231 0xFFFF, /* 03 wdtr_able */
14232 0x4444, /* 04 sdtr_speed1 */
14233 0xFFFF, /* 05 start_motor */
14234 0xFFFF, /* 06 tagqng_able */
14235 0xFFFF, /* 07 bios_scan */
14236 0, /* 08 scam_tolerant */
14237 7, /* 09 adapter_scsi_id */
14238 0, /* bios_boot_delay */
14239 3, /* 10 scsi_reset_delay */
14240 0, /* bios_id_lun */
14241 0, /* 11 termination_se */
14242 0, /* termination_lvd */
14243 0xFFE7, /* 12 bios_ctrl */
14244 0x4444, /* 13 sdtr_speed2 */
14245 0x4444, /* 14 sdtr_speed3 */
14246 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
14247 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
14248 0, /* 16 dvc_cntl */
14249 0x4444, /* 17 sdtr_speed4 */
14250 0, /* 18 serial_number_word1 */
14251 0, /* 19 serial_number_word2 */
14252 0, /* 20 serial_number_word3 */
14253 0, /* 21 check_sum */
14254 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */
14255 0, /* 30 dvc_err_code */
14256 0, /* 31 adv_err_code */
14257 0, /* 32 adv_err_addr */
14258 0, /* 33 saved_dvc_err_code */
14259 0, /* 34 saved_adv_err_code */
14260 0, /* 35 saved_adv_err_addr */
14261 0, /* 36 reserved */
14262 0, /* 37 reserved */
14263 0, /* 38 reserved */
14264 0, /* 39 reserved */
14265 0, /* 40 reserved */
14266 0, /* 41 reserved */
14267 0, /* 42 reserved */
14268 0, /* 43 reserved */
14269 0, /* 44 reserved */
14270 0, /* 45 reserved */
14271 0, /* 46 reserved */
14272 0, /* 47 reserved */
14273 0, /* 48 reserved */
14274 0, /* 49 reserved */
14275 0, /* 50 reserved */
14276 0, /* 51 reserved */
14277 0, /* 52 reserved */
14278 0, /* 53 reserved */
14279 0, /* 54 reserved */
14280 0, /* 55 reserved */
14281 0, /* 56 cisptr_lsw */
14282 0, /* 57 cisprt_msw */
14283 ADV_PCI_VENDOR_ID, /* 58 subsysvid */
14284 ADV_PCI_DEVID_38C0800_REV1, /* 59 subsysid */
14285 0, /* 60 reserved */
14286 0, /* 61 reserved */
14287 0, /* 62 reserved */
14288 0 /* 63 reserved */
14291 STATIC ADVEEP_38C0800_CONFIG
14292 ADVEEP_38C0800_Config_Field_IsChar __initdata = {
14293 0, /* 00 cfg_lsw */
14294 0, /* 01 cfg_msw */
14295 0, /* 02 disc_enable */
14296 0, /* 03 wdtr_able */
14297 0, /* 04 sdtr_speed1 */
14298 0, /* 05 start_motor */
14299 0, /* 06 tagqng_able */
14300 0, /* 07 bios_scan */
14301 0, /* 08 scam_tolerant */
14302 1, /* 09 adapter_scsi_id */
14303 1, /* bios_boot_delay */
14304 1, /* 10 scsi_reset_delay */
14305 1, /* bios_id_lun */
14306 1, /* 11 termination_se */
14307 1, /* termination_lvd */
14308 0, /* 12 bios_ctrl */
14309 0, /* 13 sdtr_speed2 */
14310 0, /* 14 sdtr_speed3 */
14311 1, /* 15 max_host_qng */
14312 1, /* max_dvc_qng */
14313 0, /* 16 dvc_cntl */
14314 0, /* 17 sdtr_speed4 */
14315 0, /* 18 serial_number_word1 */
14316 0, /* 19 serial_number_word2 */
14317 0, /* 20 serial_number_word3 */
14318 0, /* 21 check_sum */
14319 { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* 22-29 oem_name[16] */
14320 0, /* 30 dvc_err_code */
14321 0, /* 31 adv_err_code */
14322 0, /* 32 adv_err_addr */
14323 0, /* 33 saved_dvc_err_code */
14324 0, /* 34 saved_adv_err_code */
14325 0, /* 35 saved_adv_err_addr */
14326 0, /* 36 reserved */
14327 0, /* 37 reserved */
14328 0, /* 38 reserved */
14329 0, /* 39 reserved */
14330 0, /* 40 reserved */
14331 0, /* 41 reserved */
14332 0, /* 42 reserved */
14333 0, /* 43 reserved */
14334 0, /* 44 reserved */
14335 0, /* 45 reserved */
14336 0, /* 46 reserved */
14337 0, /* 47 reserved */
14338 0, /* 48 reserved */
14339 0, /* 49 reserved */
14340 0, /* 50 reserved */
14341 0, /* 51 reserved */
14342 0, /* 52 reserved */
14343 0, /* 53 reserved */
14344 0, /* 54 reserved */
14345 0, /* 55 reserved */
14346 0, /* 56 cisptr_lsw */
14347 0, /* 57 cisprt_msw */
14348 0, /* 58 subsysvid */
14349 0, /* 59 subsysid */
14350 0, /* 60 reserved */
14351 0, /* 61 reserved */
14352 0, /* 62 reserved */
14353 0 /* 63 reserved */
14356 STATIC ADVEEP_38C1600_CONFIG
14357 Default_38C1600_EEPROM_Config __initdata = {
14358 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
14359 0x0000, /* 01 cfg_msw */
14360 0xFFFF, /* 02 disc_enable */
14361 0xFFFF, /* 03 wdtr_able */
14362 0x5555, /* 04 sdtr_speed1 */
14363 0xFFFF, /* 05 start_motor */
14364 0xFFFF, /* 06 tagqng_able */
14365 0xFFFF, /* 07 bios_scan */
14366 0, /* 08 scam_tolerant */
14367 7, /* 09 adapter_scsi_id */
14368 0, /* bios_boot_delay */
14369 3, /* 10 scsi_reset_delay */
14370 0, /* bios_id_lun */
14371 0, /* 11 termination_se */
14372 0, /* termination_lvd */
14373 0xFFE7, /* 12 bios_ctrl */
14374 0x5555, /* 13 sdtr_speed2 */
14375 0x5555, /* 14 sdtr_speed3 */
14376 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
14377 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
14378 0, /* 16 dvc_cntl */
14379 0x5555, /* 17 sdtr_speed4 */
14380 0, /* 18 serial_number_word1 */
14381 0, /* 19 serial_number_word2 */
14382 0, /* 20 serial_number_word3 */
14383 0, /* 21 check_sum */
14384 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */
14385 0, /* 30 dvc_err_code */
14386 0, /* 31 adv_err_code */
14387 0, /* 32 adv_err_addr */
14388 0, /* 33 saved_dvc_err_code */
14389 0, /* 34 saved_adv_err_code */
14390 0, /* 35 saved_adv_err_addr */
14391 0, /* 36 reserved */
14392 0, /* 37 reserved */
14393 0, /* 38 reserved */
14394 0, /* 39 reserved */
14395 0, /* 40 reserved */
14396 0, /* 41 reserved */
14397 0, /* 42 reserved */
14398 0, /* 43 reserved */
14399 0, /* 44 reserved */
14400 0, /* 45 reserved */
14401 0, /* 46 reserved */
14402 0, /* 47 reserved */
14403 0, /* 48 reserved */
14404 0, /* 49 reserved */
14405 0, /* 50 reserved */
14406 0, /* 51 reserved */
14407 0, /* 52 reserved */
14408 0, /* 53 reserved */
14409 0, /* 54 reserved */
14410 0, /* 55 reserved */
14411 0, /* 56 cisptr_lsw */
14412 0, /* 57 cisprt_msw */
14413 ADV_PCI_VENDOR_ID, /* 58 subsysvid */
14414 ADV_PCI_DEVID_38C1600_REV1, /* 59 subsysid */
14415 0, /* 60 reserved */
14416 0, /* 61 reserved */
14417 0, /* 62 reserved */
14418 0 /* 63 reserved */
14421 STATIC ADVEEP_38C1600_CONFIG
14422 ADVEEP_38C1600_Config_Field_IsChar __initdata = {
14423 0, /* 00 cfg_lsw */
14424 0, /* 01 cfg_msw */
14425 0, /* 02 disc_enable */
14426 0, /* 03 wdtr_able */
14427 0, /* 04 sdtr_speed1 */
14428 0, /* 05 start_motor */
14429 0, /* 06 tagqng_able */
14430 0, /* 07 bios_scan */
14431 0, /* 08 scam_tolerant */
14432 1, /* 09 adapter_scsi_id */
14433 1, /* bios_boot_delay */
14434 1, /* 10 scsi_reset_delay */
14435 1, /* bios_id_lun */
14436 1, /* 11 termination_se */
14437 1, /* termination_lvd */
14438 0, /* 12 bios_ctrl */
14439 0, /* 13 sdtr_speed2 */
14440 0, /* 14 sdtr_speed3 */
14441 1, /* 15 max_host_qng */
14442 1, /* max_dvc_qng */
14443 0, /* 16 dvc_cntl */
14444 0, /* 17 sdtr_speed4 */
14445 0, /* 18 serial_number_word1 */
14446 0, /* 19 serial_number_word2 */
14447 0, /* 20 serial_number_word3 */
14448 0, /* 21 check_sum */
14449 { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* 22-29 oem_name[16] */
14450 0, /* 30 dvc_err_code */
14451 0, /* 31 adv_err_code */
14452 0, /* 32 adv_err_addr */
14453 0, /* 33 saved_dvc_err_code */
14454 0, /* 34 saved_adv_err_code */
14455 0, /* 35 saved_adv_err_addr */
14456 0, /* 36 reserved */
14457 0, /* 37 reserved */
14458 0, /* 38 reserved */
14459 0, /* 39 reserved */
14460 0, /* 40 reserved */
14461 0, /* 41 reserved */
14462 0, /* 42 reserved */
14463 0, /* 43 reserved */
14464 0, /* 44 reserved */
14465 0, /* 45 reserved */
14466 0, /* 46 reserved */
14467 0, /* 47 reserved */
14468 0, /* 48 reserved */
14469 0, /* 49 reserved */
14470 0, /* 50 reserved */
14471 0, /* 51 reserved */
14472 0, /* 52 reserved */
14473 0, /* 53 reserved */
14474 0, /* 54 reserved */
14475 0, /* 55 reserved */
14476 0, /* 56 cisptr_lsw */
14477 0, /* 57 cisprt_msw */
14478 0, /* 58 subsysvid */
14479 0, /* 59 subsysid */
14480 0, /* 60 reserved */
14481 0, /* 61 reserved */
14482 0, /* 62 reserved */
14483 0 /* 63 reserved */
14487 * Initialize the ADV_DVC_VAR structure.
14489 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14491 * For a non-fatal error return a warning code. If there are no warnings
14492 * then 0 is returned.
14494 STATIC int __init
14495 AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
14497 ushort warn_code;
14498 AdvPortAddr iop_base;
14499 uchar pci_cmd_reg;
14500 int status;
14502 warn_code = 0;
14503 asc_dvc->err_code = 0;
14504 iop_base = asc_dvc->iop_base;
14507 * PCI Command Register
14509 * Note: AscPCICmdRegBits_BusMastering definition (0x0007) includes
14510 * I/O Space Control, Memory Space Control and Bus Master Control bits.
14513 if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
14514 AscPCIConfigCommandRegister))
14515 & AscPCICmdRegBits_BusMastering)
14516 != AscPCICmdRegBits_BusMastering)
14518 pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
14520 DvcAdvWritePCIConfigByte(asc_dvc,
14521 AscPCIConfigCommandRegister, pci_cmd_reg);
14523 if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister))
14524 & AscPCICmdRegBits_BusMastering)
14525 != AscPCICmdRegBits_BusMastering)
14527 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14532 * PCI Latency Timer
14534 * If the "latency timer" register is 0x20 or above, then we don't need
14535 * to change it. Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
14536 * comes up less than 0x20).
14538 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
14539 DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer, 0x20);
14540 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20)
14542 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14547 * Save the state of the PCI Configuration Command Register
14548 * "Parity Error Response Control" Bit. If the bit is clear (0),
14549 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
14550 * DMA parity errors.
14552 asc_dvc->cfg->control_flag = 0;
14553 if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
14554 & AscPCICmdRegBits_ParErrRespCtrl)) == 0)
14556 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
14559 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
14560 ADV_LIB_VERSION_MINOR;
14561 asc_dvc->cfg->chip_version =
14562 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
14564 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
14565 (ushort) AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
14566 (ushort) ADV_CHIP_ID_BYTE);
14568 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
14569 (ushort) AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
14570 (ushort) ADV_CHIP_ID_WORD);
14573 * Reset the chip to start and allow register writes.
14575 if (AdvFindSignature(iop_base) == 0)
14577 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
14578 return ADV_ERROR;
14580 else {
14582 * The caller must set 'chip_type' to a valid setting.
14584 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
14585 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
14586 asc_dvc->chip_type != ADV_CHIP_ASC38C1600)
14588 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14589 return ADV_ERROR;
14593 * Reset Chip.
14595 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14596 ADV_CTRL_REG_CMD_RESET);
14597 DvcSleepMilliSecond(100);
14598 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14599 ADV_CTRL_REG_CMD_WR_IO_REG);
14601 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
14603 if ((status = AdvInitFrom38C1600EEP(asc_dvc)) == ADV_ERROR)
14605 return ADV_ERROR;
14607 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
14609 if ((status = AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR)
14611 return ADV_ERROR;
14613 } else
14615 if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR)
14617 return ADV_ERROR;
14620 warn_code |= status;
14623 return warn_code;
14627 * Initialize the ASC-3550.
14629 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14631 * For a non-fatal error return a warning code. If there are no warnings
14632 * then 0 is returned.
14634 * Needed after initialization for error recovery.
14636 STATIC int
14637 AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
14639 AdvPortAddr iop_base;
14640 ushort warn_code;
14641 ADV_DCNT sum;
14642 int begin_addr;
14643 int end_addr;
14644 ushort code_sum;
14645 int word;
14646 int j;
14647 int adv_asc3550_expanded_size;
14648 ADV_CARR_T *carrp;
14649 ADV_DCNT contig_len;
14650 ADV_SDCNT buf_size;
14651 ADV_PADDR carr_paddr;
14652 int i;
14653 ushort scsi_cfg1;
14654 uchar tid;
14655 ushort bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
14656 ushort wdtr_able = 0, sdtr_able, tagqng_able;
14657 uchar max_cmd[ADV_MAX_TID + 1];
14659 /* If there is already an error, don't continue. */
14660 if (asc_dvc->err_code != 0)
14662 return ADV_ERROR;
14666 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
14668 if (asc_dvc->chip_type != ADV_CHIP_ASC3550)
14670 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14671 return ADV_ERROR;
14674 warn_code = 0;
14675 iop_base = asc_dvc->iop_base;
14678 * Save the RISC memory BIOS region before writing the microcode.
14679 * The BIOS may already be loaded and using its RISC LRAM region
14680 * so its region must be saved and restored.
14682 * Note: This code makes the assumption, which is currently true,
14683 * that a chip reset does not clear RISC LRAM.
14685 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
14687 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
14691 * Save current per TID negotiated values.
14693 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
14695 ushort bios_version, major, minor;
14697 bios_version = bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM)/2];
14698 major = (bios_version >> 12) & 0xF;
14699 minor = (bios_version >> 8) & 0xF;
14700 if (major < 3 || (major == 3 && minor == 1))
14702 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
14703 AdvReadWordLram(iop_base, 0x120, wdtr_able);
14704 } else
14706 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14709 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14710 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14711 for (tid = 0; tid <= ADV_MAX_TID; tid++)
14713 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14714 max_cmd[tid]);
14718 * Load the Microcode
14720 * Write the microcode image to RISC memory starting at address 0.
14722 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14723 /* Assume the following compressed format of the microcode buffer:
14725 * 254 word (508 byte) table indexed by byte code followed
14726 * by the following byte codes:
14728 * 1-Byte Code:
14729 * 00: Emit word 0 in table.
14730 * 01: Emit word 1 in table.
14732 * FD: Emit word 253 in table.
14734 * Multi-Byte Code:
14735 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14736 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14738 word = 0;
14739 for (i = 253 * 2; i < _adv_asc3550_size; i++)
14741 if (_adv_asc3550_buf[i] == 0xff)
14743 for (j = 0; j < _adv_asc3550_buf[i + 1]; j++)
14745 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14746 _adv_asc3550_buf[i + 3] << 8) |
14747 _adv_asc3550_buf[i + 2]));
14748 word++;
14750 i += 3;
14751 } else if (_adv_asc3550_buf[i] == 0xfe)
14753 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14754 _adv_asc3550_buf[i + 2] << 8) |
14755 _adv_asc3550_buf[i + 1]));
14756 i += 2;
14757 word++;
14758 } else
14760 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14761 _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) |
14762 _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
14763 word++;
14768 * Set 'word' for later use to clear the rest of memory and save
14769 * the expanded mcode size.
14771 word *= 2;
14772 adv_asc3550_expanded_size = word;
14775 * Clear the rest of ASC-3550 Internal RAM (8KB).
14777 for (; word < ADV_3550_MEMSIZE; word += 2)
14779 AdvWriteWordAutoIncLram(iop_base, 0);
14783 * Verify the microcode checksum.
14785 sum = 0;
14786 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14788 for (word = 0; word < adv_asc3550_expanded_size; word += 2)
14790 sum += AdvReadWordAutoIncLram(iop_base);
14793 if (sum != _adv_asc3550_chksum)
14795 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14796 return ADV_ERROR;
14800 * Restore the RISC memory BIOS region.
14802 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
14804 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
14808 * Calculate and write the microcode code checksum to the microcode
14809 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14811 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14812 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14813 code_sum = 0;
14814 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14815 for (word = begin_addr; word < end_addr; word += 2)
14817 code_sum += AdvReadWordAutoIncLram(iop_base);
14819 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14822 * Read and save microcode version and date.
14824 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
14825 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
14828 * Set the chip type to indicate the ASC3550.
14830 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
14833 * If the PCI Configuration Command Register "Parity Error Response
14834 * Control" Bit was clear (0), then set the microcode variable
14835 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14836 * to ignore DMA parity errors.
14838 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
14840 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14841 word |= CONTROL_FLAG_IGNORE_PERR;
14842 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14846 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
14847 * threshold of 128 bytes. This register is only accessible to the host.
14849 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14850 START_CTL_EMFU | READ_CMD_MRM);
14853 * Microcode operating variables for WDTR, SDTR, and command tag
14854 * queuing will be set in AdvInquiryHandling() based on what a
14855 * device reports it is capable of in Inquiry byte 7.
14857 * If SCSI Bus Resets have been disabled, then directly set
14858 * SDTR and WDTR from the EEPROM configuration. This will allow
14859 * the BIOS and warm boot to work without a SCSI bus hang on
14860 * the Inquiry caused by host and target mismatched DTR values.
14861 * Without the SCSI Bus Reset, before an Inquiry a device can't
14862 * be assumed to be in Asynchronous, Narrow mode.
14864 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
14866 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
14867 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
14871 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
14872 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
14873 * bitmask. These values determine the maximum SDTR speed negotiated
14874 * with a device.
14876 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14877 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14878 * without determining here whether the device supports SDTR.
14880 * 4-bit speed SDTR speed name
14881 * =========== ===============
14882 * 0000b (0x0) SDTR disabled
14883 * 0001b (0x1) 5 Mhz
14884 * 0010b (0x2) 10 Mhz
14885 * 0011b (0x3) 20 Mhz (Ultra)
14886 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
14887 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
14888 * 0110b (0x6) Undefined
14890 * 1111b (0xF) Undefined
14892 word = 0;
14893 for (tid = 0; tid <= ADV_MAX_TID; tid++)
14895 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able)
14897 /* Set Ultra speed for TID 'tid'. */
14898 word |= (0x3 << (4 * (tid % 4)));
14899 } else
14901 /* Set Fast speed for TID 'tid'. */
14902 word |= (0x2 << (4 * (tid % 4)));
14904 if (tid == 3) /* Check if done with sdtr_speed1. */
14906 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
14907 word = 0;
14908 } else if (tid == 7) /* Check if done with sdtr_speed2. */
14910 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
14911 word = 0;
14912 } else if (tid == 11) /* Check if done with sdtr_speed3. */
14914 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
14915 word = 0;
14916 } else if (tid == 15) /* Check if done with sdtr_speed4. */
14918 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
14919 /* End of loop. */
14924 * Set microcode operating variable for the disconnect per TID bitmask.
14926 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
14929 * Set SCSI_CFG0 Microcode Default Value.
14931 * The microcode will set the SCSI_CFG0 register using this value
14932 * after it is started below.
14934 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14935 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14936 asc_dvc->chip_scsi_id);
14939 * Determine SCSI_CFG1 Microcode Default Value.
14941 * The microcode will set the SCSI_CFG1 register using this value
14942 * after it is started below.
14945 /* Read current SCSI_CFG1 Register value. */
14946 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14949 * If all three connectors are in use, return an error.
14951 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
14952 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0)
14954 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
14955 return ADV_ERROR;
14959 * If the internal narrow cable is reversed all of the SCSI_CTRL
14960 * register signals will be set. Check for and return an error if
14961 * this condition is found.
14963 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
14965 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14966 return ADV_ERROR;
14970 * If this is a differential board and a single-ended device
14971 * is attached to one of the connectors, return an error.
14973 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0)
14975 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
14976 return ADV_ERROR;
14980 * If automatic termination control is enabled, then set the
14981 * termination value based on a table listed in a_condor.h.
14983 * If manual termination was specified with an EEPROM setting
14984 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
14985 * is ready to be 'ored' into SCSI_CFG1.
14987 if (asc_dvc->cfg->termination == 0)
14990 * The software always controls termination by setting TERM_CTL_SEL.
14991 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
14993 asc_dvc->cfg->termination |= TERM_CTL_SEL;
14995 switch(scsi_cfg1 & CABLE_DETECT)
14997 /* TERM_CTL_H: on, TERM_CTL_L: on */
14998 case 0x3: case 0x7: case 0xB: case 0xD: case 0xE: case 0xF:
14999 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
15000 break;
15002 /* TERM_CTL_H: on, TERM_CTL_L: off */
15003 case 0x1: case 0x5: case 0x9: case 0xA: case 0xC:
15004 asc_dvc->cfg->termination |= TERM_CTL_H;
15005 break;
15007 /* TERM_CTL_H: off, TERM_CTL_L: off */
15008 case 0x2: case 0x6:
15009 break;
15014 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
15016 scsi_cfg1 &= ~TERM_CTL;
15019 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
15020 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
15021 * referenced, because the hardware internally inverts
15022 * the Termination High and Low bits if TERM_POL is set.
15024 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
15027 * Set SCSI_CFG1 Microcode Default Value
15029 * Set filter value and possibly modified termination control
15030 * bits in the Microcode SCSI_CFG1 Register Value.
15032 * The microcode will set the SCSI_CFG1 register using this value
15033 * after it is started below.
15035 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
15036 FLTR_DISABLE | scsi_cfg1);
15039 * Set MEM_CFG Microcode Default Value
15041 * The microcode will set the MEM_CFG register using this value
15042 * after it is started below.
15044 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15045 * are defined.
15047 * ASC-3550 has 8KB internal memory.
15049 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15050 BIOS_EN | RAM_SZ_8KB);
15053 * Set SEL_MASK Microcode Default Value
15055 * The microcode will set the SEL_MASK register using this value
15056 * after it is started below.
15058 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15059 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15062 * Build carrier freelist.
15064 * Driver must have already allocated memory and set 'carrier_buf'.
15066 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15068 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15069 asc_dvc->carr_freelist = NULL;
15070 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
15072 buf_size = ADV_CARRIER_BUFSIZE;
15073 } else
15075 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15078 do {
15080 * Get physical address of the carrier 'carrp'.
15082 contig_len = sizeof(ADV_CARR_T);
15083 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
15084 (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
15086 buf_size -= sizeof(ADV_CARR_T);
15089 * If the current carrier is not physically contiguous, then
15090 * maybe there was a page crossing. Try the next carrier aligned
15091 * start address.
15093 if (contig_len < sizeof(ADV_CARR_T))
15095 carrp++;
15096 continue;
15099 carrp->carr_pa = carr_paddr;
15100 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15103 * Insert the carrier at the beginning of the freelist.
15105 carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15106 asc_dvc->carr_freelist = carrp;
15108 carrp++;
15110 while (buf_size > 0);
15113 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15116 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
15118 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15119 return ADV_ERROR;
15121 asc_dvc->carr_freelist = (ADV_CARR_T *)
15122 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15125 * The first command issued will be placed in the stopper carrier.
15127 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15130 * Set RISC ICQ physical address start value.
15132 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15135 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15137 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
15139 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15140 return ADV_ERROR;
15142 asc_dvc->carr_freelist = (ADV_CARR_T *)
15143 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15146 * The first command completed by the RISC will be placed in
15147 * the stopper.
15149 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15150 * completed the RISC will set the ASC_RQ_STOPPER bit.
15152 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15155 * Set RISC IRQ physical address start value.
15157 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15158 asc_dvc->carr_pending_cnt = 0;
15160 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15161 (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
15163 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15164 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15166 /* finally, finally, gentlemen, start your engine */
15167 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15170 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15171 * Resets should be performed. The RISC has to be running
15172 * to issue a SCSI Bus Reset.
15174 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
15177 * If the BIOS Signature is present in memory, restore the
15178 * BIOS Handshake Configuration Table and do not perform
15179 * a SCSI Bus Reset.
15181 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
15184 * Restore per TID negotiated values.
15186 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15187 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15188 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15189 for (tid = 0; tid <= ADV_MAX_TID; tid++)
15191 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15192 max_cmd[tid]);
15194 } else
15196 if (AdvResetSB(asc_dvc) != ADV_TRUE)
15198 warn_code = ASC_WARN_BUSRESET_ERROR;
15203 return warn_code;
15207 * Initialize the ASC-38C0800.
15209 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15211 * For a non-fatal error return a warning code. If there are no warnings
15212 * then 0 is returned.
15214 * Needed after initialization for error recovery.
15216 STATIC int
15217 AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
15219 AdvPortAddr iop_base;
15220 ushort warn_code;
15221 ADV_DCNT sum;
15222 int begin_addr;
15223 int end_addr;
15224 ushort code_sum;
15225 int word;
15226 int j;
15227 int adv_asc38C0800_expanded_size;
15228 ADV_CARR_T *carrp;
15229 ADV_DCNT contig_len;
15230 ADV_SDCNT buf_size;
15231 ADV_PADDR carr_paddr;
15232 int i;
15233 ushort scsi_cfg1;
15234 uchar byte;
15235 uchar tid;
15236 ushort bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
15237 ushort wdtr_able, sdtr_able, tagqng_able;
15238 uchar max_cmd[ADV_MAX_TID + 1];
15240 /* If there is already an error, don't continue. */
15241 if (asc_dvc->err_code != 0)
15243 return ADV_ERROR;
15247 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
15249 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800)
15251 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
15252 return ADV_ERROR;
15255 warn_code = 0;
15256 iop_base = asc_dvc->iop_base;
15259 * Save the RISC memory BIOS region before writing the microcode.
15260 * The BIOS may already be loaded and using its RISC LRAM region
15261 * so its region must be saved and restored.
15263 * Note: This code makes the assumption, which is currently true,
15264 * that a chip reset does not clear RISC LRAM.
15266 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15268 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15272 * Save current per TID negotiated values.
15274 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15275 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15276 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15277 for (tid = 0; tid <= ADV_MAX_TID; tid++)
15279 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15280 max_cmd[tid]);
15284 * RAM BIST (RAM Built-In Self Test)
15286 * Address : I/O base + offset 0x38h register (byte).
15287 * Function: Bit 7-6(RW) : RAM mode
15288 * Normal Mode : 0x00
15289 * Pre-test Mode : 0x40
15290 * RAM Test Mode : 0x80
15291 * Bit 5 : unused
15292 * Bit 4(RO) : Done bit
15293 * Bit 3-0(RO) : Status
15294 * Host Error : 0x08
15295 * Int_RAM Error : 0x04
15296 * RISC Error : 0x02
15297 * SCSI Error : 0x01
15298 * No Error : 0x00
15300 * Note: RAM BIST code should be put right here, before loading the
15301 * microcode and after saving the RISC memory BIOS region.
15305 * LRAM Pre-test
15307 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15308 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15309 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15310 * to NORMAL_MODE, return an error too.
15312 for (i = 0; i < 2; i++)
15314 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15315 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15316 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15317 if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE)
15319 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15320 return ADV_ERROR;
15323 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15324 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15325 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15326 != NORMAL_VALUE)
15328 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15329 return ADV_ERROR;
15334 * LRAM Test - It takes about 1.5 ms to run through the test.
15336 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15337 * If Done bit not set or Status not 0, save register byte, set the
15338 * err_code, and return an error.
15340 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15341 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
15343 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15344 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0)
15346 /* Get here if Done bit not set or Status not 0. */
15347 asc_dvc->bist_err_code = byte; /* for BIOS display message */
15348 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15349 return ADV_ERROR;
15352 /* We need to reset back to normal mode after LRAM test passes. */
15353 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15356 * Load the Microcode
15358 * Write the microcode image to RISC memory starting at address 0.
15361 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15363 /* Assume the following compressed format of the microcode buffer:
15365 * 254 word (508 byte) table indexed by byte code followed
15366 * by the following byte codes:
15368 * 1-Byte Code:
15369 * 00: Emit word 0 in table.
15370 * 01: Emit word 1 in table.
15372 * FD: Emit word 253 in table.
15374 * Multi-Byte Code:
15375 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15376 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15378 word = 0;
15379 for (i = 253 * 2; i < _adv_asc38C0800_size; i++)
15381 if (_adv_asc38C0800_buf[i] == 0xff)
15383 for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++)
15385 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15386 _adv_asc38C0800_buf[i + 3] << 8) |
15387 _adv_asc38C0800_buf[i + 2]));
15388 word++;
15390 i += 3;
15391 } else if (_adv_asc38C0800_buf[i] == 0xfe)
15393 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15394 _adv_asc38C0800_buf[i + 2] << 8) |
15395 _adv_asc38C0800_buf[i + 1]));
15396 i += 2;
15397 word++;
15398 } else
15400 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15401 _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) |
15402 _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
15403 word++;
15408 * Set 'word' for later use to clear the rest of memory and save
15409 * the expanded mcode size.
15411 word *= 2;
15412 adv_asc38C0800_expanded_size = word;
15415 * Clear the rest of ASC-38C0800 Internal RAM (16KB).
15417 for (; word < ADV_38C0800_MEMSIZE; word += 2)
15419 AdvWriteWordAutoIncLram(iop_base, 0);
15423 * Verify the microcode checksum.
15425 sum = 0;
15426 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15428 for (word = 0; word < adv_asc38C0800_expanded_size; word += 2)
15430 sum += AdvReadWordAutoIncLram(iop_base);
15432 ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
15434 ASC_DBG2(1,
15435 "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
15436 (ulong) sum, (ulong) _adv_asc38C0800_chksum);
15438 if (sum != _adv_asc38C0800_chksum)
15440 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15441 return ADV_ERROR;
15445 * Restore the RISC memory BIOS region.
15447 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15449 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15453 * Calculate and write the microcode code checksum to the microcode
15454 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15456 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15457 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15458 code_sum = 0;
15459 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15460 for (word = begin_addr; word < end_addr; word += 2)
15462 code_sum += AdvReadWordAutoIncLram(iop_base);
15464 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15467 * Read microcode version and date.
15469 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
15470 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
15473 * Set the chip type to indicate the ASC38C0800.
15475 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
15478 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15479 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15480 * cable detection and then we are able to read C_DET[3:0].
15482 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15483 * Microcode Default Value' section below.
15485 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15486 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV);
15489 * If the PCI Configuration Command Register "Parity Error Response
15490 * Control" Bit was clear (0), then set the microcode variable
15491 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15492 * to ignore DMA parity errors.
15494 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
15496 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15497 word |= CONTROL_FLAG_IGNORE_PERR;
15498 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15502 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
15503 * bits for the default FIFO threshold.
15505 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
15507 * For DMA Errata #4 set the BC_THRESH_ENB bit.
15509 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15510 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
15513 * Microcode operating variables for WDTR, SDTR, and command tag
15514 * queuing will be set in AdvInquiryHandling() based on what a
15515 * device reports it is capable of in Inquiry byte 7.
15517 * If SCSI Bus Resets have been disabled, then directly set
15518 * SDTR and WDTR from the EEPROM configuration. This will allow
15519 * the BIOS and warm boot to work without a SCSI bus hang on
15520 * the Inquiry caused by host and target mismatched DTR values.
15521 * Without the SCSI Bus Reset, before an Inquiry a device can't
15522 * be assumed to be in Asynchronous, Narrow mode.
15524 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
15526 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
15527 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
15531 * Set microcode operating variables for DISC and SDTR_SPEED1,
15532 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15533 * configuration values.
15535 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15536 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15537 * without determining here whether the device supports SDTR.
15539 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
15540 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15541 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15542 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15543 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15546 * Set SCSI_CFG0 Microcode Default Value.
15548 * The microcode will set the SCSI_CFG0 register using this value
15549 * after it is started below.
15551 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15552 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15553 asc_dvc->chip_scsi_id);
15556 * Determine SCSI_CFG1 Microcode Default Value.
15558 * The microcode will set the SCSI_CFG1 register using this value
15559 * after it is started below.
15562 /* Read current SCSI_CFG1 Register value. */
15563 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15566 * If the internal narrow cable is reversed all of the SCSI_CTRL
15567 * register signals will be set. Check for and return an error if
15568 * this condition is found.
15570 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
15572 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15573 return ADV_ERROR;
15577 * All kind of combinations of devices attached to one of four connectors
15578 * are acceptable except HVD device attached. For example, LVD device can
15579 * be attached to SE connector while SE device attached to LVD connector.
15580 * If LVD device attached to SE connector, it only runs up to Ultra speed.
15582 * If an HVD device is attached to one of LVD connectors, return an error.
15583 * However, there is no way to detect HVD device attached to SE connectors.
15585 if (scsi_cfg1 & HVD)
15587 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15588 return ADV_ERROR;
15592 * If either SE or LVD automatic termination control is enabled, then
15593 * set the termination value based on a table listed in a_condor.h.
15595 * If manual termination was specified with an EEPROM setting then
15596 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
15597 * be 'ored' into SCSI_CFG1.
15599 if ((asc_dvc->cfg->termination & TERM_SE) == 0)
15601 /* SE automatic termination control is enabled. */
15602 switch(scsi_cfg1 & C_DET_SE)
15604 /* TERM_SE_HI: on, TERM_SE_LO: on */
15605 case 0x1: case 0x2: case 0x3:
15606 asc_dvc->cfg->termination |= TERM_SE;
15607 break;
15609 /* TERM_SE_HI: on, TERM_SE_LO: off */
15610 case 0x0:
15611 asc_dvc->cfg->termination |= TERM_SE_HI;
15612 break;
15616 if ((asc_dvc->cfg->termination & TERM_LVD) == 0)
15618 /* LVD automatic termination control is enabled. */
15619 switch(scsi_cfg1 & C_DET_LVD)
15621 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
15622 case 0x4: case 0x8: case 0xC:
15623 asc_dvc->cfg->termination |= TERM_LVD;
15624 break;
15626 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
15627 case 0x0:
15628 break;
15633 * Clear any set TERM_SE and TERM_LVD bits.
15635 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
15638 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
15640 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
15643 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
15644 * and set possibly modified termination control bits in the Microcode
15645 * SCSI_CFG1 Register Value.
15647 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
15650 * Set SCSI_CFG1 Microcode Default Value
15652 * Set possibly modified termination control and reset DIS_TERM_DRV
15653 * bits in the Microcode SCSI_CFG1 Register Value.
15655 * The microcode will set the SCSI_CFG1 register using this value
15656 * after it is started below.
15658 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15661 * Set MEM_CFG Microcode Default Value
15663 * The microcode will set the MEM_CFG register using this value
15664 * after it is started below.
15666 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15667 * are defined.
15669 * ASC-38C0800 has 16KB internal memory.
15671 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15672 BIOS_EN | RAM_SZ_16KB);
15675 * Set SEL_MASK Microcode Default Value
15677 * The microcode will set the SEL_MASK register using this value
15678 * after it is started below.
15680 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15681 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15684 * Build the carrier freelist.
15686 * Driver must have already allocated memory and set 'carrier_buf'.
15688 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15690 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15691 asc_dvc->carr_freelist = NULL;
15692 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
15694 buf_size = ADV_CARRIER_BUFSIZE;
15695 } else
15697 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15700 do {
15702 * Get physical address for the carrier 'carrp'.
15704 contig_len = sizeof(ADV_CARR_T);
15705 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
15706 (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
15708 buf_size -= sizeof(ADV_CARR_T);
15711 * If the current carrier is not physically contiguous, then
15712 * maybe there was a page crossing. Try the next carrier aligned
15713 * start address.
15715 if (contig_len < sizeof(ADV_CARR_T))
15717 carrp++;
15718 continue;
15721 carrp->carr_pa = carr_paddr;
15722 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15725 * Insert the carrier at the beginning of the freelist.
15727 carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15728 asc_dvc->carr_freelist = carrp;
15730 carrp++;
15732 while (buf_size > 0);
15735 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15738 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
15740 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15741 return ADV_ERROR;
15743 asc_dvc->carr_freelist = (ADV_CARR_T *)
15744 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15747 * The first command issued will be placed in the stopper carrier.
15749 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15752 * Set RISC ICQ physical address start value.
15753 * carr_pa is LE, must be native before write
15755 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15758 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15760 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
15762 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15763 return ADV_ERROR;
15765 asc_dvc->carr_freelist = (ADV_CARR_T *)
15766 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15769 * The first command completed by the RISC will be placed in
15770 * the stopper.
15772 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15773 * completed the RISC will set the ASC_RQ_STOPPER bit.
15775 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15778 * Set RISC IRQ physical address start value.
15780 * carr_pa is LE, must be native before write *
15782 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15783 asc_dvc->carr_pending_cnt = 0;
15785 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15786 (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
15788 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15789 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15791 /* finally, finally, gentlemen, start your engine */
15792 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15795 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15796 * Resets should be performed. The RISC has to be running
15797 * to issue a SCSI Bus Reset.
15799 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
15802 * If the BIOS Signature is present in memory, restore the
15803 * BIOS Handshake Configuration Table and do not perform
15804 * a SCSI Bus Reset.
15806 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
15809 * Restore per TID negotiated values.
15811 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15812 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15813 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15814 for (tid = 0; tid <= ADV_MAX_TID; tid++)
15816 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15817 max_cmd[tid]);
15819 } else
15821 if (AdvResetSB(asc_dvc) != ADV_TRUE)
15823 warn_code = ASC_WARN_BUSRESET_ERROR;
15828 return warn_code;
15832 * Initialize the ASC-38C1600.
15834 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
15836 * For a non-fatal error return a warning code. If there are no warnings
15837 * then 0 is returned.
15839 * Needed after initialization for error recovery.
15841 STATIC int
15842 AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
15844 AdvPortAddr iop_base;
15845 ushort warn_code;
15846 ADV_DCNT sum;
15847 int begin_addr;
15848 int end_addr;
15849 ushort code_sum;
15850 long word;
15851 int j;
15852 int adv_asc38C1600_expanded_size;
15853 ADV_CARR_T *carrp;
15854 ADV_DCNT contig_len;
15855 ADV_SDCNT buf_size;
15856 ADV_PADDR carr_paddr;
15857 int i;
15858 ushort scsi_cfg1;
15859 uchar byte;
15860 uchar tid;
15861 ushort bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
15862 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
15863 uchar max_cmd[ASC_MAX_TID + 1];
15865 /* If there is already an error, don't continue. */
15866 if (asc_dvc->err_code != 0)
15868 return ADV_ERROR;
15872 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
15874 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600)
15876 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
15877 return ADV_ERROR;
15880 warn_code = 0;
15881 iop_base = asc_dvc->iop_base;
15884 * Save the RISC memory BIOS region before writing the microcode.
15885 * The BIOS may already be loaded and using its RISC LRAM region
15886 * so its region must be saved and restored.
15888 * Note: This code makes the assumption, which is currently true,
15889 * that a chip reset does not clear RISC LRAM.
15891 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15893 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15897 * Save current per TID negotiated values.
15899 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15900 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15901 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15902 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15903 for (tid = 0; tid <= ASC_MAX_TID; tid++)
15905 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15906 max_cmd[tid]);
15910 * RAM BIST (Built-In Self Test)
15912 * Address : I/O base + offset 0x38h register (byte).
15913 * Function: Bit 7-6(RW) : RAM mode
15914 * Normal Mode : 0x00
15915 * Pre-test Mode : 0x40
15916 * RAM Test Mode : 0x80
15917 * Bit 5 : unused
15918 * Bit 4(RO) : Done bit
15919 * Bit 3-0(RO) : Status
15920 * Host Error : 0x08
15921 * Int_RAM Error : 0x04
15922 * RISC Error : 0x02
15923 * SCSI Error : 0x01
15924 * No Error : 0x00
15926 * Note: RAM BIST code should be put right here, before loading the
15927 * microcode and after saving the RISC memory BIOS region.
15931 * LRAM Pre-test
15933 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15934 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15935 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15936 * to NORMAL_MODE, return an error too.
15938 for (i = 0; i < 2; i++)
15940 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15941 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15942 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15943 if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE)
15945 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15946 return ADV_ERROR;
15949 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15950 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15951 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15952 != NORMAL_VALUE)
15954 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15955 return ADV_ERROR;
15960 * LRAM Test - It takes about 1.5 ms to run through the test.
15962 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15963 * If Done bit not set or Status not 0, save register byte, set the
15964 * err_code, and return an error.
15966 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15967 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
15969 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15970 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0)
15972 /* Get here if Done bit not set or Status not 0. */
15973 asc_dvc->bist_err_code = byte; /* for BIOS display message */
15974 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15975 return ADV_ERROR;
15978 /* We need to reset back to normal mode after LRAM test passes. */
15979 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15982 * Load the Microcode
15984 * Write the microcode image to RISC memory starting at address 0.
15987 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15990 * Assume the following compressed format of the microcode buffer:
15992 * 254 word (508 byte) table indexed by byte code followed
15993 * by the following byte codes:
15995 * 1-Byte Code:
15996 * 00: Emit word 0 in table.
15997 * 01: Emit word 1 in table.
15999 * FD: Emit word 253 in table.
16001 * Multi-Byte Code:
16002 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
16003 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
16005 word = 0;
16006 for (i = 253 * 2; i < _adv_asc38C1600_size; i++)
16008 if (_adv_asc38C1600_buf[i] == 0xff)
16010 for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++)
16012 AdvWriteWordAutoIncLram(iop_base, (((ushort)
16013 _adv_asc38C1600_buf[i + 3] << 8) |
16014 _adv_asc38C1600_buf[i + 2]));
16015 word++;
16017 i += 3;
16018 } else if (_adv_asc38C1600_buf[i] == 0xfe)
16020 AdvWriteWordAutoIncLram(iop_base, (((ushort)
16021 _adv_asc38C1600_buf[i + 2] << 8) |
16022 _adv_asc38C1600_buf[i + 1]));
16023 i += 2;
16024 word++;
16025 } else
16027 AdvWriteWordAutoIncLram(iop_base, (((ushort)
16028 _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) |
16029 _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
16030 word++;
16035 * Set 'word' for later use to clear the rest of memory and save
16036 * the expanded mcode size.
16038 word *= 2;
16039 adv_asc38C1600_expanded_size = word;
16042 * Clear the rest of ASC-38C1600 Internal RAM (32KB).
16044 for (; word < ADV_38C1600_MEMSIZE; word += 2)
16046 AdvWriteWordAutoIncLram(iop_base, 0);
16050 * Verify the microcode checksum.
16052 sum = 0;
16053 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
16055 for (word = 0; word < adv_asc38C1600_expanded_size; word += 2)
16057 sum += AdvReadWordAutoIncLram(iop_base);
16060 if (sum != _adv_asc38C1600_chksum)
16062 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
16063 return ADV_ERROR;
16067 * Restore the RISC memory BIOS region.
16069 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
16071 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
16075 * Calculate and write the microcode code checksum to the microcode
16076 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
16078 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
16079 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
16080 code_sum = 0;
16081 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
16082 for (word = begin_addr; word < end_addr; word += 2)
16084 code_sum += AdvReadWordAutoIncLram(iop_base);
16086 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
16089 * Read microcode version and date.
16091 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
16092 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
16095 * Set the chip type to indicate the ASC38C1600.
16097 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
16100 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
16101 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
16102 * cable detection and then we are able to read C_DET[3:0].
16104 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
16105 * Microcode Default Value' section below.
16107 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
16108 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV);
16111 * If the PCI Configuration Command Register "Parity Error Response
16112 * Control" Bit was clear (0), then set the microcode variable
16113 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
16114 * to ignore DMA parity errors.
16116 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
16118 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16119 word |= CONTROL_FLAG_IGNORE_PERR;
16120 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16124 * If the BIOS control flag AIPP (Asynchronous Information
16125 * Phase Protection) disable bit is not set, then set the firmware
16126 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
16127 * AIPP checking and encoding.
16129 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0)
16131 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16132 word |= CONTROL_FLAG_ENABLE_AIPP;
16133 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16137 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
16138 * and START_CTL_TH [3:2].
16140 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
16141 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
16144 * Microcode operating variables for WDTR, SDTR, and command tag
16145 * queuing will be set in AdvInquiryHandling() based on what a
16146 * device reports it is capable of in Inquiry byte 7.
16148 * If SCSI Bus Resets have been disabled, then directly set
16149 * SDTR and WDTR from the EEPROM configuration. This will allow
16150 * the BIOS and warm boot to work without a SCSI bus hang on
16151 * the Inquiry caused by host and target mismatched DTR values.
16152 * Without the SCSI Bus Reset, before an Inquiry a device can't
16153 * be assumed to be in Asynchronous, Narrow mode.
16155 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
16157 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
16158 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
16162 * Set microcode operating variables for DISC and SDTR_SPEED1,
16163 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
16164 * configuration values.
16166 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
16167 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
16168 * without determining here whether the device supports SDTR.
16170 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
16171 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
16172 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
16173 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
16174 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
16177 * Set SCSI_CFG0 Microcode Default Value.
16179 * The microcode will set the SCSI_CFG0 register using this value
16180 * after it is started below.
16182 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
16183 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
16184 asc_dvc->chip_scsi_id);
16187 * Calculate SCSI_CFG1 Microcode Default Value.
16189 * The microcode will set the SCSI_CFG1 register using this value
16190 * after it is started below.
16192 * Each ASC-38C1600 function has only two cable detect bits.
16193 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
16195 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
16198 * If the cable is reversed all of the SCSI_CTRL register signals
16199 * will be set. Check for and return an error if this condition is
16200 * found.
16202 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
16204 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
16205 return ADV_ERROR;
16209 * Each ASC-38C1600 function has two connectors. Only an HVD device
16210 * can not be connected to either connector. An LVD device or SE device
16211 * may be connected to either connecor. If an SE device is connected,
16212 * then at most Ultra speed (20 Mhz) can be used on both connectors.
16214 * If an HVD device is attached, return an error.
16216 if (scsi_cfg1 & HVD)
16218 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
16219 return ADV_ERROR;
16223 * Each function in the ASC-38C1600 uses only the SE cable detect and
16224 * termination because there are two connectors for each function. Each
16225 * function may use either LVD or SE mode. Corresponding the SE automatic
16226 * termination control EEPROM bits are used for each function. Each
16227 * function has its own EEPROM. If SE automatic control is enabled for
16228 * the function, then set the termination value based on a table listed
16229 * in a_condor.h.
16231 * If manual termination is specified in the EEPROM for the function,
16232 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
16233 * ready to be 'ored' into SCSI_CFG1.
16235 if ((asc_dvc->cfg->termination & TERM_SE) == 0)
16237 /* SE automatic termination control is enabled. */
16238 switch(scsi_cfg1 & C_DET_SE)
16240 /* TERM_SE_HI: on, TERM_SE_LO: on */
16241 case 0x1: case 0x2: case 0x3:
16242 asc_dvc->cfg->termination |= TERM_SE;
16243 break;
16245 case 0x0:
16246 if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0)
16248 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
16250 else
16252 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
16253 asc_dvc->cfg->termination |= TERM_SE_HI;
16255 break;
16260 * Clear any set TERM_SE bits.
16262 scsi_cfg1 &= ~TERM_SE;
16265 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
16267 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
16270 * Clear Big Endian and Terminator Polarity bits and set possibly
16271 * modified termination control bits in the Microcode SCSI_CFG1
16272 * Register Value.
16274 * Big Endian bit is not used even on big endian machines.
16276 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
16279 * Set SCSI_CFG1 Microcode Default Value
16281 * Set possibly modified termination control bits in the Microcode
16282 * SCSI_CFG1 Register Value.
16284 * The microcode will set the SCSI_CFG1 register using this value
16285 * after it is started below.
16287 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
16290 * Set MEM_CFG Microcode Default Value
16292 * The microcode will set the MEM_CFG register using this value
16293 * after it is started below.
16295 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
16296 * are defined.
16298 * ASC-38C1600 has 32KB internal memory.
16300 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
16301 * out a special 16K Adv Library and Microcode version. After the issue
16302 * resolved, we should turn back to the 32K support. Both a_condor.h and
16303 * mcode.sas files also need to be updated.
16305 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
16306 * BIOS_EN | RAM_SZ_32KB);
16308 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, BIOS_EN | RAM_SZ_16KB);
16311 * Set SEL_MASK Microcode Default Value
16313 * The microcode will set the SEL_MASK register using this value
16314 * after it is started below.
16316 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
16317 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
16320 * Build the carrier freelist.
16322 * Driver must have already allocated memory and set 'carrier_buf'.
16325 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
16327 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
16328 asc_dvc->carr_freelist = NULL;
16329 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
16331 buf_size = ADV_CARRIER_BUFSIZE;
16332 } else
16334 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
16337 do {
16339 * Get physical address for the carrier 'carrp'.
16341 contig_len = sizeof(ADV_CARR_T);
16342 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
16343 (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
16345 buf_size -= sizeof(ADV_CARR_T);
16348 * If the current carrier is not physically contiguous, then
16349 * maybe there was a page crossing. Try the next carrier aligned
16350 * start address.
16352 if (contig_len < sizeof(ADV_CARR_T))
16354 carrp++;
16355 continue;
16358 carrp->carr_pa = carr_paddr;
16359 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
16362 * Insert the carrier at the beginning of the freelist.
16364 carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
16365 asc_dvc->carr_freelist = carrp;
16367 carrp++;
16369 while (buf_size > 0);
16372 * Set-up the Host->RISC Initiator Command Queue (ICQ).
16374 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
16376 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16377 return ADV_ERROR;
16379 asc_dvc->carr_freelist = (ADV_CARR_T *)
16380 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
16383 * The first command issued will be placed in the stopper carrier.
16385 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16388 * Set RISC ICQ physical address start value. Initialize the
16389 * COMMA register to the same value otherwise the RISC will
16390 * prematurely detect a command is available.
16392 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
16393 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
16394 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
16397 * Set-up the RISC->Host Initiator Response Queue (IRQ).
16399 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
16401 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16402 return ADV_ERROR;
16404 asc_dvc->carr_freelist = (ADV_CARR_T *)
16405 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
16408 * The first command completed by the RISC will be placed in
16409 * the stopper.
16411 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
16412 * completed the RISC will set the ASC_RQ_STOPPER bit.
16414 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16417 * Set RISC IRQ physical address start value.
16419 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
16420 asc_dvc->carr_pending_cnt = 0;
16422 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
16423 (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
16424 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
16425 AdvWriteWordRegister(iop_base, IOPW_PC, word);
16427 /* finally, finally, gentlemen, start your engine */
16428 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
16431 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
16432 * Resets should be performed. The RISC has to be running
16433 * to issue a SCSI Bus Reset.
16435 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
16438 * If the BIOS Signature is present in memory, restore the
16439 * per TID microcode operating variables.
16441 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
16444 * Restore per TID negotiated values.
16446 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16447 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16448 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16449 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16450 for (tid = 0; tid <= ASC_MAX_TID; tid++)
16452 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16453 max_cmd[tid]);
16455 } else
16457 if (AdvResetSB(asc_dvc) != ADV_TRUE)
16459 warn_code = ASC_WARN_BUSRESET_ERROR;
16464 return warn_code;
16468 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16469 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16470 * all of this is done.
16472 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16474 * For a non-fatal error return a warning code. If there are no warnings
16475 * then 0 is returned.
16477 * Note: Chip is stopped on entry.
16479 STATIC int __init
16480 AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
16482 AdvPortAddr iop_base;
16483 ushort warn_code;
16484 ADVEEP_3550_CONFIG eep_config;
16485 int i;
16487 iop_base = asc_dvc->iop_base;
16489 warn_code = 0;
16492 * Read the board's EEPROM configuration.
16494 * Set default values if a bad checksum is found.
16496 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16498 warn_code |= ASC_WARN_EEPROM_CHKSUM;
16501 * Set EEPROM default values.
16503 for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++)
16505 *((uchar *) &eep_config + i) =
16506 *((uchar *) &Default_3550_EEPROM_Config + i);
16510 * Assume the 6 byte board serial number that was read
16511 * from EEPROM is correct even if the EEPROM checksum
16512 * failed.
16514 eep_config.serial_number_word3 =
16515 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16517 eep_config.serial_number_word2 =
16518 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16520 eep_config.serial_number_word1 =
16521 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16523 AdvSet3550EEPConfig(iop_base, &eep_config);
16526 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16527 * EEPROM configuration that was read.
16529 * This is the mapping of EEPROM fields to Adv Library fields.
16531 asc_dvc->wdtr_able = eep_config.wdtr_able;
16532 asc_dvc->sdtr_able = eep_config.sdtr_able;
16533 asc_dvc->ultra_able = eep_config.ultra_able;
16534 asc_dvc->tagqng_able = eep_config.tagqng_able;
16535 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16536 asc_dvc->max_host_qng = eep_config.max_host_qng;
16537 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16538 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16539 asc_dvc->start_motor = eep_config.start_motor;
16540 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16541 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16542 asc_dvc->no_scam = eep_config.scam_tolerant;
16543 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16544 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16545 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16548 * Set the host maximum queuing (max. 253, min. 16) and the per device
16549 * maximum queuing (max. 63, min. 4).
16551 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
16553 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16554 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
16556 /* If the value is zero, assume it is uninitialized. */
16557 if (eep_config.max_host_qng == 0)
16559 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16560 } else
16562 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16566 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
16568 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16569 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
16571 /* If the value is zero, assume it is uninitialized. */
16572 if (eep_config.max_dvc_qng == 0)
16574 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16575 } else
16577 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16582 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16583 * set 'max_dvc_qng' to 'max_host_qng'.
16585 if (eep_config.max_dvc_qng > eep_config.max_host_qng)
16587 eep_config.max_dvc_qng = eep_config.max_host_qng;
16591 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16592 * values based on possibly adjusted EEPROM values.
16594 asc_dvc->max_host_qng = eep_config.max_host_qng;
16595 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16599 * If the EEPROM 'termination' field is set to automatic (0), then set
16600 * the ADV_DVC_CFG 'termination' field to automatic also.
16602 * If the termination is specified with a non-zero 'termination'
16603 * value check that a legal value is set and set the ADV_DVC_CFG
16604 * 'termination' field appropriately.
16606 if (eep_config.termination == 0)
16608 asc_dvc->cfg->termination = 0; /* auto termination */
16609 } else
16611 /* Enable manual control with low off / high off. */
16612 if (eep_config.termination == 1)
16614 asc_dvc->cfg->termination = TERM_CTL_SEL;
16616 /* Enable manual control with low off / high on. */
16617 } else if (eep_config.termination == 2)
16619 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
16621 /* Enable manual control with low on / high on. */
16622 } else if (eep_config.termination == 3)
16624 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
16625 } else
16628 * The EEPROM 'termination' field contains a bad value. Use
16629 * automatic termination instead.
16631 asc_dvc->cfg->termination = 0;
16632 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16636 return warn_code;
16640 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16641 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16642 * all of this is done.
16644 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16646 * For a non-fatal error return a warning code. If there are no warnings
16647 * then 0 is returned.
16649 * Note: Chip is stopped on entry.
16651 STATIC int __init
16652 AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
16654 AdvPortAddr iop_base;
16655 ushort warn_code;
16656 ADVEEP_38C0800_CONFIG eep_config;
16657 int i;
16658 uchar tid, termination;
16659 ushort sdtr_speed = 0;
16661 iop_base = asc_dvc->iop_base;
16663 warn_code = 0;
16666 * Read the board's EEPROM configuration.
16668 * Set default values if a bad checksum is found.
16670 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16672 warn_code |= ASC_WARN_EEPROM_CHKSUM;
16675 * Set EEPROM default values.
16677 for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++)
16679 *((uchar *) &eep_config + i) =
16680 *((uchar *) &Default_38C0800_EEPROM_Config + i);
16684 * Assume the 6 byte board serial number that was read
16685 * from EEPROM is correct even if the EEPROM checksum
16686 * failed.
16688 eep_config.serial_number_word3 =
16689 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16691 eep_config.serial_number_word2 =
16692 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16694 eep_config.serial_number_word1 =
16695 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16697 AdvSet38C0800EEPConfig(iop_base, &eep_config);
16700 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
16701 * EEPROM configuration that was read.
16703 * This is the mapping of EEPROM fields to Adv Library fields.
16705 asc_dvc->wdtr_able = eep_config.wdtr_able;
16706 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16707 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16708 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16709 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16710 asc_dvc->tagqng_able = eep_config.tagqng_able;
16711 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16712 asc_dvc->max_host_qng = eep_config.max_host_qng;
16713 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16714 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16715 asc_dvc->start_motor = eep_config.start_motor;
16716 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16717 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16718 asc_dvc->no_scam = eep_config.scam_tolerant;
16719 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16720 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16721 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16724 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16725 * are set, then set an 'sdtr_able' bit for it.
16727 asc_dvc->sdtr_able = 0;
16728 for (tid = 0; tid <= ADV_MAX_TID; tid++)
16730 if (tid == 0)
16732 sdtr_speed = asc_dvc->sdtr_speed1;
16733 } else if (tid == 4)
16735 sdtr_speed = asc_dvc->sdtr_speed2;
16736 } else if (tid == 8)
16738 sdtr_speed = asc_dvc->sdtr_speed3;
16739 } else if (tid == 12)
16741 sdtr_speed = asc_dvc->sdtr_speed4;
16743 if (sdtr_speed & ADV_MAX_TID)
16745 asc_dvc->sdtr_able |= (1 << tid);
16747 sdtr_speed >>= 4;
16751 * Set the host maximum queuing (max. 253, min. 16) and the per device
16752 * maximum queuing (max. 63, min. 4).
16754 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
16756 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16757 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
16759 /* If the value is zero, assume it is uninitialized. */
16760 if (eep_config.max_host_qng == 0)
16762 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16763 } else
16765 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16769 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
16771 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16772 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
16774 /* If the value is zero, assume it is uninitialized. */
16775 if (eep_config.max_dvc_qng == 0)
16777 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16778 } else
16780 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16785 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16786 * set 'max_dvc_qng' to 'max_host_qng'.
16788 if (eep_config.max_dvc_qng > eep_config.max_host_qng)
16790 eep_config.max_dvc_qng = eep_config.max_host_qng;
16794 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16795 * values based on possibly adjusted EEPROM values.
16797 asc_dvc->max_host_qng = eep_config.max_host_qng;
16798 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16801 * If the EEPROM 'termination' field is set to automatic (0), then set
16802 * the ADV_DVC_CFG 'termination' field to automatic also.
16804 * If the termination is specified with a non-zero 'termination'
16805 * value check that a legal value is set and set the ADV_DVC_CFG
16806 * 'termination' field appropriately.
16808 if (eep_config.termination_se == 0)
16810 termination = 0; /* auto termination for SE */
16811 } else
16813 /* Enable manual control with low off / high off. */
16814 if (eep_config.termination_se == 1)
16816 termination = 0;
16818 /* Enable manual control with low off / high on. */
16819 } else if (eep_config.termination_se == 2)
16821 termination = TERM_SE_HI;
16823 /* Enable manual control with low on / high on. */
16824 } else if (eep_config.termination_se == 3)
16826 termination = TERM_SE;
16827 } else
16830 * The EEPROM 'termination_se' field contains a bad value.
16831 * Use automatic termination instead.
16833 termination = 0;
16834 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16838 if (eep_config.termination_lvd == 0)
16840 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
16841 } else
16843 /* Enable manual control with low off / high off. */
16844 if (eep_config.termination_lvd == 1)
16846 asc_dvc->cfg->termination = termination;
16848 /* Enable manual control with low off / high on. */
16849 } else if (eep_config.termination_lvd == 2)
16851 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16853 /* Enable manual control with low on / high on. */
16854 } else if (eep_config.termination_lvd == 3)
16856 asc_dvc->cfg->termination =
16857 termination | TERM_LVD;
16858 } else
16861 * The EEPROM 'termination_lvd' field contains a bad value.
16862 * Use automatic termination instead.
16864 asc_dvc->cfg->termination = termination;
16865 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16869 return warn_code;
16873 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
16874 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
16875 * all of this is done.
16877 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
16879 * For a non-fatal error return a warning code. If there are no warnings
16880 * then 0 is returned.
16882 * Note: Chip is stopped on entry.
16884 STATIC int __init
16885 AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
16887 AdvPortAddr iop_base;
16888 ushort warn_code;
16889 ADVEEP_38C1600_CONFIG eep_config;
16890 int i;
16891 uchar tid, termination;
16892 ushort sdtr_speed = 0;
16894 iop_base = asc_dvc->iop_base;
16896 warn_code = 0;
16899 * Read the board's EEPROM configuration.
16901 * Set default values if a bad checksum is found.
16903 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16905 warn_code |= ASC_WARN_EEPROM_CHKSUM;
16908 * Set EEPROM default values.
16910 for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++)
16912 if (i == 1 && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) != 0)
16915 * Set Function 1 EEPROM Word 0 MSB
16917 * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11)
16918 * EEPROM bits.
16920 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and
16921 * old Mac system booting problem. The Expansion ROM must
16922 * be disabled in Function 1 for these systems.
16925 *((uchar *) &eep_config + i) =
16926 ((*((uchar *) &Default_38C1600_EEPROM_Config + i)) &
16927 (~(((ADV_EEPROM_BIOS_ENABLE | ADV_EEPROM_INTAB) >> 8) &
16928 0xFF)));
16931 * Set the INTAB (bit 11) if the GPIO 0 input indicates
16932 * the Function 1 interrupt line is wired to INTA.
16934 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
16935 * 1 - Function 1 interrupt line wired to INT A.
16936 * 0 - Function 1 interrupt line wired to INT B.
16938 * Note: Adapter boards always have Function 0 wired to INTA.
16939 * Put all 5 GPIO bits in input mode and then read
16940 * their input values.
16942 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
16943 if (AdvReadByteRegister(iop_base, IOPB_GPIO_DATA) & 0x01)
16945 /* Function 1 interrupt wired to INTA; Set EEPROM bit. */
16946 *((uchar *) &eep_config + i) |=
16947 ((ADV_EEPROM_INTAB >> 8) & 0xFF);
16950 else
16952 *((uchar *) &eep_config + i) =
16953 *((uchar *) &Default_38C1600_EEPROM_Config + i);
16958 * Assume the 6 byte board serial number that was read
16959 * from EEPROM is correct even if the EEPROM checksum
16960 * failed.
16962 eep_config.serial_number_word3 =
16963 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16965 eep_config.serial_number_word2 =
16966 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16968 eep_config.serial_number_word1 =
16969 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16971 AdvSet38C1600EEPConfig(iop_base, &eep_config);
16975 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16976 * EEPROM configuration that was read.
16978 * This is the mapping of EEPROM fields to Adv Library fields.
16980 asc_dvc->wdtr_able = eep_config.wdtr_able;
16981 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16982 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16983 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16984 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16985 asc_dvc->ppr_able = 0;
16986 asc_dvc->tagqng_able = eep_config.tagqng_able;
16987 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16988 asc_dvc->max_host_qng = eep_config.max_host_qng;
16989 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16990 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
16991 asc_dvc->start_motor = eep_config.start_motor;
16992 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16993 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16994 asc_dvc->no_scam = eep_config.scam_tolerant;
16997 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16998 * are set, then set an 'sdtr_able' bit for it.
17000 asc_dvc->sdtr_able = 0;
17001 for (tid = 0; tid <= ASC_MAX_TID; tid++)
17003 if (tid == 0)
17005 sdtr_speed = asc_dvc->sdtr_speed1;
17006 } else if (tid == 4)
17008 sdtr_speed = asc_dvc->sdtr_speed2;
17009 } else if (tid == 8)
17011 sdtr_speed = asc_dvc->sdtr_speed3;
17012 } else if (tid == 12)
17014 sdtr_speed = asc_dvc->sdtr_speed4;
17016 if (sdtr_speed & ASC_MAX_TID)
17018 asc_dvc->sdtr_able |= (1 << tid);
17020 sdtr_speed >>= 4;
17024 * Set the host maximum queuing (max. 253, min. 16) and the per device
17025 * maximum queuing (max. 63, min. 4).
17027 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
17029 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17030 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
17032 /* If the value is zero, assume it is uninitialized. */
17033 if (eep_config.max_host_qng == 0)
17035 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17036 } else
17038 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
17042 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
17044 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17045 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
17047 /* If the value is zero, assume it is uninitialized. */
17048 if (eep_config.max_dvc_qng == 0)
17050 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17051 } else
17053 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
17058 * If 'max_dvc_qng' is greater than 'max_host_qng', then
17059 * set 'max_dvc_qng' to 'max_host_qng'.
17061 if (eep_config.max_dvc_qng > eep_config.max_host_qng)
17063 eep_config.max_dvc_qng = eep_config.max_host_qng;
17067 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
17068 * values based on possibly adjusted EEPROM values.
17070 asc_dvc->max_host_qng = eep_config.max_host_qng;
17071 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
17074 * If the EEPROM 'termination' field is set to automatic (0), then set
17075 * the ASC_DVC_CFG 'termination' field to automatic also.
17077 * If the termination is specified with a non-zero 'termination'
17078 * value check that a legal value is set and set the ASC_DVC_CFG
17079 * 'termination' field appropriately.
17081 if (eep_config.termination_se == 0)
17083 termination = 0; /* auto termination for SE */
17084 } else
17086 /* Enable manual control with low off / high off. */
17087 if (eep_config.termination_se == 1)
17089 termination = 0;
17091 /* Enable manual control with low off / high on. */
17092 } else if (eep_config.termination_se == 2)
17094 termination = TERM_SE_HI;
17096 /* Enable manual control with low on / high on. */
17097 } else if (eep_config.termination_se == 3)
17099 termination = TERM_SE;
17100 } else
17103 * The EEPROM 'termination_se' field contains a bad value.
17104 * Use automatic termination instead.
17106 termination = 0;
17107 warn_code |= ASC_WARN_EEPROM_TERMINATION;
17111 if (eep_config.termination_lvd == 0)
17113 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
17114 } else
17116 /* Enable manual control with low off / high off. */
17117 if (eep_config.termination_lvd == 1)
17119 asc_dvc->cfg->termination = termination;
17121 /* Enable manual control with low off / high on. */
17122 } else if (eep_config.termination_lvd == 2)
17124 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
17126 /* Enable manual control with low on / high on. */
17127 } else if (eep_config.termination_lvd == 3)
17129 asc_dvc->cfg->termination =
17130 termination | TERM_LVD;
17131 } else
17134 * The EEPROM 'termination_lvd' field contains a bad value.
17135 * Use automatic termination instead.
17137 asc_dvc->cfg->termination = termination;
17138 warn_code |= ASC_WARN_EEPROM_TERMINATION;
17142 return warn_code;
17146 * Read EEPROM configuration into the specified buffer.
17148 * Return a checksum based on the EEPROM configuration read.
17150 STATIC ushort __init
17151 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
17153 ushort wval, chksum;
17154 ushort *wbuf;
17155 int eep_addr;
17156 ushort *charfields;
17158 charfields = (ushort *) &ADVEEP_3550_Config_Field_IsChar;
17159 wbuf = (ushort *) cfg_buf;
17160 chksum = 0;
17162 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17163 eep_addr < ADV_EEP_DVC_CFG_END;
17164 eep_addr++, wbuf++)
17166 wval = AdvReadEEPWord(iop_base, eep_addr);
17167 chksum += wval; /* Checksum is calculated from word values. */
17168 if (*charfields++) {
17169 *wbuf = le16_to_cpu(wval);
17170 } else {
17171 *wbuf = wval;
17174 /* Read checksum word. */
17175 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17176 wbuf++; charfields++;
17178 /* Read rest of EEPROM not covered by the checksum. */
17179 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17180 eep_addr < ADV_EEP_MAX_WORD_ADDR;
17181 eep_addr++, wbuf++)
17183 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17184 if (*charfields++) {
17185 *wbuf = le16_to_cpu(*wbuf);
17188 return chksum;
17192 * Read EEPROM configuration into the specified buffer.
17194 * Return a checksum based on the EEPROM configuration read.
17196 STATIC ushort __init
17197 AdvGet38C0800EEPConfig(AdvPortAddr iop_base,
17198 ADVEEP_38C0800_CONFIG *cfg_buf)
17200 ushort wval, chksum;
17201 ushort *wbuf;
17202 int eep_addr;
17203 ushort *charfields;
17205 charfields = (ushort *) &ADVEEP_38C0800_Config_Field_IsChar;
17206 wbuf = (ushort *) cfg_buf;
17207 chksum = 0;
17209 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17210 eep_addr < ADV_EEP_DVC_CFG_END;
17211 eep_addr++, wbuf++)
17213 wval = AdvReadEEPWord(iop_base, eep_addr);
17214 chksum += wval; /* Checksum is calculated from word values. */
17215 if (*charfields++) {
17216 *wbuf = le16_to_cpu(wval);
17217 } else {
17218 *wbuf = wval;
17221 /* Read checksum word. */
17222 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17223 wbuf++; charfields++;
17225 /* Read rest of EEPROM not covered by the checksum. */
17226 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17227 eep_addr < ADV_EEP_MAX_WORD_ADDR;
17228 eep_addr++, wbuf++)
17230 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17231 if (*charfields++) {
17232 *wbuf = le16_to_cpu(*wbuf);
17235 return chksum;
17239 * Read EEPROM configuration into the specified buffer.
17241 * Return a checksum based on the EEPROM configuration read.
17243 STATIC ushort __init
17244 AdvGet38C1600EEPConfig(AdvPortAddr iop_base,
17245 ADVEEP_38C1600_CONFIG *cfg_buf)
17247 ushort wval, chksum;
17248 ushort *wbuf;
17249 int eep_addr;
17250 ushort *charfields;
17252 charfields = (ushort*) &ADVEEP_38C1600_Config_Field_IsChar;
17253 wbuf = (ushort *) cfg_buf;
17254 chksum = 0;
17256 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17257 eep_addr < ADV_EEP_DVC_CFG_END;
17258 eep_addr++, wbuf++)
17260 wval = AdvReadEEPWord(iop_base, eep_addr);
17261 chksum += wval; /* Checksum is calculated from word values. */
17262 if (*charfields++) {
17263 *wbuf = le16_to_cpu(wval);
17264 } else {
17265 *wbuf = wval;
17268 /* Read checksum word. */
17269 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17270 wbuf++; charfields++;
17272 /* Read rest of EEPROM not covered by the checksum. */
17273 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17274 eep_addr < ADV_EEP_MAX_WORD_ADDR;
17275 eep_addr++, wbuf++)
17277 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17278 if (*charfields++) {
17279 *wbuf = le16_to_cpu(*wbuf);
17282 return chksum;
17286 * Read the EEPROM from specified location
17288 STATIC ushort __init
17289 AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
17291 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
17292 ASC_EEP_CMD_READ | eep_word_addr);
17293 AdvWaitEEPCmd(iop_base);
17294 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
17298 * Wait for EEPROM command to complete
17300 STATIC void __init
17301 AdvWaitEEPCmd(AdvPortAddr iop_base)
17303 int eep_delay_ms;
17305 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++)
17307 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE)
17309 break;
17311 DvcSleepMilliSecond(1);
17313 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == 0)
17315 ASC_ASSERT(0);
17317 return;
17321 * Write the EEPROM from 'cfg_buf'.
17323 void
17324 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
17326 ushort *wbuf;
17327 ushort addr, chksum;
17328 ushort *charfields;
17330 wbuf = (ushort *) cfg_buf;
17331 charfields = (ushort *) &ADVEEP_3550_Config_Field_IsChar;
17332 chksum = 0;
17334 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17335 AdvWaitEEPCmd(iop_base);
17338 * Write EEPROM from word 0 to word 20.
17340 for (addr = ADV_EEP_DVC_CFG_BEGIN;
17341 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17343 ushort word;
17345 if (*charfields++) {
17346 word = cpu_to_le16(*wbuf);
17347 } else {
17348 word = *wbuf;
17350 chksum += *wbuf; /* Checksum is calculated from word values. */
17351 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17352 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17353 AdvWaitEEPCmd(iop_base);
17354 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17358 * Write EEPROM checksum at word 21.
17360 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17361 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17362 AdvWaitEEPCmd(iop_base);
17363 wbuf++; charfields++;
17366 * Write EEPROM OEM name at words 22 to 29.
17368 for (addr = ADV_EEP_DVC_CTL_BEGIN;
17369 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17371 ushort word;
17373 if (*charfields++) {
17374 word = cpu_to_le16(*wbuf);
17375 } else {
17376 word = *wbuf;
17378 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17379 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17380 AdvWaitEEPCmd(iop_base);
17382 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17383 AdvWaitEEPCmd(iop_base);
17384 return;
17388 * Write the EEPROM from 'cfg_buf'.
17390 void
17391 AdvSet38C0800EEPConfig(AdvPortAddr iop_base,
17392 ADVEEP_38C0800_CONFIG *cfg_buf)
17394 ushort *wbuf;
17395 ushort *charfields;
17396 ushort addr, chksum;
17398 wbuf = (ushort *) cfg_buf;
17399 charfields = (ushort *) &ADVEEP_38C0800_Config_Field_IsChar;
17400 chksum = 0;
17402 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17403 AdvWaitEEPCmd(iop_base);
17406 * Write EEPROM from word 0 to word 20.
17408 for (addr = ADV_EEP_DVC_CFG_BEGIN;
17409 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17411 ushort word;
17413 if (*charfields++) {
17414 word = cpu_to_le16(*wbuf);
17415 } else {
17416 word = *wbuf;
17418 chksum += *wbuf; /* Checksum is calculated from word values. */
17419 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17420 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17421 AdvWaitEEPCmd(iop_base);
17422 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17426 * Write EEPROM checksum at word 21.
17428 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17429 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17430 AdvWaitEEPCmd(iop_base);
17431 wbuf++; charfields++;
17434 * Write EEPROM OEM name at words 22 to 29.
17436 for (addr = ADV_EEP_DVC_CTL_BEGIN;
17437 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17439 ushort word;
17441 if (*charfields++) {
17442 word = cpu_to_le16(*wbuf);
17443 } else {
17444 word = *wbuf;
17446 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17447 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17448 AdvWaitEEPCmd(iop_base);
17450 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17451 AdvWaitEEPCmd(iop_base);
17452 return;
17456 * Write the EEPROM from 'cfg_buf'.
17458 void
17459 AdvSet38C1600EEPConfig(AdvPortAddr iop_base,
17460 ADVEEP_38C1600_CONFIG *cfg_buf)
17462 ushort *wbuf;
17463 ushort *charfields;
17464 ushort addr, chksum;
17466 wbuf = (ushort *) cfg_buf;
17467 charfields = (ushort *) &ADVEEP_38C1600_Config_Field_IsChar;
17468 chksum = 0;
17470 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17471 AdvWaitEEPCmd(iop_base);
17474 * Write EEPROM from word 0 to word 20.
17476 for (addr = ADV_EEP_DVC_CFG_BEGIN;
17477 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17479 ushort word;
17481 if (*charfields++) {
17482 word = cpu_to_le16(*wbuf);
17483 } else {
17484 word = *wbuf;
17486 chksum += *wbuf; /* Checksum is calculated from word values. */
17487 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17488 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17489 AdvWaitEEPCmd(iop_base);
17490 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17494 * Write EEPROM checksum at word 21.
17496 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17497 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17498 AdvWaitEEPCmd(iop_base);
17499 wbuf++; charfields++;
17502 * Write EEPROM OEM name at words 22 to 29.
17504 for (addr = ADV_EEP_DVC_CTL_BEGIN;
17505 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17507 ushort word;
17509 if (*charfields++) {
17510 word = cpu_to_le16(*wbuf);
17511 } else {
17512 word = *wbuf;
17514 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17515 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17516 AdvWaitEEPCmd(iop_base);
17518 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17519 AdvWaitEEPCmd(iop_base);
17520 return;
17523 /* a_advlib.c */
17525 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
17527 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
17528 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
17529 * RISC to notify it a new command is ready to be executed.
17531 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
17532 * set to SCSI_MAX_RETRY.
17534 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
17535 * for DMA addresses or math operations are byte swapped to little-endian
17536 * order.
17538 * Return:
17539 * ADV_SUCCESS(1) - The request was successfully queued.
17540 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
17541 * request completes.
17542 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
17543 * host IC error.
17545 STATIC int
17546 AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc,
17547 ADV_SCSI_REQ_Q *scsiq)
17549 ulong last_int_level;
17550 AdvPortAddr iop_base;
17551 ADV_DCNT req_size;
17552 ADV_PADDR req_paddr;
17553 ADV_CARR_T *new_carrp;
17555 ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
17558 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
17560 if (scsiq->target_id > ADV_MAX_TID)
17562 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
17563 scsiq->done_status = QD_WITH_ERROR;
17564 return ADV_ERROR;
17567 iop_base = asc_dvc->iop_base;
17569 last_int_level = DvcEnterCritical();
17572 * Allocate a carrier ensuring at least one carrier always
17573 * remains on the freelist and initialize fields.
17575 if ((new_carrp = asc_dvc->carr_freelist) == NULL)
17577 DvcLeaveCritical(last_int_level);
17578 return ADV_BUSY;
17580 asc_dvc->carr_freelist = (ADV_CARR_T *)
17581 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
17582 asc_dvc->carr_pending_cnt++;
17585 * Set the carrier to be a stopper by setting 'next_vpa'
17586 * to the stopper value. The current stopper will be changed
17587 * below to point to the new stopper.
17589 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
17592 * Clear the ADV_SCSI_REQ_Q done flag.
17594 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
17596 req_size = sizeof(ADV_SCSI_REQ_Q);
17597 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *) scsiq,
17598 (ADV_SDCNT *) &req_size, ADV_IS_SCSIQ_FLAG);
17600 ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
17601 ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
17603 /* Wait for assertion before making little-endian */
17604 req_paddr = cpu_to_le32(req_paddr);
17606 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
17607 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
17608 scsiq->scsiq_rptr = req_paddr;
17610 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
17612 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
17613 * order during initialization.
17615 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
17618 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
17619 * the microcode. The newly allocated stopper will become the new
17620 * stopper.
17622 asc_dvc->icq_sp->areq_vpa = req_paddr;
17625 * Set the 'next_vpa' pointer for the old stopper to be the
17626 * physical address of the new stopper. The RISC can only
17627 * follow physical addresses.
17629 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
17632 * Set the host adapter stopper pointer to point to the new carrier.
17634 asc_dvc->icq_sp = new_carrp;
17636 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17637 asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
17640 * Tickle the RISC to tell it to read its Command Queue Head pointer.
17642 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
17643 if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
17646 * Clear the tickle value. In the ASC-3550 the RISC flag
17647 * command 'clr_tickle_a' does not work unless the host
17648 * value is cleared.
17650 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17652 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17655 * Notify the RISC a carrier is ready by writing the physical
17656 * address of the new carrier stopper to the COMMA register.
17658 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
17659 le32_to_cpu(new_carrp->carr_pa));
17662 DvcLeaveCritical(last_int_level);
17664 return ADV_SUCCESS;
17668 * Reset SCSI Bus and purge all outstanding requests.
17670 * Return Value:
17671 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
17672 * ADV_FALSE(0) - Microcode command failed.
17673 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
17674 * may be hung which requires driver recovery.
17676 STATIC int
17677 AdvResetSB(ADV_DVC_VAR *asc_dvc)
17679 int status;
17682 * Send the SCSI Bus Reset idle start idle command which asserts
17683 * the SCSI Bus Reset signal.
17685 status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_START, 0L);
17686 if (status != ADV_TRUE)
17688 return status;
17692 * Delay for the specified SCSI Bus Reset hold time.
17694 * The hold time delay is done on the host because the RISC has no
17695 * microsecond accurate timer.
17697 DvcDelayMicroSecond(asc_dvc, (ushort) ASC_SCSI_RESET_HOLD_TIME_US);
17700 * Send the SCSI Bus Reset end idle command which de-asserts
17701 * the SCSI Bus Reset signal and purges any pending requests.
17703 status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_END, 0L);
17704 if (status != ADV_TRUE)
17706 return status;
17709 DvcSleepMilliSecond((ADV_DCNT) asc_dvc->scsi_reset_wait * 1000);
17711 return status;
17715 * Reset chip and SCSI Bus.
17717 * Return Value:
17718 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
17719 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
17721 STATIC int
17722 AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
17724 int status;
17725 ushort wdtr_able, sdtr_able, tagqng_able;
17726 ushort ppr_able = 0;
17727 uchar tid, max_cmd[ADV_MAX_TID + 1];
17728 AdvPortAddr iop_base;
17729 ushort bios_sig;
17731 iop_base = asc_dvc->iop_base;
17734 * Save current per TID negotiated values.
17736 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17737 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17738 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17740 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17742 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17743 for (tid = 0; tid <= ADV_MAX_TID; tid++)
17745 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17746 max_cmd[tid]);
17750 * Force the AdvInitAsc3550/38C0800Driver() function to
17751 * perform a SCSI Bus Reset by clearing the BIOS signature word.
17752 * The initialization functions assumes a SCSI Bus Reset is not
17753 * needed if the BIOS signature word is present.
17755 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17756 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
17759 * Stop chip and reset it.
17761 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
17762 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
17763 DvcSleepMilliSecond(100);
17764 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG);
17767 * Reset Adv Library error code, if any, and try
17768 * re-initializing the chip.
17770 asc_dvc->err_code = 0;
17771 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17773 status = AdvInitAsc38C1600Driver(asc_dvc);
17775 else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
17777 status = AdvInitAsc38C0800Driver(asc_dvc);
17778 } else
17780 status = AdvInitAsc3550Driver(asc_dvc);
17783 /* Translate initialization return value to status value. */
17784 if (status == 0)
17786 status = ADV_TRUE;
17787 } else
17789 status = ADV_FALSE;
17793 * Restore the BIOS signature word.
17795 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17798 * Restore per TID negotiated values.
17800 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17801 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17802 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17804 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17806 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17807 for (tid = 0; tid <= ADV_MAX_TID; tid++)
17809 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17810 max_cmd[tid]);
17813 return status;
17817 * Adv Library Interrupt Service Routine
17819 * This function is called by a driver's interrupt service routine.
17820 * The function disables and re-enables interrupts.
17822 * When a microcode idle command is completed, the ADV_DVC_VAR
17823 * 'idle_cmd_done' field is set to ADV_TRUE.
17825 * Note: AdvISR() can be called when interrupts are disabled or even
17826 * when there is no hardware interrupt condition present. It will
17827 * always check for completed idle commands and microcode requests.
17828 * This is an important feature that shouldn't be changed because it
17829 * allows commands to be completed from polling mode loops.
17831 * Return:
17832 * ADV_TRUE(1) - interrupt was pending
17833 * ADV_FALSE(0) - no interrupt was pending
17835 STATIC int
17836 AdvISR(ADV_DVC_VAR *asc_dvc)
17838 AdvPortAddr iop_base;
17839 uchar int_stat;
17840 ushort target_bit;
17841 ADV_CARR_T *free_carrp;
17842 ADV_VADDR irq_next_vpa;
17843 int flags;
17844 ADV_SCSI_REQ_Q *scsiq;
17846 flags = DvcEnterCritical();
17848 iop_base = asc_dvc->iop_base;
17850 /* Reading the register clears the interrupt. */
17851 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
17853 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
17854 ADV_INTR_STATUS_INTRC)) == 0)
17856 DvcLeaveCritical(flags);
17857 return ADV_FALSE;
17861 * Notify the driver of an asynchronous microcode condition by
17862 * calling the ADV_DVC_VAR.async_callback function. The function
17863 * is passed the microcode ASC_MC_INTRB_CODE byte value.
17865 if (int_stat & ADV_INTR_STATUS_INTRB)
17867 uchar intrb_code;
17869 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
17871 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17872 asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
17874 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
17875 asc_dvc->carr_pending_cnt != 0)
17877 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
17878 if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
17880 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17885 if (asc_dvc->async_callback != 0)
17887 (*asc_dvc->async_callback)(asc_dvc, intrb_code);
17892 * Check if the IRQ stopper carrier contains a completed request.
17894 while (((irq_next_vpa =
17895 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0)
17898 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
17899 * The RISC will have set 'areq_vpa' to a virtual address.
17901 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
17902 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
17903 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
17904 * in AdvExeScsiQueue().
17906 scsiq = (ADV_SCSI_REQ_Q *)
17907 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
17910 * Request finished with good status and the queue was not
17911 * DMAed to host memory by the firmware. Set all status fields
17912 * to indicate good status.
17914 if ((irq_next_vpa & ASC_RQ_GOOD) != 0)
17916 scsiq->done_status = QD_NO_ERROR;
17917 scsiq->host_status = scsiq->scsi_status = 0;
17918 scsiq->data_cnt = 0L;
17922 * Advance the stopper pointer to the next carrier
17923 * ignoring the lower four bits. Free the previous
17924 * stopper carrier.
17926 free_carrp = asc_dvc->irq_sp;
17927 asc_dvc->irq_sp = (ADV_CARR_T *)
17928 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
17930 free_carrp->next_vpa =
17931 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
17932 asc_dvc->carr_freelist = free_carrp;
17933 asc_dvc->carr_pending_cnt--;
17935 ASC_ASSERT(scsiq != NULL);
17936 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
17939 * Clear request microcode control flag.
17941 scsiq->cntl = 0;
17944 * If the command that completed was a SCSI INQUIRY and
17945 * LUN 0 was sent the command, then process the INQUIRY
17946 * command information for the device.
17948 * Note: If data returned were either VPD or CmdDt data,
17949 * don't process the INQUIRY command information for
17950 * the device, otherwise may erroneously set *_able bits.
17952 if (scsiq->done_status == QD_NO_ERROR &&
17953 scsiq->cdb[0] == INQUIRY &&
17954 scsiq->target_lun == 0 &&
17955 (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
17956 == ADV_INQ_RTN_STD_INQUIRY_DATA)
17958 AdvInquiryHandling(asc_dvc, scsiq);
17962 * Notify the driver of the completed request by passing
17963 * the ADV_SCSI_REQ_Q pointer to its callback function.
17965 scsiq->a_flag |= ADV_SCSIQ_DONE;
17966 (*asc_dvc->isr_callback)(asc_dvc, scsiq);
17968 * Note: After the driver callback function is called, 'scsiq'
17969 * can no longer be referenced.
17971 * Fall through and continue processing other completed
17972 * requests...
17976 * Disable interrupts again in case the driver inadvertently
17977 * enabled interrupts in its callback function.
17979 * The DvcEnterCritical() return value is ignored, because
17980 * the 'flags' saved when AdvISR() was first entered will be
17981 * used to restore the interrupt flag on exit.
17983 (void) DvcEnterCritical();
17985 DvcLeaveCritical(flags);
17986 return ADV_TRUE;
17990 * Send an idle command to the chip and wait for completion.
17992 * Command completion is polled for once per microsecond.
17994 * The function can be called from anywhere including an interrupt handler.
17995 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
17996 * functions to prevent reentrancy.
17998 * Return Values:
17999 * ADV_TRUE - command completed successfully
18000 * ADV_FALSE - command failed
18001 * ADV_ERROR - command timed out
18003 STATIC int
18004 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
18005 ushort idle_cmd,
18006 ADV_DCNT idle_cmd_parameter)
18008 ulong last_int_level;
18009 int result;
18010 ADV_DCNT i, j;
18011 AdvPortAddr iop_base;
18013 last_int_level = DvcEnterCritical();
18015 iop_base = asc_dvc->iop_base;
18018 * Clear the idle command status which is set by the microcode
18019 * to a non-zero value to indicate when the command is completed.
18020 * The non-zero result is one of the IDLE_CMD_STATUS_* values
18021 * defined in a_advlib.h.
18023 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort) 0);
18026 * Write the idle command value after the idle command parameter
18027 * has been written to avoid a race condition. If the order is not
18028 * followed, the microcode may process the idle command before the
18029 * parameters have been written to LRAM.
18031 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
18032 cpu_to_le32(idle_cmd_parameter));
18033 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
18036 * Tickle the RISC to tell it to process the idle command.
18038 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
18039 if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
18042 * Clear the tickle value. In the ASC-3550 the RISC flag
18043 * command 'clr_tickle_b' does not work unless the host
18044 * value is cleared.
18046 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
18049 /* Wait for up to 100 millisecond for the idle command to timeout. */
18050 for (i = 0; i < SCSI_WAIT_100_MSEC; i++)
18052 /* Poll once each microsecond for command completion. */
18053 for (j = 0; j < SCSI_US_PER_MSEC; j++)
18055 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, result);
18056 if (result != 0)
18058 DvcLeaveCritical(last_int_level);
18059 return result;
18061 DvcDelayMicroSecond(asc_dvc, (ushort) 1);
18065 ASC_ASSERT(0); /* The idle command should never timeout. */
18066 DvcLeaveCritical(last_int_level);
18067 return ADV_ERROR;
18071 * Inquiry Information Byte 7 Handling
18073 * Handle SCSI Inquiry Command information for a device by setting
18074 * microcode operating variables that affect WDTR, SDTR, and Tag
18075 * Queuing.
18077 STATIC void
18078 AdvInquiryHandling(
18079 ADV_DVC_VAR *asc_dvc,
18080 ADV_SCSI_REQ_Q *scsiq)
18082 AdvPortAddr iop_base;
18083 uchar tid;
18084 ADV_SCSI_INQUIRY *inq;
18085 ushort tidmask;
18086 ushort cfg_word;
18089 * AdvInquiryHandling() requires up to INQUIRY information Byte 7
18090 * to be available.
18092 * If less than 8 bytes of INQUIRY information were requested or less
18093 * than 8 bytes were transferred, then return. cdb[4] is the request
18094 * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
18095 * microcode to the transfer residual count.
18098 if (scsiq->cdb[4] < 8 ||
18099 (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8)
18101 return;
18104 iop_base = asc_dvc->iop_base;
18105 tid = scsiq->target_id;
18107 inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr;
18110 * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
18112 if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2)
18114 return;
18115 } else
18118 * INQUIRY Byte 7 Handling
18120 * Use a device's INQUIRY byte 7 to determine whether it
18121 * supports WDTR, SDTR, and Tag Queuing. If the feature
18122 * is enabled in the EEPROM and the device supports the
18123 * feature, then enable it in the microcode.
18126 tidmask = ADV_TID_TO_TIDMASK(tid);
18129 * Wide Transfers
18131 * If the EEPROM enabled WDTR for the device and the device
18132 * supports wide bus (16 bit) transfers, then turn on the
18133 * device's 'wdtr_able' bit and write the new value to the
18134 * microcode.
18136 if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq))
18138 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
18139 if ((cfg_word & tidmask) == 0)
18141 cfg_word |= tidmask;
18142 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
18145 * Clear the microcode "SDTR negotiation" and "WDTR
18146 * negotiation" done indicators for the target to cause
18147 * it to negotiate with the new setting set above.
18148 * WDTR when accepted causes the target to enter
18149 * asynchronous mode, so SDTR must be negotiated.
18151 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18152 cfg_word &= ~tidmask;
18153 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18154 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
18155 cfg_word &= ~tidmask;
18156 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
18161 * Synchronous Transfers
18163 * If the EEPROM enabled SDTR for the device and the device
18164 * supports synchronous transfers, then turn on the device's
18165 * 'sdtr_able' bit. Write the new value to the microcode.
18167 if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq))
18169 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
18170 if ((cfg_word & tidmask) == 0)
18172 cfg_word |= tidmask;
18173 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
18176 * Clear the microcode "SDTR negotiation" done indicator
18177 * for the target to cause it to negotiate with the new
18178 * setting set above.
18180 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18181 cfg_word &= ~tidmask;
18182 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18186 * If the Inquiry data included enough space for the SPI-3
18187 * Clocking field, then check if DT mode is supported.
18189 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 &&
18190 (scsiq->cdb[4] >= 57 ||
18191 (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57))
18194 * PPR (Parallel Protocol Request) Capable
18196 * If the device supports DT mode, then it must be PPR capable.
18197 * The PPR message will be used in place of the SDTR and WDTR
18198 * messages to negotiate synchronous speed and offset, transfer
18199 * width, and protocol options.
18201 if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY)
18203 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, asc_dvc->ppr_able);
18204 asc_dvc->ppr_able |= tidmask;
18205 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, asc_dvc->ppr_able);
18210 * If the EEPROM enabled Tag Queuing for the device and the
18211 * device supports Tag Queueing, then turn on the device's
18212 * 'tagqng_enable' bit in the microcode and set the microcode
18213 * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
18214 * value.
18216 * Tag Queuing is disabled for the BIOS which runs in polled
18217 * mode and would see no benefit from Tag Queuing. Also by
18218 * disabling Tag Queuing in the BIOS devices with Tag Queuing
18219 * bugs will at least work with the BIOS.
18221 if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq))
18223 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
18224 cfg_word |= tidmask;
18225 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
18227 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
18228 asc_dvc->max_dvc_qng);
18232 MODULE_LICENSE("Dual BSD/GPL");