[SCSI] advansys: remove INQUIRY sniffing
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / scsi / advansys.c
blob5885ce4aad9a1758d8908a4bdcf2f6a311d17c3b
1 #define ASC_VERSION "3.4" /* AdvanSys Driver Version */
3 /*
4 * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
6 * Copyright (c) 1995-2000 Advanced System Products, Inc.
7 * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
8 * Copyright (c) 2007 Matthew Wilcox <matthew@wil.cx>
9 * All Rights Reserved.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
18 * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
19 * changed its name to ConnectCom Solutions, Inc.
20 * On June 18, 2001 Initio Corp. acquired ConnectCom's SCSI assets
25 Documentation for the AdvanSys Driver
27 A. Linux Kernels Supported by this Driver
28 B. Adapters Supported by this Driver
29 C. Linux source files modified by AdvanSys Driver
30 D. Source Comments
31 E. Driver Compile Time Options and Debugging
32 F. Driver LILO Option
33 G. Tests to run before releasing new driver
34 H. Release History
35 I. Known Problems/Fix List
36 J. Credits (Chronological Order)
38 A. Linux Kernels Supported by this Driver
40 This driver has been tested in the following Linux kernels: v2.2.18
41 v2.4.0. The driver is supported on v2.2 and v2.4 kernels and on x86,
42 alpha, and PowerPC platforms.
44 B. Adapters Supported by this Driver
46 AdvanSys (Advanced System Products, Inc.) manufactures the following
47 RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow
48 (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI
49 buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit
50 transfer) SCSI Host Adapters for the PCI bus.
52 The CDB counts below indicate the number of SCSI CDB (Command
53 Descriptor Block) requests that can be stored in the RISC chip
54 cache and board LRAM. A CDB is a single SCSI command. The driver
55 detect routine will display the number of CDBs available for each
56 adapter detected. The number of CDBs used by the driver can be
57 lowered in the BIOS by changing the 'Host Queue Size' adapter setting.
59 Laptop Products:
60 ABP-480 - Bus-Master CardBus (16 CDB) (2.4 kernel and greater)
62 Connectivity Products:
63 ABP510/5150 - Bus-Master ISA (240 CDB)
64 ABP5140 - Bus-Master ISA PnP (16 CDB)
65 ABP5142 - Bus-Master ISA PnP with floppy (16 CDB)
66 ABP902/3902 - Bus-Master PCI (16 CDB)
67 ABP3905 - Bus-Master PCI (16 CDB)
68 ABP915 - Bus-Master PCI (16 CDB)
69 ABP920 - Bus-Master PCI (16 CDB)
70 ABP3922 - Bus-Master PCI (16 CDB)
71 ABP3925 - Bus-Master PCI (16 CDB)
72 ABP930 - Bus-Master PCI (16 CDB)
73 ABP930U - Bus-Master PCI Ultra (16 CDB)
74 ABP930UA - Bus-Master PCI Ultra (16 CDB)
75 ABP960 - Bus-Master PCI MAC/PC (16 CDB)
76 ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
78 Single Channel Products:
79 ABP542 - Bus-Master ISA with floppy (240 CDB)
80 ABP742 - Bus-Master EISA (240 CDB)
81 ABP842 - Bus-Master VL (240 CDB)
82 ABP940 - Bus-Master PCI (240 CDB)
83 ABP940U - Bus-Master PCI Ultra (240 CDB)
84 ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB)
85 ABP970 - Bus-Master PCI MAC/PC (240 CDB)
86 ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
87 ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB)
88 ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB)
89 ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB)
90 ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB)
92 Multi-Channel Products:
93 ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
94 ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
95 ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
96 ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel)
97 ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
98 ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
99 ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.)
100 ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB)
101 ABP3950U3W - Bus-Master PCI Dual LVD2/Ultra3-Wide (253 CDB)
103 C. Linux source files modified by AdvanSys Driver
105 This section for historical purposes documents the changes
106 originally made to the Linux kernel source to add the advansys
107 driver. As Linux has changed some of these files have also
108 been modified.
110 1. linux/arch/i386/config.in:
112 bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
114 2. linux/drivers/scsi/hosts.c:
116 #ifdef CONFIG_SCSI_ADVANSYS
117 #include "advansys.h"
118 #endif
120 and after "static struct scsi_host_template builtin_scsi_hosts[] =":
122 #ifdef CONFIG_SCSI_ADVANSYS
123 ADVANSYS,
124 #endif
126 3. linux/drivers/scsi/Makefile:
128 ifdef CONFIG_SCSI_ADVANSYS
129 SCSI_SRCS := $(SCSI_SRCS) advansys.c
130 SCSI_OBJS := $(SCSI_OBJS) advansys.o
131 else
132 SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
133 endif
135 4. linux/init/main.c:
137 extern void advansys_setup(char *str, int *ints);
139 and add the following lines to the bootsetups[] array.
141 #ifdef CONFIG_SCSI_ADVANSYS
142 { "advansys=", advansys_setup },
143 #endif
145 D. Source Comments
147 1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
149 2. This driver should be maintained in multiple files. But to make
150 it easier to include with Linux and to follow Linux conventions,
151 the whole driver is maintained in the source files advansys.h and
152 advansys.c. In this file logical sections of the driver begin with
153 a comment that contains '---'. The following are the logical sections
154 of the driver below.
156 --- Linux Version
157 --- Linux Include File
158 --- Driver Options
159 --- Debugging Header
160 --- Asc Library Constants and Macros
161 --- Adv Library Constants and Macros
162 --- Driver Constants and Macros
163 --- Driver Structures
164 --- Driver Data
165 --- Driver Function Prototypes
166 --- Linux 'struct scsi_host_template' and advansys_setup() Functions
167 --- Loadable Driver Support
168 --- Miscellaneous Driver Functions
169 --- Functions Required by the Asc Library
170 --- Functions Required by the Adv Library
171 --- Tracing and Debugging Functions
172 --- Asc Library Functions
173 --- Adv Library Functions
175 3. The string 'XXX' is used to flag code that needs to be re-written
176 or that contains a problem that needs to be addressed.
178 4. I have stripped comments from and reformatted the source for the
179 Asc Library and Adv Library to reduce the size of this file. This
180 source can be found under the following headings. The Asc Library
181 is used to support Narrow Boards. The Adv Library is used to
182 support Wide Boards.
184 --- Asc Library Constants and Macros
185 --- Adv Library Constants and Macros
186 --- Asc Library Functions
187 --- Adv Library Functions
189 E. Driver Compile Time Options and Debugging
191 In this source file the following constants can be defined. They are
192 defined in the source below. Both of these options are enabled by
193 default.
195 1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled)
197 Enabling this option adds assertion logic statements to the
198 driver. If an assertion fails a message will be displayed to
199 the console, but the system will continue to operate. Any
200 assertions encountered should be reported to the person
201 responsible for the driver. Assertion statements may proactively
202 detect problems with the driver and facilitate fixing these
203 problems. Enabling assertions will add a small overhead to the
204 execution of the driver.
206 2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled)
208 Enabling this option adds tracing functions to the driver and
209 the ability to set a driver tracing level at boot time. This
210 option will also export symbols not required outside the driver to
211 the kernel name space. This option is very useful for debugging
212 the driver, but it will add to the size of the driver execution
213 image and add overhead to the execution of the driver.
215 The amount of debugging output can be controlled with the global
216 variable 'asc_dbglvl'. The higher the number the more output. By
217 default the debug level is 0.
219 If the driver is loaded at boot time and the LILO Driver Option
220 is included in the system, the debug level can be changed by
221 specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
222 first three hex digits of the pseudo I/O Port must be set to
223 'deb' and the fourth hex digit specifies the debug level: 0 - F.
224 The following command line will look for an adapter at 0x330
225 and set the debug level to 2.
227 linux advansys=0x330,0,0,0,0xdeb2
229 If the driver is built as a loadable module this variable can be
230 defined when the driver is loaded. The following insmod command
231 will set the debug level to one.
233 insmod advansys.o asc_dbglvl=1
235 Debugging Message Levels:
236 0: Errors Only
237 1: High-Level Tracing
238 2-N: Verbose Tracing
240 To enable debug output to console, please make sure that:
242 a. System and kernel logging is enabled (syslogd, klogd running).
243 b. Kernel messages are routed to console output. Check
244 /etc/syslog.conf for an entry similar to this:
246 kern.* /dev/console
248 c. klogd is started with the appropriate -c parameter
249 (e.g. klogd -c 8)
251 This will cause printk() messages to be be displayed on the
252 current console. Refer to the klogd(8) and syslogd(8) man pages
253 for details.
255 Alternatively you can enable printk() to console with this
256 program. However, this is not the 'official' way to do this.
257 Debug output is logged in /var/log/messages.
259 main()
261 syscall(103, 7, 0, 0);
264 Increasing LOG_BUF_LEN in kernel/printk.c to something like
265 40960 allows more debug messages to be buffered in the kernel
266 and written to the console or log file.
268 3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0)
270 Enabling this option adds statistics collection and display
271 through /proc to the driver. The information is useful for
272 monitoring driver and device performance. It will add to the
273 size of the driver execution image and add minor overhead to
274 the execution of the driver.
276 Statistics are maintained on a per adapter basis. Driver entry
277 point call counts and transfer size counts are maintained.
278 Statistics are only available for kernels greater than or equal
279 to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured.
281 AdvanSys SCSI adapter files have the following path name format:
283 /proc/scsi/advansys/{0,1,2,3,...}
285 This information can be displayed with cat. For example:
287 cat /proc/scsi/advansys/0
289 When ADVANSYS_STATS is not defined the AdvanSys /proc files only
290 contain adapter and device configuration information.
292 F. Driver LILO Option
294 If init/main.c is modified as described in the 'Directions for Adding
295 the AdvanSys Driver to Linux' section (B.4.) above, the driver will
296 recognize the 'advansys' LILO command line and /etc/lilo.conf option.
297 This option can be used to either disable I/O port scanning or to limit
298 scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
299 PCI boards will still be searched for and detected. This option only
300 affects searching for ISA and VL boards.
302 Examples:
303 1. Eliminate I/O port scanning:
304 boot: linux advansys=
306 boot: linux advansys=0x0
307 2. Limit I/O port scanning to one I/O port:
308 boot: linux advansys=0x110
309 3. Limit I/O port scanning to four I/O ports:
310 boot: linux advansys=0x110,0x210,0x230,0x330
312 For a loadable module the same effect can be achieved by setting
313 the 'asc_iopflag' variable and 'asc_ioport' array when loading
314 the driver, e.g.
316 insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
318 If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1)
319 I/O Port may be added to specify the driver debug level. Refer to
320 the 'Driver Compile Time Options and Debugging' section above for
321 more information.
323 G. Tests to run before releasing new driver
325 1. In the supported kernels verify there are no warning or compile
326 errors when the kernel is built as both a driver and as a module
327 and with the following options:
329 ADVANSYS_DEBUG - enabled and disabled
330 CONFIG_SMP - enabled and disabled
331 CONFIG_PROC_FS - enabled and disabled
333 2. Run tests on an x86, alpha, and PowerPC with at least one narrow
334 card and one wide card attached to a hard disk and CD-ROM drive:
335 fdisk, mkfs, fsck, bonnie, copy/compare test from the
336 CD-ROM to the hard drive.
338 H. Release History
340 BETA-1.0 (12/23/95):
341 First Release
343 BETA-1.1 (12/28/95):
344 1. Prevent advansys_detect() from being called twice.
345 2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
347 1.2 (1/12/96):
348 1. Prevent re-entrancy in the interrupt handler which
349 resulted in the driver hanging Linux.
350 2. Fix problem that prevented ABP-940 cards from being
351 recognized on some PCI motherboards.
352 3. Add support for the ABP-5140 PnP ISA card.
353 4. Fix check condition return status.
354 5. Add conditionally compiled code for Linux v1.3.X.
356 1.3 (2/23/96):
357 1. Fix problem in advansys_biosparam() that resulted in the
358 wrong drive geometry being returned for drives > 1GB with
359 extended translation enabled.
360 2. Add additional tracing during device initialization.
361 3. Change code that only applies to ISA PnP adapter.
362 4. Eliminate 'make dep' warning.
363 5. Try to fix problem with handling resets by increasing their
364 timeout value.
366 1.4 (5/8/96):
367 1. Change definitions to eliminate conflicts with other subsystems.
368 2. Add versioning code for the shared interrupt changes.
369 3. Eliminate problem in asc_rmqueue() with iterating after removing
370 a request.
371 4. Remove reset request loop problem from the "Known Problems or
372 Issues" section. This problem was isolated and fixed in the
373 mid-level SCSI driver.
375 1.5 (8/8/96):
376 1. Add support for ABP-940U (PCI Ultra) adapter.
377 2. Add support for IRQ sharing by setting the IRQF_SHARED flag for
378 request_irq and supplying a dev_id pointer to both request_irq()
379 and free_irq().
380 3. In AscSearchIOPortAddr11() restore a call to check_region() which
381 should be used before I/O port probing.
382 4. Fix bug in asc_prt_hex() which resulted in the displaying
383 the wrong data.
384 5. Incorporate miscellaneous Asc Library bug fixes and new microcode.
385 6. Change driver versioning to be specific to each Linux sub-level.
386 7. Change statistics gathering to be per adapter instead of global
387 to the driver.
388 8. Add more information and statistics to the adapter /proc file:
389 /proc/scsi/advansys[0...].
390 9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list.
391 This problem has been addressed with the SCSI mid-level changes
392 made in v1.3.89. The advansys_select_queue_depths() function
393 was added for the v1.3.89 changes.
395 1.6 (9/10/96):
396 1. Incorporate miscellaneous Asc Library bug fixes and new microcode.
398 1.7 (9/25/96):
399 1. Enable clustering and optimize the setting of the maximum number
400 of scatter gather elements for any particular board. Clustering
401 increases CPU utilization, but results in a relatively larger
402 increase in I/O throughput.
403 2. Improve the performance of the request queuing functions by
404 adding a last pointer to the queue structure.
405 3. Correct problems with reset and abort request handling that
406 could have hung or crashed Linux.
407 4. Add more information to the adapter /proc file:
408 /proc/scsi/advansys[0...].
409 5. Remove the request timeout issue form the driver issues list.
410 6. Miscellaneous documentation additions and changes.
412 1.8 (10/4/96):
413 1. Make changes to handle the new v2.1.0 kernel memory mapping
414 in which a kernel virtual address may not be equivalent to its
415 bus or DMA memory address.
416 2. Change abort and reset request handling to make it yet even
417 more robust.
418 3. Try to mitigate request starvation by sending ordered requests
419 to heavily loaded, tag queuing enabled devices.
420 4. Maintain statistics on request response time.
421 5. Add request response time statistics and other information to
422 the adapter /proc file: /proc/scsi/advansys[0...].
424 1.9 (10/21/96):
425 1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to
426 make use of mid-level SCSI driver device queue depth flow
427 control mechanism. This will eliminate aborts caused by a
428 device being unable to keep up with requests and eliminate
429 repeat busy or QUEUE FULL status returned by a device.
430 2. Incorporate miscellaneous Asc Library bug fixes.
431 3. To allow the driver to work in kernels with broken module
432 support set 'cmd_per_lun' if the driver is compiled as a
433 module. This change affects kernels v1.3.89 to present.
434 4. Remove PCI BIOS address from the driver banner. The PCI BIOS
435 is relocated by the motherboard BIOS and its new address can
436 not be determined by the driver.
437 5. Add mid-level SCSI queue depth information to the adapter
438 /proc file: /proc/scsi/advansys[0...].
440 2.0 (11/14/96):
441 1. Change allocation of global structures used for device
442 initialization to guarantee they are in DMA-able memory.
443 Previously when the driver was loaded as a module these
444 structures might not have been in DMA-able memory, causing
445 device initialization to fail.
447 2.1 (12/30/96):
448 1. In advansys_reset(), if the request is a synchronous reset
449 request, even if the request serial number has changed, then
450 complete the request.
451 2. Add Asc Library bug fixes including new microcode.
452 3. Clear inquiry buffer before using it.
453 4. Correct ifdef typo.
455 2.2 (1/15/97):
456 1. Add Asc Library bug fixes including new microcode.
457 2. Add synchronous data transfer rate information to the
458 adapter /proc file: /proc/scsi/advansys[0...].
459 3. Change ADVANSYS_DEBUG to be disabled by default. This
460 will reduce the size of the driver image, eliminate execution
461 overhead, and remove unneeded symbols from the kernel symbol
462 space that were previously added by the driver.
463 4. Add new compile-time option ADVANSYS_ASSERT for assertion
464 code that used to be defined within ADVANSYS_DEBUG. This
465 option is enabled by default.
467 2.8 (5/26/97):
468 1. Change version number to 2.8 to synchronize the Linux driver
469 version numbering with other AdvanSys drivers.
470 2. Reformat source files without tabs to present the same view
471 of the file to everyone regardless of the editor tab setting
472 being used.
473 3. Add Asc Library bug fixes.
475 3.1A (1/8/98):
476 1. Change version number to 3.1 to indicate that support for
477 Ultra-Wide adapters (ABP-940UW) is included in this release.
478 2. Add Asc Library (Narrow Board) bug fixes.
479 3. Report an underrun condition with the host status byte set
480 to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which
481 causes the underrun condition to be ignored. When Linux defines
482 its own DID_UNDERRUN the constant defined in this file can be
483 removed.
484 4. Add patch to AscWaitTixISRDone().
485 5. Add support for up to 16 different AdvanSys host adapter SCSI
486 channels in one system. This allows four cards with four channels
487 to be used in one system.
489 3.1B (1/9/98):
490 1. Handle that PCI register base addresses are not always page
491 aligned even though ioremap() requires that the address argument
492 be page aligned.
494 3.1C (1/10/98):
495 1. Update latest BIOS version checked for from the /proc file.
496 2. Don't set microcode SDTR variable at initialization. Instead
497 wait until device capabilities have been detected from an Inquiry
498 command.
500 3.1D (1/21/98):
501 1. Improve performance when the driver is compiled as module by
502 allowing up to 64 scatter-gather elements instead of 8.
504 3.1E (5/1/98):
505 1. Set time delay in AscWaitTixISRDone() to 1000 ms.
506 2. Include SMP locking changes.
507 3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS
508 access functions.
509 4. Update board serial number printing.
510 5. Try allocating an IRQ both with and without the IRQF_DISABLED
511 flag set to allow IRQ sharing with drivers that do not set
512 the IRQF_DISABLED flag. Also display a more descriptive error
513 message if request_irq() fails.
514 6. Update to latest Asc and Adv Libraries.
516 3.2A (7/22/99):
517 1. Update Adv Library to 4.16 which includes support for
518 the ASC38C0800 (Ultra2/LVD) IC.
520 3.2B (8/23/99):
521 1. Correct PCI compile time option for v2.1.93 and greater
522 kernels, advansys_info() string, and debug compile time
523 option.
524 2. Correct DvcSleepMilliSecond() for v2.1.0 and greater
525 kernels. This caused an LVD detection/BIST problem problem
526 among other things.
527 3. Sort PCI cards by PCI Bus, Slot, Function ascending order
528 to be consistent with the BIOS.
529 4. Update to Asc Library S121 and Adv Library 5.2.
531 3.2C (8/24/99):
532 1. Correct PCI card detection bug introduced in 3.2B that
533 prevented PCI cards from being detected in kernels older
534 than v2.1.93.
536 3.2D (8/26/99):
537 1. Correct /proc device synchronous speed information display.
538 Also when re-negotiation is pending for a target device
539 note this condition with an * and footnote.
540 2. Correct initialization problem with Ultra-Wide cards that
541 have a pre-3.2 BIOS. A microcode variable changed locations
542 in 3.2 and greater BIOSes which caused WDTR to be attempted
543 erroneously with drives that don't support WDTR.
545 3.2E (8/30/99):
546 1. Fix compile error caused by v2.3.13 PCI structure change.
547 2. Remove field from ASCEEP_CONFIG that resulted in an EEPROM
548 checksum error for ISA cards.
549 3. Remove ASC_QUEUE_FLOW_CONTROL conditional code. The mid-level
550 SCSI changes that it depended on were never included in Linux.
552 3.2F (9/3/99):
553 1. Handle new initial function code added in v2.3.16 for all
554 driver versions.
556 3.2G (9/8/99):
557 1. Fix PCI board detection in v2.3.13 and greater kernels.
558 2. Fix comiple errors in v2.3.X with debugging enabled.
560 3.2H (9/13/99):
561 1. Add 64-bit address, long support for Alpha and UltraSPARC.
562 The driver has been verified to work on an Alpha system.
563 2. Add partial byte order handling support for Power PC and
564 other big-endian platforms. This support has not yet been
565 completed or verified.
566 3. For wide boards replace block zeroing of request and
567 scatter-gather structures with individual field initialization
568 to improve performance.
569 4. Correct and clarify ROM BIOS version detection.
571 3.2I (10/8/99):
572 1. Update to Adv Library 5.4.
573 2. Add v2.3.19 underrun reporting to asc_isr_callback() and
574 adv_isr_callback(). Remove DID_UNDERRUN constant and other
575 no longer needed code that previously documented the lack
576 of underrun handling.
578 3.2J (10/14/99):
579 1. Eliminate compile errors for v2.0 and earlier kernels.
581 3.2K (11/15/99):
582 1. Correct debug compile error in asc_prt_adv_scsi_req_q().
583 2. Update Adv Library to 5.5.
584 3. Add ifdef handling for /proc changes added in v2.3.28.
585 4. Increase Wide board scatter-gather list maximum length to
586 255 when the driver is compiled into the kernel.
588 3.2L (11/18/99):
589 1. Fix bug in adv_get_sglist() that caused an assertion failure
590 at line 7475. The reqp->sgblkp pointer must be initialized
591 to NULL in adv_get_sglist().
593 3.2M (11/29/99):
594 1. Really fix bug in adv_get_sglist().
595 2. Incorporate v2.3.29 changes into driver.
597 3.2N (4/1/00):
598 1. Add CONFIG_ISA ifdef code.
599 2. Include advansys_interrupts_enabled name change patch.
600 3. For >= v2.3.28 use new SCSI error handling with new function
601 advansys_eh_bus_reset(). Don't include an abort function
602 because of base library limitations.
603 4. For >= v2.3.28 use per board lock instead of io_request_lock.
604 5. For >= v2.3.28 eliminate advansys_command() and
605 advansys_command_done().
606 6. Add some changes for PowerPC (Big Endian) support, but it isn't
607 working yet.
608 7. Fix "nonexistent resource free" problem that occurred on a module
609 unload for boards with an I/O space >= 255. The 'n_io_port' field
610 is only one byte and can not be used to hold an ioport length more
611 than 255.
613 3.3A (4/4/00):
614 1. Update to Adv Library 5.8.
615 2. For wide cards add support for CDBs up to 16 bytes.
616 3. Eliminate warnings when CONFIG_PROC_FS is not defined.
618 3.3B (5/1/00):
619 1. Support for PowerPC (Big Endian) wide cards. Narrow cards
620 still need work.
621 2. Change bitfields to shift and mask access for endian
622 portability.
624 3.3C (10/13/00):
625 1. Update for latest 2.4 kernel.
626 2. Test ABP-480 CardBus support in 2.4 kernel - works!
627 3. Update to Asc Library S123.
628 4. Update to Adv Library 5.12.
630 3.3D (11/22/00):
631 1. Update for latest 2.4 kernel.
632 2. Create patches for 2.2 and 2.4 kernels.
634 3.3E (1/9/01):
635 1. Now that 2.4 is released remove ifdef code for kernel versions
636 less than 2.2. The driver is now only supported in kernels 2.2,
637 2.4, and greater.
638 2. Add code to release and acquire the io_request_lock in
639 the driver entrypoint functions: advansys_detect and
640 advansys_queuecommand. In kernel 2.4 the SCSI mid-level driver
641 still holds the io_request_lock on entry to SCSI low-level drivers.
642 This was supposed to be removed before 2.4 was released but never
643 happened. When the mid-level SCSI driver is changed all references
644 to the io_request_lock should be removed from the driver.
645 3. Simplify error handling by removing advansys_abort(),
646 AscAbortSRB(), AscResetDevice(). SCSI bus reset requests are
647 now handled by resetting the SCSI bus and fully re-initializing
648 the chip. This simple method of error recovery has proven to work
649 most reliably after attempts at different methods. Also now only
650 support the "new" error handling method and remove the obsolete
651 error handling interface.
652 4. Fix debug build errors.
654 3.3F (1/24/01):
655 1. Merge with ConnectCom version from Andy Kellner which
656 updates Adv Library to 5.14.
657 2. Make PowerPC (Big Endian) work for narrow cards and
658 fix problems writing EEPROM for wide cards.
659 3. Remove interrupts_enabled assertion function.
661 3.3G (2/16/01):
662 1. Return an error from narrow boards if passed a 16 byte
663 CDB. The wide board can already handle 16 byte CDBs.
665 3.3GJ (4/15/02):
666 1. hacks for lk 2.5 series (D. Gilbert)
668 3.3GJD (10/14/02):
669 1. change select_queue_depths to slave_configure
670 2. make cmd_per_lun be sane again
672 3.3K [2004/06/24]:
673 1. continuing cleanup for lk 2.6 series
674 2. Fix problem in lk 2.6.7-bk2 that broke PCI wide cards
675 3. Fix problem that oopsed ISA cards
677 I. Known Problems/Fix List (XXX)
679 1. Need to add memory mapping workaround. Test the memory mapping.
680 If it doesn't work revert to I/O port access. Can a test be done
681 safely?
682 2. Handle an interrupt not working. Keep an interrupt counter in
683 the interrupt handler. In the timeout function if the interrupt
684 has not occurred then print a message and run in polled mode.
685 3. Allow bus type scanning order to be changed.
686 4. Need to add support for target mode commands, cf. CAM XPT.
688 J. Credits (Chronological Order)
690 Bob Frey <bfrey@turbolinux.com.cn> wrote the AdvanSys SCSI driver
691 and maintained it up to 3.3F. He continues to answer questions
692 and help maintain the driver.
694 Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and
695 basis for the Linux v1.3.X changes which were included in the
696 1.2 release.
698 Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug
699 in advansys_biosparam() which was fixed in the 1.3 release.
701 Erik Ratcliffe <erik@caldera.com> has done testing of the
702 AdvanSys driver in the Caldera releases.
704 Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to
705 AscWaitTixISRDone() which he found necessary to make the
706 driver work with a SCSI-1 disk.
708 Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide
709 support in the 3.1A driver.
711 Doug Gilbert <dgilbert@interlog.com> has made changes and
712 suggestions to improve the driver and done a lot of testing.
714 Ken Mort <ken@mort.net> reported a DEBUG compile bug fixed
715 in 3.2K.
717 Tom Rini <trini@kernel.crashing.org> provided the CONFIG_ISA
718 patch and helped with PowerPC wide and narrow board support.
720 Philip Blundell <philb@gnu.org> provided an
721 advansys_interrupts_enabled patch.
723 Dave Jones <dave@denial.force9.co.uk> reported the compiler
724 warnings generated when CONFIG_PROC_FS was not defined in
725 the 3.2M driver.
727 Jerry Quinn <jlquinn@us.ibm.com> fixed PowerPC support (endian
728 problems) for wide cards.
730 Bryan Henderson <bryanh@giraffe-data.com> helped debug narrow
731 card error handling.
733 Manuel Veloso <veloso@pobox.com> worked hard on PowerPC narrow
734 board support and fixed a bug in AscGetEEPConfig().
736 Arnaldo Carvalho de Melo <acme@conectiva.com.br> made
737 save_flags/restore_flags changes.
739 Andy Kellner <AKellner@connectcom.net> continues the Advansys SCSI
740 driver development for ConnectCom (Version > 3.3F).
742 K. ConnectCom (AdvanSys) Contact Information
744 Mail: ConnectCom Solutions, Inc.
745 1150 Ringwood Court
746 San Jose, CA 95131
747 Operator/Sales: 1-408-383-9400
748 FAX: 1-408-383-9612
749 Tech Support: 1-408-467-2930
750 Tech Support E-Mail: linux@connectcom.net
751 FTP Site: ftp.connectcom.net (login: anonymous)
752 Web Site: http://www.connectcom.net
757 * --- Linux Include Files
760 #include <linux/module.h>
761 #include <linux/string.h>
762 #include <linux/kernel.h>
763 #include <linux/types.h>
764 #include <linux/ioport.h>
765 #include <linux/interrupt.h>
766 #include <linux/delay.h>
767 #include <linux/slab.h>
768 #include <linux/mm.h>
769 #include <linux/proc_fs.h>
770 #include <linux/init.h>
771 #include <linux/blkdev.h>
772 #include <linux/isa.h>
773 #include <linux/eisa.h>
774 #include <linux/pci.h>
775 #include <linux/spinlock.h>
776 #include <linux/dma-mapping.h>
778 #include <asm/io.h>
779 #include <asm/system.h>
780 #include <asm/dma.h>
782 #include <scsi/scsi_cmnd.h>
783 #include <scsi/scsi_device.h>
784 #include <scsi/scsi_tcq.h>
785 #include <scsi/scsi.h>
786 #include <scsi/scsi_host.h>
788 /* FIXME: (by jejb@steeleye.com)
790 * Although all of the necessary command mapping places have the
791 * appropriate dma_map.. APIs, the driver still processes its internal
792 * queue using bus_to_virt() and virt_to_bus() which are illegal under
793 * the API. The entire queue processing structure will need to be
794 * altered to fix this.
796 #warning this driver is still not properly converted to the DMA API
799 * --- Driver Options
802 /* Enable driver assertions. */
803 #define ADVANSYS_ASSERT
805 /* Enable driver /proc statistics. */
806 #define ADVANSYS_STATS
808 /* Enable driver tracing. */
809 /* #define ADVANSYS_DEBUG */
812 * --- Asc Library Constants and Macros
815 #define ASC_LIB_VERSION_MAJOR 1
816 #define ASC_LIB_VERSION_MINOR 24
817 #define ASC_LIB_SERIAL_NUMBER 123
820 * Portable Data Types
822 * Any instance where a 32-bit long or pointer type is assumed
823 * for precision or HW defined structures, the following define
824 * types must be used. In Linux the char, short, and int types
825 * are all consistent at 8, 16, and 32 bits respectively. Pointers
826 * and long types are 64 bits on Alpha and UltraSPARC.
828 #define ASC_PADDR __u32 /* Physical/Bus address data type. */
829 #define ASC_VADDR __u32 /* Virtual address data type. */
830 #define ASC_DCNT __u32 /* Unsigned Data count type. */
831 #define ASC_SDCNT __s32 /* Signed Data count type. */
834 * These macros are used to convert a virtual address to a
835 * 32-bit value. This currently can be used on Linux Alpha
836 * which uses 64-bit virtual address but a 32-bit bus address.
837 * This is likely to break in the future, but doing this now
838 * will give us time to change the HW and FW to handle 64-bit
839 * addresses.
841 #define ASC_VADDR_TO_U32 virt_to_bus
842 #define ASC_U32_TO_VADDR bus_to_virt
844 typedef unsigned char uchar;
846 #ifndef TRUE
847 #define TRUE (1)
848 #endif
849 #ifndef FALSE
850 #define FALSE (0)
851 #endif
853 #define EOF (-1)
854 #define ERR (-1)
855 #define UW_ERR (uint)(0xFFFF)
856 #define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
857 #define ASC_PCI_ID2FUNC(id) (((id) >> 8) & 0x7)
858 #define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
860 #define ASC_DVCLIB_CALL_DONE (1)
861 #define ASC_DVCLIB_CALL_FAILED (0)
862 #define ASC_DVCLIB_CALL_ERROR (-1)
864 #define PCI_VENDOR_ID_ASP 0x10cd
865 #define PCI_DEVICE_ID_ASP_1200A 0x1100
866 #define PCI_DEVICE_ID_ASP_ABP940 0x1200
867 #define PCI_DEVICE_ID_ASP_ABP940U 0x1300
868 #define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
869 #define PCI_DEVICE_ID_38C0800_REV1 0x2500
870 #define PCI_DEVICE_ID_38C1600_REV1 0x2700
873 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
874 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
875 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
876 * SRB structure.
878 #define CC_VERY_LONG_SG_LIST 0
879 #define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
881 #define PortAddr unsigned short /* port address size */
882 #define inp(port) inb(port)
883 #define outp(port, byte) outb((byte), (port))
885 #define inpw(port) inw(port)
886 #define outpw(port, word) outw((word), (port))
888 #define ASC_MAX_SG_QUEUE 7
889 #define ASC_MAX_SG_LIST 255
891 #define ASC_CS_TYPE unsigned short
893 #define ASC_IS_ISA (0x0001)
894 #define ASC_IS_ISAPNP (0x0081)
895 #define ASC_IS_EISA (0x0002)
896 #define ASC_IS_PCI (0x0004)
897 #define ASC_IS_PCI_ULTRA (0x0104)
898 #define ASC_IS_PCMCIA (0x0008)
899 #define ASC_IS_MCA (0x0020)
900 #define ASC_IS_VL (0x0040)
901 #define ASC_ISA_PNP_PORT_ADDR (0x279)
902 #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
903 #define ASC_IS_WIDESCSI_16 (0x0100)
904 #define ASC_IS_WIDESCSI_32 (0x0200)
905 #define ASC_IS_BIG_ENDIAN (0x8000)
906 #define ASC_CHIP_MIN_VER_VL (0x01)
907 #define ASC_CHIP_MAX_VER_VL (0x07)
908 #define ASC_CHIP_MIN_VER_PCI (0x09)
909 #define ASC_CHIP_MAX_VER_PCI (0x0F)
910 #define ASC_CHIP_VER_PCI_BIT (0x08)
911 #define ASC_CHIP_MIN_VER_ISA (0x11)
912 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
913 #define ASC_CHIP_MAX_VER_ISA (0x27)
914 #define ASC_CHIP_VER_ISA_BIT (0x30)
915 #define ASC_CHIP_VER_ISAPNP_BIT (0x20)
916 #define ASC_CHIP_VER_ASYN_BUG (0x21)
917 #define ASC_CHIP_VER_PCI 0x08
918 #define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
919 #define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
920 #define ASC_CHIP_MIN_VER_EISA (0x41)
921 #define ASC_CHIP_MAX_VER_EISA (0x47)
922 #define ASC_CHIP_VER_EISA_BIT (0x40)
923 #define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
924 #define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER 0x21
925 #define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER 0x0A
926 #define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL)
927 #define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
928 #define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL)
929 #define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
930 #define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL)
931 #define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
932 #define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL)
933 #define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL)
935 #define ASC_SCSI_ID_BITS 3
936 #define ASC_SCSI_TIX_TYPE uchar
937 #define ASC_ALL_DEVICE_BIT_SET 0xFF
938 #define ASC_SCSI_BIT_ID_TYPE uchar
939 #define ASC_MAX_TID 7
940 #define ASC_MAX_LUN 7
941 #define ASC_SCSI_WIDTH_BIT_SET 0xFF
942 #define ASC_MAX_SENSE_LEN 32
943 #define ASC_MIN_SENSE_LEN 14
944 #define ASC_MAX_CDB_LEN 12
945 #define ASC_SCSI_RESET_HOLD_TIME_US 60
948 * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
949 * and CmdDt (Command Support Data) field bit definitions.
951 #define ADV_INQ_RTN_VPD_AND_CMDDT 0x3
952 #define ADV_INQ_RTN_CMDDT_FOR_OP_CODE 0x2
953 #define ADV_INQ_RTN_VPD_FOR_PG_CODE 0x1
954 #define ADV_INQ_RTN_STD_INQUIRY_DATA 0x0
956 #define ASC_SCSIDIR_NOCHK 0x00
957 #define ASC_SCSIDIR_T2H 0x08
958 #define ASC_SCSIDIR_H2T 0x10
959 #define ASC_SCSIDIR_NODATA 0x18
960 #define SCSI_ASC_NOMEDIA 0x3A
961 #define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4))
962 #define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F))
963 #define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13))
964 #define PUT_CDB1(x) ((uchar)((uint)(x) >> 8))
965 #define MS_SDTR_LEN 0x03
966 #define MS_WDTR_LEN 0x02
968 #define ASC_SG_LIST_PER_Q 7
969 #define QS_FREE 0x00
970 #define QS_READY 0x01
971 #define QS_DISC1 0x02
972 #define QS_DISC2 0x04
973 #define QS_BUSY 0x08
974 #define QS_ABORTED 0x40
975 #define QS_DONE 0x80
976 #define QC_NO_CALLBACK 0x01
977 #define QC_SG_SWAP_QUEUE 0x02
978 #define QC_SG_HEAD 0x04
979 #define QC_DATA_IN 0x08
980 #define QC_DATA_OUT 0x10
981 #define QC_URGENT 0x20
982 #define QC_MSG_OUT 0x40
983 #define QC_REQ_SENSE 0x80
984 #define QCSG_SG_XFER_LIST 0x02
985 #define QCSG_SG_XFER_MORE 0x04
986 #define QCSG_SG_XFER_END 0x08
987 #define QD_IN_PROGRESS 0x00
988 #define QD_NO_ERROR 0x01
989 #define QD_ABORTED_BY_HOST 0x02
990 #define QD_WITH_ERROR 0x04
991 #define QD_INVALID_REQUEST 0x80
992 #define QD_INVALID_HOST_NUM 0x81
993 #define QD_INVALID_DEVICE 0x82
994 #define QD_ERR_INTERNAL 0xFF
995 #define QHSTA_NO_ERROR 0x00
996 #define QHSTA_M_SEL_TIMEOUT 0x11
997 #define QHSTA_M_DATA_OVER_RUN 0x12
998 #define QHSTA_M_DATA_UNDER_RUN 0x12
999 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
1000 #define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
1001 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1002 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
1003 #define QHSTA_D_HOST_ABORT_FAILED 0x23
1004 #define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
1005 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1006 #define QHSTA_D_ASPI_NO_BUF_POOL 0x26
1007 #define QHSTA_M_WTM_TIMEOUT 0x41
1008 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
1009 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
1010 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1011 #define QHSTA_M_TARGET_STATUS_BUSY 0x45
1012 #define QHSTA_M_BAD_TAG_CODE 0x46
1013 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
1014 #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1015 #define QHSTA_D_LRAM_CMP_ERROR 0x81
1016 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1017 #define ASC_FLAG_SCSIQ_REQ 0x01
1018 #define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
1019 #define ASC_FLAG_BIOS_ASYNC_IO 0x04
1020 #define ASC_FLAG_SRB_LINEAR_ADDR 0x08
1021 #define ASC_FLAG_WIN16 0x10
1022 #define ASC_FLAG_WIN32 0x20
1023 #define ASC_FLAG_ISA_OVER_16MB 0x40
1024 #define ASC_FLAG_DOS_VM_CALLBACK 0x80
1025 #define ASC_TAG_FLAG_EXTRA_BYTES 0x10
1026 #define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
1027 #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
1028 #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1029 #define ASC_SCSIQ_CPY_BEG 4
1030 #define ASC_SCSIQ_SGHD_CPY_BEG 2
1031 #define ASC_SCSIQ_B_FWD 0
1032 #define ASC_SCSIQ_B_BWD 1
1033 #define ASC_SCSIQ_B_STATUS 2
1034 #define ASC_SCSIQ_B_QNO 3
1035 #define ASC_SCSIQ_B_CNTL 4
1036 #define ASC_SCSIQ_B_SG_QUEUE_CNT 5
1037 #define ASC_SCSIQ_D_DATA_ADDR 8
1038 #define ASC_SCSIQ_D_DATA_CNT 12
1039 #define ASC_SCSIQ_B_SENSE_LEN 20
1040 #define ASC_SCSIQ_DONE_INFO_BEG 22
1041 #define ASC_SCSIQ_D_SRBPTR 22
1042 #define ASC_SCSIQ_B_TARGET_IX 26
1043 #define ASC_SCSIQ_B_CDB_LEN 28
1044 #define ASC_SCSIQ_B_TAG_CODE 29
1045 #define ASC_SCSIQ_W_VM_ID 30
1046 #define ASC_SCSIQ_DONE_STATUS 32
1047 #define ASC_SCSIQ_HOST_STATUS 33
1048 #define ASC_SCSIQ_SCSI_STATUS 34
1049 #define ASC_SCSIQ_CDB_BEG 36
1050 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1051 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
1052 #define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
1053 #define ASC_SCSIQ_B_SG_WK_QP 49
1054 #define ASC_SCSIQ_B_SG_WK_IX 50
1055 #define ASC_SCSIQ_W_ALT_DC1 52
1056 #define ASC_SCSIQ_B_LIST_CNT 6
1057 #define ASC_SCSIQ_B_CUR_LIST_CNT 7
1058 #define ASC_SGQ_B_SG_CNTL 4
1059 #define ASC_SGQ_B_SG_HEAD_QP 5
1060 #define ASC_SGQ_B_SG_LIST_CNT 6
1061 #define ASC_SGQ_B_SG_CUR_LIST_CNT 7
1062 #define ASC_SGQ_LIST_BEG 8
1063 #define ASC_DEF_SCSI1_QNG 4
1064 #define ASC_MAX_SCSI1_QNG 4
1065 #define ASC_DEF_SCSI2_QNG 16
1066 #define ASC_MAX_SCSI2_QNG 32
1067 #define ASC_TAG_CODE_MASK 0x23
1068 #define ASC_STOP_REQ_RISC_STOP 0x01
1069 #define ASC_STOP_ACK_RISC_STOP 0x03
1070 #define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
1071 #define ASC_STOP_CLEAN_UP_DISC_Q 0x20
1072 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1073 #define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1074 #define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1075 #define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
1076 #define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
1077 #define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
1078 #define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1079 #define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
1081 typedef struct asc_scsiq_1 {
1082 uchar status;
1083 uchar q_no;
1084 uchar cntl;
1085 uchar sg_queue_cnt;
1086 uchar target_id;
1087 uchar target_lun;
1088 ASC_PADDR data_addr;
1089 ASC_DCNT data_cnt;
1090 ASC_PADDR sense_addr;
1091 uchar sense_len;
1092 uchar extra_bytes;
1093 } ASC_SCSIQ_1;
1095 typedef struct asc_scsiq_2 {
1096 ASC_VADDR srb_ptr;
1097 uchar target_ix;
1098 uchar flag;
1099 uchar cdb_len;
1100 uchar tag_code;
1101 ushort vm_id;
1102 } ASC_SCSIQ_2;
1104 typedef struct asc_scsiq_3 {
1105 uchar done_stat;
1106 uchar host_stat;
1107 uchar scsi_stat;
1108 uchar scsi_msg;
1109 } ASC_SCSIQ_3;
1111 typedef struct asc_scsiq_4 {
1112 uchar cdb[ASC_MAX_CDB_LEN];
1113 uchar y_first_sg_list_qp;
1114 uchar y_working_sg_qp;
1115 uchar y_working_sg_ix;
1116 uchar y_res;
1117 ushort x_req_count;
1118 ushort x_reconnect_rtn;
1119 ASC_PADDR x_saved_data_addr;
1120 ASC_DCNT x_saved_data_cnt;
1121 } ASC_SCSIQ_4;
1123 typedef struct asc_q_done_info {
1124 ASC_SCSIQ_2 d2;
1125 ASC_SCSIQ_3 d3;
1126 uchar q_status;
1127 uchar q_no;
1128 uchar cntl;
1129 uchar sense_len;
1130 uchar extra_bytes;
1131 uchar res;
1132 ASC_DCNT remain_bytes;
1133 } ASC_QDONE_INFO;
1135 typedef struct asc_sg_list {
1136 ASC_PADDR addr;
1137 ASC_DCNT bytes;
1138 } ASC_SG_LIST;
1140 typedef struct asc_sg_head {
1141 ushort entry_cnt;
1142 ushort queue_cnt;
1143 ushort entry_to_copy;
1144 ushort res;
1145 ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1146 } ASC_SG_HEAD;
1148 #define ASC_MIN_SG_LIST 2
1150 typedef struct asc_min_sg_head {
1151 ushort entry_cnt;
1152 ushort queue_cnt;
1153 ushort entry_to_copy;
1154 ushort res;
1155 ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
1156 } ASC_MIN_SG_HEAD;
1158 #define QCX_SORT (0x0001)
1159 #define QCX_COALEASE (0x0002)
1161 typedef struct asc_scsi_q {
1162 ASC_SCSIQ_1 q1;
1163 ASC_SCSIQ_2 q2;
1164 uchar *cdbptr;
1165 ASC_SG_HEAD *sg_head;
1166 ushort remain_sg_entry_cnt;
1167 ushort next_sg_index;
1168 } ASC_SCSI_Q;
1170 typedef struct asc_scsi_req_q {
1171 ASC_SCSIQ_1 r1;
1172 ASC_SCSIQ_2 r2;
1173 uchar *cdbptr;
1174 ASC_SG_HEAD *sg_head;
1175 uchar *sense_ptr;
1176 ASC_SCSIQ_3 r3;
1177 uchar cdb[ASC_MAX_CDB_LEN];
1178 uchar sense[ASC_MIN_SENSE_LEN];
1179 } ASC_SCSI_REQ_Q;
1181 typedef struct asc_scsi_bios_req_q {
1182 ASC_SCSIQ_1 r1;
1183 ASC_SCSIQ_2 r2;
1184 uchar *cdbptr;
1185 ASC_SG_HEAD *sg_head;
1186 uchar *sense_ptr;
1187 ASC_SCSIQ_3 r3;
1188 uchar cdb[ASC_MAX_CDB_LEN];
1189 uchar sense[ASC_MIN_SENSE_LEN];
1190 } ASC_SCSI_BIOS_REQ_Q;
1192 typedef struct asc_risc_q {
1193 uchar fwd;
1194 uchar bwd;
1195 ASC_SCSIQ_1 i1;
1196 ASC_SCSIQ_2 i2;
1197 ASC_SCSIQ_3 i3;
1198 ASC_SCSIQ_4 i4;
1199 } ASC_RISC_Q;
1201 typedef struct asc_sg_list_q {
1202 uchar seq_no;
1203 uchar q_no;
1204 uchar cntl;
1205 uchar sg_head_qp;
1206 uchar sg_list_cnt;
1207 uchar sg_cur_list_cnt;
1208 } ASC_SG_LIST_Q;
1210 typedef struct asc_risc_sg_list_q {
1211 uchar fwd;
1212 uchar bwd;
1213 ASC_SG_LIST_Q sg;
1214 ASC_SG_LIST sg_list[7];
1215 } ASC_RISC_SG_LIST_Q;
1217 #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL
1218 #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024
1219 #define ASCQ_ERR_NO_ERROR 0
1220 #define ASCQ_ERR_IO_NOT_FOUND 1
1221 #define ASCQ_ERR_LOCAL_MEM 2
1222 #define ASCQ_ERR_CHKSUM 3
1223 #define ASCQ_ERR_START_CHIP 4
1224 #define ASCQ_ERR_INT_TARGET_ID 5
1225 #define ASCQ_ERR_INT_LOCAL_MEM 6
1226 #define ASCQ_ERR_HALT_RISC 7
1227 #define ASCQ_ERR_GET_ASPI_ENTRY 8
1228 #define ASCQ_ERR_CLOSE_ASPI 9
1229 #define ASCQ_ERR_HOST_INQUIRY 0x0A
1230 #define ASCQ_ERR_SAVED_SRB_BAD 0x0B
1231 #define ASCQ_ERR_QCNTL_SG_LIST 0x0C
1232 #define ASCQ_ERR_Q_STATUS 0x0D
1233 #define ASCQ_ERR_WR_SCSIQ 0x0E
1234 #define ASCQ_ERR_PC_ADDR 0x0F
1235 #define ASCQ_ERR_SYN_OFFSET 0x10
1236 #define ASCQ_ERR_SYN_XFER_TIME 0x11
1237 #define ASCQ_ERR_LOCK_DMA 0x12
1238 #define ASCQ_ERR_UNLOCK_DMA 0x13
1239 #define ASCQ_ERR_VDS_CHK_INSTALL 0x14
1240 #define ASCQ_ERR_MICRO_CODE_HALT 0x15
1241 #define ASCQ_ERR_SET_LRAM_ADDR 0x16
1242 #define ASCQ_ERR_CUR_QNG 0x17
1243 #define ASCQ_ERR_SG_Q_LINKS 0x18
1244 #define ASCQ_ERR_SCSIQ_PTR 0x19
1245 #define ASCQ_ERR_ISR_RE_ENTRY 0x1A
1246 #define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
1247 #define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
1248 #define ASCQ_ERR_SG_LIST_ODD_ADDRESS 0x1D
1249 #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1250 #define ASCQ_ERR_SCSIQ_NULL_PTR 0x1F
1251 #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR 0x20
1252 #define ASCQ_ERR_GET_NUM_OF_FREE_Q 0x21
1253 #define ASCQ_ERR_SEND_SCSI_Q 0x22
1254 #define ASCQ_ERR_HOST_REQ_RISC_HALT 0x23
1255 #define ASCQ_ERR_RESET_SDTR 0x24
1258 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
1260 #define ASC_WARN_NO_ERROR 0x0000
1261 #define ASC_WARN_IO_PORT_ROTATE 0x0001
1262 #define ASC_WARN_EEPROM_CHKSUM 0x0002
1263 #define ASC_WARN_IRQ_MODIFIED 0x0004
1264 #define ASC_WARN_AUTO_CONFIG 0x0008
1265 #define ASC_WARN_CMD_QNG_CONFLICT 0x0010
1266 #define ASC_WARN_EEPROM_RECOVER 0x0020
1267 #define ASC_WARN_CFG_MSW_RECOVER 0x0040
1268 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1271 * Error code values are set in ASC_DVC_VAR 'err_code'.
1273 #define ASC_IERR_WRITE_EEPROM 0x0001
1274 #define ASC_IERR_MCODE_CHKSUM 0x0002
1275 #define ASC_IERR_SET_PC_ADDR 0x0004
1276 #define ASC_IERR_START_STOP_CHIP 0x0008
1277 #define ASC_IERR_IRQ_NO 0x0010
1278 #define ASC_IERR_SET_IRQ_NO 0x0020
1279 #define ASC_IERR_CHIP_VERSION 0x0040
1280 #define ASC_IERR_SET_SCSI_ID 0x0080
1281 #define ASC_IERR_GET_PHY_ADDR 0x0100
1282 #define ASC_IERR_BAD_SIGNATURE 0x0200
1283 #define ASC_IERR_NO_BUS_TYPE 0x0400
1284 #define ASC_IERR_SCAM 0x0800
1285 #define ASC_IERR_SET_SDTR 0x1000
1286 #define ASC_IERR_RW_LRAM 0x8000
1288 #define ASC_DEF_IRQ_NO 10
1289 #define ASC_MAX_IRQ_NO 15
1290 #define ASC_MIN_IRQ_NO 10
1291 #define ASC_MIN_REMAIN_Q (0x02)
1292 #define ASC_DEF_MAX_TOTAL_QNG (0xF0)
1293 #define ASC_MIN_TAG_Q_PER_DVC (0x04)
1294 #define ASC_DEF_TAG_Q_PER_DVC (0x04)
1295 #define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q
1296 #define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1297 #define ASC_MAX_TOTAL_QNG 240
1298 #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1299 #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
1300 #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
1301 #define ASC_MAX_INRAM_TAG_QNG 16
1302 #define ASC_IOADR_TABLE_MAX_IX 11
1303 #define ASC_IOADR_GAP 0x10
1304 #define ASC_LIB_SCSIQ_WK_SP 256
1305 #define ASC_MAX_SYN_XFER_NO 16
1306 #define ASC_SYN_MAX_OFFSET 0x0F
1307 #define ASC_DEF_SDTR_OFFSET 0x0F
1308 #define ASC_DEF_SDTR_INDEX 0x00
1309 #define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
1310 #define SYN_XFER_NS_0 25
1311 #define SYN_XFER_NS_1 30
1312 #define SYN_XFER_NS_2 35
1313 #define SYN_XFER_NS_3 40
1314 #define SYN_XFER_NS_4 50
1315 #define SYN_XFER_NS_5 60
1316 #define SYN_XFER_NS_6 70
1317 #define SYN_XFER_NS_7 85
1318 #define SYN_ULTRA_XFER_NS_0 12
1319 #define SYN_ULTRA_XFER_NS_1 19
1320 #define SYN_ULTRA_XFER_NS_2 25
1321 #define SYN_ULTRA_XFER_NS_3 32
1322 #define SYN_ULTRA_XFER_NS_4 38
1323 #define SYN_ULTRA_XFER_NS_5 44
1324 #define SYN_ULTRA_XFER_NS_6 50
1325 #define SYN_ULTRA_XFER_NS_7 57
1326 #define SYN_ULTRA_XFER_NS_8 63
1327 #define SYN_ULTRA_XFER_NS_9 69
1328 #define SYN_ULTRA_XFER_NS_10 75
1329 #define SYN_ULTRA_XFER_NS_11 82
1330 #define SYN_ULTRA_XFER_NS_12 88
1331 #define SYN_ULTRA_XFER_NS_13 94
1332 #define SYN_ULTRA_XFER_NS_14 100
1333 #define SYN_ULTRA_XFER_NS_15 107
1335 typedef struct ext_msg {
1336 uchar msg_type;
1337 uchar msg_len;
1338 uchar msg_req;
1339 union {
1340 struct {
1341 uchar sdtr_xfer_period;
1342 uchar sdtr_req_ack_offset;
1343 } sdtr;
1344 struct {
1345 uchar wdtr_width;
1346 } wdtr;
1347 struct {
1348 uchar mdp_b3;
1349 uchar mdp_b2;
1350 uchar mdp_b1;
1351 uchar mdp_b0;
1352 } mdp;
1353 } u_ext_msg;
1354 uchar res;
1355 } EXT_MSG;
1357 #define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
1358 #define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
1359 #define wdtr_width u_ext_msg.wdtr.wdtr_width
1360 #define mdp_b3 u_ext_msg.mdp_b3
1361 #define mdp_b2 u_ext_msg.mdp_b2
1362 #define mdp_b1 u_ext_msg.mdp_b1
1363 #define mdp_b0 u_ext_msg.mdp_b0
1365 typedef struct asc_dvc_cfg {
1366 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1367 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1368 ASC_SCSI_BIT_ID_TYPE disc_enable;
1369 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1370 uchar chip_scsi_id;
1371 uchar isa_dma_speed;
1372 uchar isa_dma_channel;
1373 uchar chip_version;
1374 ushort lib_serial_no;
1375 ushort lib_version;
1376 ushort mcode_date;
1377 ushort mcode_version;
1378 uchar max_tag_qng[ASC_MAX_TID + 1];
1379 uchar *overrun_buf;
1380 uchar sdtr_period_offset[ASC_MAX_TID + 1];
1381 ushort pci_slot_info;
1382 uchar adapter_info[6];
1383 struct device *dev;
1384 } ASC_DVC_CFG;
1386 #define ASC_DEF_DVC_CNTL 0xFFFF
1387 #define ASC_DEF_CHIP_SCSI_ID 7
1388 #define ASC_DEF_ISA_DMA_SPEED 4
1389 #define ASC_INIT_STATE_NULL 0x0000
1390 #define ASC_INIT_STATE_BEG_GET_CFG 0x0001
1391 #define ASC_INIT_STATE_END_GET_CFG 0x0002
1392 #define ASC_INIT_STATE_BEG_SET_CFG 0x0004
1393 #define ASC_INIT_STATE_END_SET_CFG 0x0008
1394 #define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
1395 #define ASC_INIT_STATE_END_LOAD_MC 0x0020
1396 #define ASC_INIT_STATE_BEG_INQUIRY 0x0040
1397 #define ASC_INIT_STATE_END_INQUIRY 0x0080
1398 #define ASC_INIT_RESET_SCSI_DONE 0x0100
1399 #define ASC_INIT_STATE_WITHOUT_EEP 0x8000
1400 #define ASC_BUG_FIX_IF_NOT_DWB 0x0001
1401 #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
1402 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1403 #define ASC_MIN_TAGGED_CMD 7
1404 #define ASC_MAX_SCSI_RESET_WAIT 30
1406 struct asc_dvc_var; /* Forward Declaration. */
1408 typedef void (*ASC_ISR_CALLBACK) (struct asc_dvc_var *, ASC_QDONE_INFO *);
1409 typedef int (*ASC_EXE_CALLBACK) (struct asc_dvc_var *, ASC_SCSI_Q *);
1411 typedef struct asc_dvc_var {
1412 PortAddr iop_base;
1413 ushort err_code;
1414 ushort dvc_cntl;
1415 ushort bug_fix_cntl;
1416 ushort bus_type;
1417 ASC_ISR_CALLBACK isr_callback;
1418 ASC_EXE_CALLBACK exe_callback;
1419 ASC_SCSI_BIT_ID_TYPE init_sdtr;
1420 ASC_SCSI_BIT_ID_TYPE sdtr_done;
1421 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1422 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1423 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1424 ASC_SCSI_BIT_ID_TYPE start_motor;
1425 uchar scsi_reset_wait;
1426 uchar chip_no;
1427 char is_in_int;
1428 uchar max_total_qng;
1429 uchar cur_total_qng;
1430 uchar in_critical_cnt;
1431 uchar irq_no;
1432 uchar last_q_shortage;
1433 ushort init_state;
1434 uchar cur_dvc_qng[ASC_MAX_TID + 1];
1435 uchar max_dvc_qng[ASC_MAX_TID + 1];
1436 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
1437 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
1438 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1439 ASC_DVC_CFG *cfg;
1440 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1441 char redo_scam;
1442 ushort res2;
1443 uchar dos_int13_table[ASC_MAX_TID + 1];
1444 ASC_DCNT max_dma_count;
1445 ASC_SCSI_BIT_ID_TYPE no_scam;
1446 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1447 uchar max_sdtr_index;
1448 uchar host_init_sdtr_index;
1449 struct asc_board *drv_ptr;
1450 ASC_DCNT uc_break;
1451 } ASC_DVC_VAR;
1453 typedef struct asc_dvc_inq_info {
1454 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1455 } ASC_DVC_INQ_INFO;
1457 typedef struct asc_cap_info {
1458 ASC_DCNT lba;
1459 ASC_DCNT blk_size;
1460 } ASC_CAP_INFO;
1462 typedef struct asc_cap_info_array {
1463 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1464 } ASC_CAP_INFO_ARRAY;
1466 #define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
1467 #define ASC_MCNTL_NULL_TARGET (ushort)0x0002
1468 #define ASC_CNTL_INITIATOR (ushort)0x0001
1469 #define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
1470 #define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
1471 #define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
1472 #define ASC_CNTL_NO_SCAM (ushort)0x0010
1473 #define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
1474 #define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
1475 #define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
1476 #define ASC_CNTL_RESET_SCSI (ushort)0x0200
1477 #define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
1478 #define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
1479 #define ASC_CNTL_SCSI_PARITY (ushort)0x1000
1480 #define ASC_CNTL_BURST_MODE (ushort)0x2000
1481 #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1482 #define ASC_EEP_DVC_CFG_BEG_VL 2
1483 #define ASC_EEP_MAX_DVC_ADDR_VL 15
1484 #define ASC_EEP_DVC_CFG_BEG 32
1485 #define ASC_EEP_MAX_DVC_ADDR 45
1486 #define ASC_EEP_DEFINED_WORDS 10
1487 #define ASC_EEP_MAX_ADDR 63
1488 #define ASC_EEP_RES_WORDS 0
1489 #define ASC_EEP_MAX_RETRY 20
1490 #define ASC_MAX_INIT_BUSY_RETRY 8
1491 #define ASC_EEP_ISA_PNP_WSIZE 16
1494 * These macros keep the chip SCSI id and ISA DMA speed
1495 * bitfields in board order. C bitfields aren't portable
1496 * between big and little-endian platforms so they are
1497 * not used.
1500 #define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
1501 #define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
1502 #define ASC_EEP_SET_CHIP_ID(cfg, sid) \
1503 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
1504 #define ASC_EEP_SET_DMA_SPD(cfg, spd) \
1505 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
1507 typedef struct asceep_config {
1508 ushort cfg_lsw;
1509 ushort cfg_msw;
1510 uchar init_sdtr;
1511 uchar disc_enable;
1512 uchar use_cmd_qng;
1513 uchar start_motor;
1514 uchar max_total_qng;
1515 uchar max_tag_qng;
1516 uchar bios_scan;
1517 uchar power_up_wait;
1518 uchar no_scam;
1519 uchar id_speed; /* low order 4 bits is chip scsi id */
1520 /* high order 4 bits is isa dma speed */
1521 uchar dos_int13_table[ASC_MAX_TID + 1];
1522 uchar adapter_info[6];
1523 ushort cntl;
1524 ushort chksum;
1525 } ASCEEP_CONFIG;
1527 #define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800
1528 #define ASC_PCI_CFG_LSW_BURST_MODE 0x0080
1529 #define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020
1531 #define ASC_EEP_CMD_READ 0x80
1532 #define ASC_EEP_CMD_WRITE 0x40
1533 #define ASC_EEP_CMD_WRITE_ABLE 0x30
1534 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
1535 #define ASC_OVERRUN_BSIZE 0x00000048UL
1536 #define ASC_CTRL_BREAK_ONCE 0x0001
1537 #define ASC_CTRL_BREAK_STAY_IDLE 0x0002
1538 #define ASCV_MSGOUT_BEG 0x0000
1539 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1540 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1541 #define ASCV_BREAK_SAVED_CODE (ushort)0x0006
1542 #define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
1543 #define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
1544 #define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
1545 #define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
1546 #define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
1547 #define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
1548 #define ASCV_BREAK_ADDR (ushort)0x0028
1549 #define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
1550 #define ASCV_BREAK_CONTROL (ushort)0x002C
1551 #define ASCV_BREAK_HIT_COUNT (ushort)0x002E
1553 #define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
1554 #define ASCV_MCODE_CHKSUM_W (ushort)0x0032
1555 #define ASCV_MCODE_SIZE_W (ushort)0x0034
1556 #define ASCV_STOP_CODE_B (ushort)0x0036
1557 #define ASCV_DVC_ERR_CODE_B (ushort)0x0037
1558 #define ASCV_OVERRUN_PADDR_D (ushort)0x0038
1559 #define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
1560 #define ASCV_HALTCODE_W (ushort)0x0040
1561 #define ASCV_CHKSUM_W (ushort)0x0042
1562 #define ASCV_MC_DATE_W (ushort)0x0044
1563 #define ASCV_MC_VER_W (ushort)0x0046
1564 #define ASCV_NEXTRDY_B (ushort)0x0048
1565 #define ASCV_DONENEXT_B (ushort)0x0049
1566 #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1567 #define ASCV_SCSIBUSY_B (ushort)0x004B
1568 #define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
1569 #define ASCV_CURCDB_B (ushort)0x004D
1570 #define ASCV_RCLUN_B (ushort)0x004E
1571 #define ASCV_BUSY_QHEAD_B (ushort)0x004F
1572 #define ASCV_DISC1_QHEAD_B (ushort)0x0050
1573 #define ASCV_DISC_ENABLE_B (ushort)0x0052
1574 #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1575 #define ASCV_HOSTSCSI_ID_B (ushort)0x0055
1576 #define ASCV_MCODE_CNTL_B (ushort)0x0056
1577 #define ASCV_NULL_TARGET_B (ushort)0x0057
1578 #define ASCV_FREE_Q_HEAD_W (ushort)0x0058
1579 #define ASCV_DONE_Q_TAIL_W (ushort)0x005A
1580 #define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
1581 #define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
1582 #define ASCV_HOST_FLAG_B (ushort)0x005D
1583 #define ASCV_TOTAL_READY_Q_B (ushort)0x0064
1584 #define ASCV_VER_SERIAL_B (ushort)0x0065
1585 #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1586 #define ASCV_WTM_FLAG_B (ushort)0x0068
1587 #define ASCV_RISC_FLAG_B (ushort)0x006A
1588 #define ASCV_REQ_SG_LIST_QP (ushort)0x006B
1589 #define ASC_HOST_FLAG_IN_ISR 0x01
1590 #define ASC_HOST_FLAG_ACK_INT 0x02
1591 #define ASC_RISC_FLAG_GEN_INT 0x01
1592 #define ASC_RISC_FLAG_REQ_SG_LIST 0x02
1593 #define IOP_CTRL (0x0F)
1594 #define IOP_STATUS (0x0E)
1595 #define IOP_INT_ACK IOP_STATUS
1596 #define IOP_REG_IFC (0x0D)
1597 #define IOP_SYN_OFFSET (0x0B)
1598 #define IOP_EXTRA_CONTROL (0x0D)
1599 #define IOP_REG_PC (0x0C)
1600 #define IOP_RAM_ADDR (0x0A)
1601 #define IOP_RAM_DATA (0x08)
1602 #define IOP_EEP_DATA (0x06)
1603 #define IOP_EEP_CMD (0x07)
1604 #define IOP_VERSION (0x03)
1605 #define IOP_CONFIG_HIGH (0x04)
1606 #define IOP_CONFIG_LOW (0x02)
1607 #define IOP_SIG_BYTE (0x01)
1608 #define IOP_SIG_WORD (0x00)
1609 #define IOP_REG_DC1 (0x0E)
1610 #define IOP_REG_DC0 (0x0C)
1611 #define IOP_REG_SB (0x0B)
1612 #define IOP_REG_DA1 (0x0A)
1613 #define IOP_REG_DA0 (0x08)
1614 #define IOP_REG_SC (0x09)
1615 #define IOP_DMA_SPEED (0x07)
1616 #define IOP_REG_FLAG (0x07)
1617 #define IOP_FIFO_H (0x06)
1618 #define IOP_FIFO_L (0x04)
1619 #define IOP_REG_ID (0x05)
1620 #define IOP_REG_QP (0x03)
1621 #define IOP_REG_IH (0x02)
1622 #define IOP_REG_IX (0x01)
1623 #define IOP_REG_AX (0x00)
1624 #define IFC_REG_LOCK (0x00)
1625 #define IFC_REG_UNLOCK (0x09)
1626 #define IFC_WR_EN_FILTER (0x10)
1627 #define IFC_RD_NO_EEPROM (0x10)
1628 #define IFC_SLEW_RATE (0x20)
1629 #define IFC_ACT_NEG (0x40)
1630 #define IFC_INP_FILTER (0x80)
1631 #define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
1632 #define SC_SEL (uchar)(0x80)
1633 #define SC_BSY (uchar)(0x40)
1634 #define SC_ACK (uchar)(0x20)
1635 #define SC_REQ (uchar)(0x10)
1636 #define SC_ATN (uchar)(0x08)
1637 #define SC_IO (uchar)(0x04)
1638 #define SC_CD (uchar)(0x02)
1639 #define SC_MSG (uchar)(0x01)
1640 #define SEC_SCSI_CTL (uchar)(0x80)
1641 #define SEC_ACTIVE_NEGATE (uchar)(0x40)
1642 #define SEC_SLEW_RATE (uchar)(0x20)
1643 #define SEC_ENABLE_FILTER (uchar)(0x10)
1644 #define ASC_HALT_EXTMSG_IN (ushort)0x8000
1645 #define ASC_HALT_CHK_CONDITION (ushort)0x8100
1646 #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1647 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
1648 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
1649 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1650 #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1651 #define ASC_MAX_QNO 0xF8
1652 #define ASC_DATA_SEC_BEG (ushort)0x0080
1653 #define ASC_DATA_SEC_END (ushort)0x0080
1654 #define ASC_CODE_SEC_BEG (ushort)0x0080
1655 #define ASC_CODE_SEC_END (ushort)0x0080
1656 #define ASC_QADR_BEG (0x4000)
1657 #define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
1658 #define ASC_QADR_END (ushort)0x7FFF
1659 #define ASC_QLAST_ADR (ushort)0x7FC0
1660 #define ASC_QBLK_SIZE 0x40
1661 #define ASC_BIOS_DATA_QBEG 0xF8
1662 #define ASC_MIN_ACTIVE_QNO 0x01
1663 #define ASC_QLINK_END 0xFF
1664 #define ASC_EEPROM_WORDS 0x10
1665 #define ASC_MAX_MGS_LEN 0x10
1666 #define ASC_BIOS_ADDR_DEF 0xDC00
1667 #define ASC_BIOS_SIZE 0x3800
1668 #define ASC_BIOS_RAM_OFF 0x3800
1669 #define ASC_BIOS_RAM_SIZE 0x800
1670 #define ASC_BIOS_MIN_ADDR 0xC000
1671 #define ASC_BIOS_MAX_ADDR 0xEC00
1672 #define ASC_BIOS_BANK_SIZE 0x0400
1673 #define ASC_MCODE_START_ADDR 0x0080
1674 #define ASC_CFG0_HOST_INT_ON 0x0020
1675 #define ASC_CFG0_BIOS_ON 0x0040
1676 #define ASC_CFG0_VERA_BURST_ON 0x0080
1677 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
1678 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
1679 #define ASC_CFG1_LRAM_8BITS_ON 0x0800
1680 #define ASC_CFG_MSW_CLR_MASK 0x3080
1681 #define CSW_TEST1 (ASC_CS_TYPE)0x8000
1682 #define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
1683 #define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
1684 #define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
1685 #define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
1686 #define CSW_TEST2 (ASC_CS_TYPE)0x0400
1687 #define CSW_TEST3 (ASC_CS_TYPE)0x0200
1688 #define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
1689 #define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
1690 #define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
1691 #define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
1692 #define CSW_HALTED (ASC_CS_TYPE)0x0010
1693 #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1694 #define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
1695 #define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
1696 #define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
1697 #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1698 #define CIW_INT_ACK (ASC_CS_TYPE)0x0100
1699 #define CIW_TEST1 (ASC_CS_TYPE)0x0200
1700 #define CIW_TEST2 (ASC_CS_TYPE)0x0400
1701 #define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
1702 #define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
1703 #define CC_CHIP_RESET (uchar)0x80
1704 #define CC_SCSI_RESET (uchar)0x40
1705 #define CC_HALT (uchar)0x20
1706 #define CC_SINGLE_STEP (uchar)0x10
1707 #define CC_DMA_ABLE (uchar)0x08
1708 #define CC_TEST (uchar)0x04
1709 #define CC_BANK_ONE (uchar)0x02
1710 #define CC_DIAG (uchar)0x01
1711 #define ASC_1000_ID0W 0x04C1
1712 #define ASC_1000_ID0W_FIX 0x00C1
1713 #define ASC_1000_ID1B 0x25
1714 #define ASC_EISA_REV_IOP_MASK (0x0C83)
1715 #define ASC_EISA_PID_IOP_MASK (0x0C80)
1716 #define ASC_EISA_CFG_IOP_MASK (0x0C86)
1717 #define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
1718 #define INS_HALTINT (ushort)0x6281
1719 #define INS_HALT (ushort)0x6280
1720 #define INS_SINT (ushort)0x6200
1721 #define INS_RFLAG_WTM (ushort)0x7380
1722 #define ASC_MC_SAVE_CODE_WSIZE 0x500
1723 #define ASC_MC_SAVE_DATA_WSIZE 0x40
1725 typedef struct asc_mc_saved {
1726 ushort data[ASC_MC_SAVE_DATA_WSIZE];
1727 ushort code[ASC_MC_SAVE_CODE_WSIZE];
1728 } ASC_MC_SAVED;
1730 #define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1731 #define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1732 #define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1733 #define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1734 #define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1735 #define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1736 #define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
1737 #define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
1738 #define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1739 #define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1740 #define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1741 #define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1742 #define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1743 #define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1744 #define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1745 #define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
1746 #define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
1747 #define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
1748 #define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
1749 #define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
1750 #define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
1751 #define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
1752 #define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
1753 #define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
1754 #define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
1755 #define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
1756 #define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1757 #define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1758 #define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
1759 #define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
1760 #define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
1761 #define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
1762 #define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1763 #define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
1764 #define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
1765 #define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
1766 #define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
1767 #define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
1768 #define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
1769 #define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
1770 #define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1771 #define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1772 #define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
1773 #define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
1774 #define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
1775 #define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
1776 #define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
1777 #define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
1778 #define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
1779 #define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
1780 #define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
1781 #define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
1782 #define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
1783 #define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
1784 #define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
1785 #define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
1786 #define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
1787 #define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
1788 #define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
1789 #define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
1790 #define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
1791 #define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
1792 #define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
1793 #define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
1794 #define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
1795 #define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
1796 #define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
1797 #define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
1799 static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1800 static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1801 static void AscWaitEEPRead(void);
1802 static void AscWaitEEPWrite(void);
1803 static ushort AscReadEEPWord(PortAddr, uchar);
1804 static ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1805 static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1806 static int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1807 static int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1808 static int AscStartChip(PortAddr);
1809 static int AscStopChip(PortAddr);
1810 static void AscSetChipIH(PortAddr, ushort);
1811 static int AscIsChipHalted(PortAddr);
1812 static void AscAckInterrupt(PortAddr);
1813 static void AscDisableInterrupt(PortAddr);
1814 static void AscEnableInterrupt(PortAddr);
1815 static void AscSetBank(PortAddr, uchar);
1816 static int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1817 #ifdef CONFIG_ISA
1818 static ushort AscGetIsaDmaChannel(PortAddr);
1819 static ushort AscSetIsaDmaChannel(PortAddr, ushort);
1820 static uchar AscSetIsaDmaSpeed(PortAddr, uchar);
1821 static uchar AscGetIsaDmaSpeed(PortAddr);
1822 #endif /* CONFIG_ISA */
1823 static uchar AscReadLramByte(PortAddr, ushort);
1824 static ushort AscReadLramWord(PortAddr, ushort);
1825 #if CC_VERY_LONG_SG_LIST
1826 static ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1827 #endif /* CC_VERY_LONG_SG_LIST */
1828 static void AscWriteLramWord(PortAddr, ushort, ushort);
1829 static void AscWriteLramByte(PortAddr, ushort, uchar);
1830 static ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
1831 static void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1832 static void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1833 static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1834 static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
1835 static ushort AscInitAscDvcVar(ASC_DVC_VAR *);
1836 static ushort AscInitFromEEP(ASC_DVC_VAR *);
1837 static ushort AscInitFromAscDvcVar(ASC_DVC_VAR *);
1838 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1839 static int AscTestExternalLram(ASC_DVC_VAR *);
1840 static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1841 static uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1842 static void AscSetChipSDTR(PortAddr, uchar, uchar);
1843 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1844 static uchar AscAllocFreeQueue(PortAddr, uchar);
1845 static uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1846 static int AscHostReqRiscHalt(PortAddr);
1847 static int AscStopQueueExe(PortAddr);
1848 static int AscSendScsiQueue(ASC_DVC_VAR *,
1849 ASC_SCSI_Q *scsiq, uchar n_q_required);
1850 static int AscPutReadyQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1851 static int AscPutReadySgListQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1852 static int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1853 static int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1854 static ushort AscInitLram(ASC_DVC_VAR *);
1855 static ushort AscInitQLinkVar(ASC_DVC_VAR *);
1856 static int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1857 static int AscIsrChipHalted(ASC_DVC_VAR *);
1858 static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1859 ASC_QDONE_INFO *, ASC_DCNT);
1860 static int AscIsrQDone(ASC_DVC_VAR *);
1861 #ifdef CONFIG_ISA
1862 static ushort AscGetEisaChipCfg(PortAddr);
1863 #endif /* CONFIG_ISA */
1864 static uchar AscGetChipScsiCtrl(PortAddr);
1865 static uchar AscSetChipScsiID(PortAddr, uchar);
1866 static uchar AscGetChipVersion(PortAddr, ushort);
1867 static ushort AscGetChipBusType(PortAddr);
1868 static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
1869 static int AscFindSignature(PortAddr);
1870 static void AscToggleIRQAct(PortAddr);
1871 static uchar AscGetChipIRQ(PortAddr, ushort);
1872 static uchar AscSetChipIRQ(PortAddr, uchar, ushort);
1873 static ushort AscGetChipBiosAddress(PortAddr, ushort);
1874 static inline ulong DvcEnterCritical(void);
1875 static inline void DvcLeaveCritical(ulong);
1876 static ushort AscGetChipBiosAddress(PortAddr, ushort);
1877 static void DvcSleepMilliSecond(ASC_DCNT);
1878 static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
1879 static void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1880 static void DvcGetQinfo(PortAddr, ushort, uchar *, int);
1881 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
1882 static void AscAsyncFix(ASC_DVC_VAR *, struct scsi_device *);
1883 static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
1884 static int AscISR(ASC_DVC_VAR *);
1885 static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar);
1886 static int AscSgListToQueue(int);
1887 #ifdef CONFIG_ISA
1888 static void AscEnableIsaDma(uchar);
1889 #endif /* CONFIG_ISA */
1890 static ASC_DCNT AscGetMaxDmaCount(ushort);
1891 static const char *advansys_info(struct Scsi_Host *shost);
1894 * --- Adv Library Constants and Macros
1897 #define ADV_LIB_VERSION_MAJOR 5
1898 #define ADV_LIB_VERSION_MINOR 14
1901 * Define Adv Library required special types.
1905 * Portable Data Types
1907 * Any instance where a 32-bit long or pointer type is assumed
1908 * for precision or HW defined structures, the following define
1909 * types must be used. In Linux the char, short, and int types
1910 * are all consistent at 8, 16, and 32 bits respectively. Pointers
1911 * and long types are 64 bits on Alpha and UltraSPARC.
1913 #define ADV_PADDR __u32 /* Physical address data type. */
1914 #define ADV_VADDR __u32 /* Virtual address data type. */
1915 #define ADV_DCNT __u32 /* Unsigned Data count type. */
1916 #define ADV_SDCNT __s32 /* Signed Data count type. */
1919 * These macros are used to convert a virtual address to a
1920 * 32-bit value. This currently can be used on Linux Alpha
1921 * which uses 64-bit virtual address but a 32-bit bus address.
1922 * This is likely to break in the future, but doing this now
1923 * will give us time to change the HW and FW to handle 64-bit
1924 * addresses.
1926 #define ADV_VADDR_TO_U32 virt_to_bus
1927 #define ADV_U32_TO_VADDR bus_to_virt
1929 #define AdvPortAddr void __iomem * /* Virtual memory address size */
1932 * Define Adv Library required memory access macros.
1934 #define ADV_MEM_READB(addr) readb(addr)
1935 #define ADV_MEM_READW(addr) readw(addr)
1936 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
1937 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
1938 #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
1940 #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
1943 * For wide boards a CDB length maximum of 16 bytes
1944 * is supported.
1946 #define ADV_MAX_CDB_LEN 16
1949 * Define total number of simultaneous maximum element scatter-gather
1950 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
1951 * maximum number of outstanding commands per wide host adapter. Each
1952 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
1953 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
1954 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
1955 * structures or 255 scatter-gather elements.
1958 #define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
1961 * Define Adv Library required maximum number of scatter-gather
1962 * elements per request.
1964 #define ADV_MAX_SG_LIST 255
1966 /* Number of SG blocks needed. */
1967 #define ADV_NUM_SG_BLOCK \
1968 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
1970 /* Total contiguous memory needed for SG blocks. */
1971 #define ADV_SG_TOTAL_MEM_SIZE \
1972 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
1974 #define ADV_PAGE_SIZE PAGE_SIZE
1976 #define ADV_NUM_PAGE_CROSSING \
1977 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1979 #define ADV_EEP_DVC_CFG_BEGIN (0x00)
1980 #define ADV_EEP_DVC_CFG_END (0x15)
1981 #define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
1982 #define ADV_EEP_MAX_WORD_ADDR (0x1E)
1984 #define ADV_EEP_DELAY_MS 100
1986 #define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
1987 #define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
1989 * For the ASC3550 Bit 13 is Termination Polarity control bit.
1990 * For later ICs Bit 13 controls whether the CIS (Card Information
1991 * Service Section) is loaded from EEPROM.
1993 #define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
1994 #define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
1996 * ASC38C1600 Bit 11
1998 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
1999 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
2000 * Function 0 will specify INT B.
2002 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
2003 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
2004 * Function 1 will specify INT A.
2006 #define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
2008 typedef struct adveep_3550_config {
2009 /* Word Offset, Description */
2011 ushort cfg_lsw; /* 00 power up initialization */
2012 /* bit 13 set - Term Polarity Control */
2013 /* bit 14 set - BIOS Enable */
2014 /* bit 15 set - Big Endian Mode */
2015 ushort cfg_msw; /* 01 unused */
2016 ushort disc_enable; /* 02 disconnect enable */
2017 ushort wdtr_able; /* 03 Wide DTR able */
2018 ushort sdtr_able; /* 04 Synchronous DTR able */
2019 ushort start_motor; /* 05 send start up motor */
2020 ushort tagqng_able; /* 06 tag queuing able */
2021 ushort bios_scan; /* 07 BIOS device control */
2022 ushort scam_tolerant; /* 08 no scam */
2024 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2025 uchar bios_boot_delay; /* power up wait */
2027 uchar scsi_reset_delay; /* 10 reset delay */
2028 uchar bios_id_lun; /* first boot device scsi id & lun */
2029 /* high nibble is lun */
2030 /* low nibble is scsi id */
2032 uchar termination; /* 11 0 - automatic */
2033 /* 1 - low off / high off */
2034 /* 2 - low off / high on */
2035 /* 3 - low on / high on */
2036 /* There is no low on / high off */
2038 uchar reserved1; /* reserved byte (not used) */
2040 ushort bios_ctrl; /* 12 BIOS control bits */
2041 /* bit 0 BIOS don't act as initiator. */
2042 /* bit 1 BIOS > 1 GB support */
2043 /* bit 2 BIOS > 2 Disk Support */
2044 /* bit 3 BIOS don't support removables */
2045 /* bit 4 BIOS support bootable CD */
2046 /* bit 5 BIOS scan enabled */
2047 /* bit 6 BIOS support multiple LUNs */
2048 /* bit 7 BIOS display of message */
2049 /* bit 8 SCAM disabled */
2050 /* bit 9 Reset SCSI bus during init. */
2051 /* bit 10 */
2052 /* bit 11 No verbose initialization. */
2053 /* bit 12 SCSI parity enabled */
2054 /* bit 13 */
2055 /* bit 14 */
2056 /* bit 15 */
2057 ushort ultra_able; /* 13 ULTRA speed able */
2058 ushort reserved2; /* 14 reserved */
2059 uchar max_host_qng; /* 15 maximum host queuing */
2060 uchar max_dvc_qng; /* maximum per device queuing */
2061 ushort dvc_cntl; /* 16 control bit for driver */
2062 ushort bug_fix; /* 17 control bit for bug fix */
2063 ushort serial_number_word1; /* 18 Board serial number word 1 */
2064 ushort serial_number_word2; /* 19 Board serial number word 2 */
2065 ushort serial_number_word3; /* 20 Board serial number word 3 */
2066 ushort check_sum; /* 21 EEP check sum */
2067 uchar oem_name[16]; /* 22 OEM name */
2068 ushort dvc_err_code; /* 30 last device driver error code */
2069 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2070 ushort adv_err_addr; /* 32 last uc error address */
2071 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2072 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2073 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2074 ushort num_of_err; /* 36 number of error */
2075 } ADVEEP_3550_CONFIG;
2077 typedef struct adveep_38C0800_config {
2078 /* Word Offset, Description */
2080 ushort cfg_lsw; /* 00 power up initialization */
2081 /* bit 13 set - Load CIS */
2082 /* bit 14 set - BIOS Enable */
2083 /* bit 15 set - Big Endian Mode */
2084 ushort cfg_msw; /* 01 unused */
2085 ushort disc_enable; /* 02 disconnect enable */
2086 ushort wdtr_able; /* 03 Wide DTR able */
2087 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2088 ushort start_motor; /* 05 send start up motor */
2089 ushort tagqng_able; /* 06 tag queuing able */
2090 ushort bios_scan; /* 07 BIOS device control */
2091 ushort scam_tolerant; /* 08 no scam */
2093 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2094 uchar bios_boot_delay; /* power up wait */
2096 uchar scsi_reset_delay; /* 10 reset delay */
2097 uchar bios_id_lun; /* first boot device scsi id & lun */
2098 /* high nibble is lun */
2099 /* low nibble is scsi id */
2101 uchar termination_se; /* 11 0 - automatic */
2102 /* 1 - low off / high off */
2103 /* 2 - low off / high on */
2104 /* 3 - low on / high on */
2105 /* There is no low on / high off */
2107 uchar termination_lvd; /* 11 0 - automatic */
2108 /* 1 - low off / high off */
2109 /* 2 - low off / high on */
2110 /* 3 - low on / high on */
2111 /* There is no low on / high off */
2113 ushort bios_ctrl; /* 12 BIOS control bits */
2114 /* bit 0 BIOS don't act as initiator. */
2115 /* bit 1 BIOS > 1 GB support */
2116 /* bit 2 BIOS > 2 Disk Support */
2117 /* bit 3 BIOS don't support removables */
2118 /* bit 4 BIOS support bootable CD */
2119 /* bit 5 BIOS scan enabled */
2120 /* bit 6 BIOS support multiple LUNs */
2121 /* bit 7 BIOS display of message */
2122 /* bit 8 SCAM disabled */
2123 /* bit 9 Reset SCSI bus during init. */
2124 /* bit 10 */
2125 /* bit 11 No verbose initialization. */
2126 /* bit 12 SCSI parity enabled */
2127 /* bit 13 */
2128 /* bit 14 */
2129 /* bit 15 */
2130 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2131 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2132 uchar max_host_qng; /* 15 maximum host queueing */
2133 uchar max_dvc_qng; /* maximum per device queuing */
2134 ushort dvc_cntl; /* 16 control bit for driver */
2135 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2136 ushort serial_number_word1; /* 18 Board serial number word 1 */
2137 ushort serial_number_word2; /* 19 Board serial number word 2 */
2138 ushort serial_number_word3; /* 20 Board serial number word 3 */
2139 ushort check_sum; /* 21 EEP check sum */
2140 uchar oem_name[16]; /* 22 OEM name */
2141 ushort dvc_err_code; /* 30 last device driver error code */
2142 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2143 ushort adv_err_addr; /* 32 last uc error address */
2144 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2145 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2146 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2147 ushort reserved36; /* 36 reserved */
2148 ushort reserved37; /* 37 reserved */
2149 ushort reserved38; /* 38 reserved */
2150 ushort reserved39; /* 39 reserved */
2151 ushort reserved40; /* 40 reserved */
2152 ushort reserved41; /* 41 reserved */
2153 ushort reserved42; /* 42 reserved */
2154 ushort reserved43; /* 43 reserved */
2155 ushort reserved44; /* 44 reserved */
2156 ushort reserved45; /* 45 reserved */
2157 ushort reserved46; /* 46 reserved */
2158 ushort reserved47; /* 47 reserved */
2159 ushort reserved48; /* 48 reserved */
2160 ushort reserved49; /* 49 reserved */
2161 ushort reserved50; /* 50 reserved */
2162 ushort reserved51; /* 51 reserved */
2163 ushort reserved52; /* 52 reserved */
2164 ushort reserved53; /* 53 reserved */
2165 ushort reserved54; /* 54 reserved */
2166 ushort reserved55; /* 55 reserved */
2167 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2168 ushort cisprt_msw; /* 57 CIS PTR MSW */
2169 ushort subsysvid; /* 58 SubSystem Vendor ID */
2170 ushort subsysid; /* 59 SubSystem ID */
2171 ushort reserved60; /* 60 reserved */
2172 ushort reserved61; /* 61 reserved */
2173 ushort reserved62; /* 62 reserved */
2174 ushort reserved63; /* 63 reserved */
2175 } ADVEEP_38C0800_CONFIG;
2177 typedef struct adveep_38C1600_config {
2178 /* Word Offset, Description */
2180 ushort cfg_lsw; /* 00 power up initialization */
2181 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
2182 /* clear - Func. 0 INTA, Func. 1 INTB */
2183 /* bit 13 set - Load CIS */
2184 /* bit 14 set - BIOS Enable */
2185 /* bit 15 set - Big Endian Mode */
2186 ushort cfg_msw; /* 01 unused */
2187 ushort disc_enable; /* 02 disconnect enable */
2188 ushort wdtr_able; /* 03 Wide DTR able */
2189 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2190 ushort start_motor; /* 05 send start up motor */
2191 ushort tagqng_able; /* 06 tag queuing able */
2192 ushort bios_scan; /* 07 BIOS device control */
2193 ushort scam_tolerant; /* 08 no scam */
2195 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2196 uchar bios_boot_delay; /* power up wait */
2198 uchar scsi_reset_delay; /* 10 reset delay */
2199 uchar bios_id_lun; /* first boot device scsi id & lun */
2200 /* high nibble is lun */
2201 /* low nibble is scsi id */
2203 uchar termination_se; /* 11 0 - automatic */
2204 /* 1 - low off / high off */
2205 /* 2 - low off / high on */
2206 /* 3 - low on / high on */
2207 /* There is no low on / high off */
2209 uchar termination_lvd; /* 11 0 - automatic */
2210 /* 1 - low off / high off */
2211 /* 2 - low off / high on */
2212 /* 3 - low on / high on */
2213 /* There is no low on / high off */
2215 ushort bios_ctrl; /* 12 BIOS control bits */
2216 /* bit 0 BIOS don't act as initiator. */
2217 /* bit 1 BIOS > 1 GB support */
2218 /* bit 2 BIOS > 2 Disk Support */
2219 /* bit 3 BIOS don't support removables */
2220 /* bit 4 BIOS support bootable CD */
2221 /* bit 5 BIOS scan enabled */
2222 /* bit 6 BIOS support multiple LUNs */
2223 /* bit 7 BIOS display of message */
2224 /* bit 8 SCAM disabled */
2225 /* bit 9 Reset SCSI bus during init. */
2226 /* bit 10 Basic Integrity Checking disabled */
2227 /* bit 11 No verbose initialization. */
2228 /* bit 12 SCSI parity enabled */
2229 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
2230 /* bit 14 */
2231 /* bit 15 */
2232 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2233 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2234 uchar max_host_qng; /* 15 maximum host queueing */
2235 uchar max_dvc_qng; /* maximum per device queuing */
2236 ushort dvc_cntl; /* 16 control bit for driver */
2237 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2238 ushort serial_number_word1; /* 18 Board serial number word 1 */
2239 ushort serial_number_word2; /* 19 Board serial number word 2 */
2240 ushort serial_number_word3; /* 20 Board serial number word 3 */
2241 ushort check_sum; /* 21 EEP check sum */
2242 uchar oem_name[16]; /* 22 OEM name */
2243 ushort dvc_err_code; /* 30 last device driver error code */
2244 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2245 ushort adv_err_addr; /* 32 last uc error address */
2246 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2247 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2248 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2249 ushort reserved36; /* 36 reserved */
2250 ushort reserved37; /* 37 reserved */
2251 ushort reserved38; /* 38 reserved */
2252 ushort reserved39; /* 39 reserved */
2253 ushort reserved40; /* 40 reserved */
2254 ushort reserved41; /* 41 reserved */
2255 ushort reserved42; /* 42 reserved */
2256 ushort reserved43; /* 43 reserved */
2257 ushort reserved44; /* 44 reserved */
2258 ushort reserved45; /* 45 reserved */
2259 ushort reserved46; /* 46 reserved */
2260 ushort reserved47; /* 47 reserved */
2261 ushort reserved48; /* 48 reserved */
2262 ushort reserved49; /* 49 reserved */
2263 ushort reserved50; /* 50 reserved */
2264 ushort reserved51; /* 51 reserved */
2265 ushort reserved52; /* 52 reserved */
2266 ushort reserved53; /* 53 reserved */
2267 ushort reserved54; /* 54 reserved */
2268 ushort reserved55; /* 55 reserved */
2269 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2270 ushort cisprt_msw; /* 57 CIS PTR MSW */
2271 ushort subsysvid; /* 58 SubSystem Vendor ID */
2272 ushort subsysid; /* 59 SubSystem ID */
2273 ushort reserved60; /* 60 reserved */
2274 ushort reserved61; /* 61 reserved */
2275 ushort reserved62; /* 62 reserved */
2276 ushort reserved63; /* 63 reserved */
2277 } ADVEEP_38C1600_CONFIG;
2280 * EEPROM Commands
2282 #define ASC_EEP_CMD_DONE 0x0200
2283 #define ASC_EEP_CMD_DONE_ERR 0x0001
2285 /* cfg_word */
2286 #define EEP_CFG_WORD_BIG_ENDIAN 0x8000
2288 /* bios_ctrl */
2289 #define BIOS_CTRL_BIOS 0x0001
2290 #define BIOS_CTRL_EXTENDED_XLAT 0x0002
2291 #define BIOS_CTRL_GT_2_DISK 0x0004
2292 #define BIOS_CTRL_BIOS_REMOVABLE 0x0008
2293 #define BIOS_CTRL_BOOTABLE_CD 0x0010
2294 #define BIOS_CTRL_MULTIPLE_LUN 0x0040
2295 #define BIOS_CTRL_DISPLAY_MSG 0x0080
2296 #define BIOS_CTRL_NO_SCAM 0x0100
2297 #define BIOS_CTRL_RESET_SCSI_BUS 0x0200
2298 #define BIOS_CTRL_INIT_VERBOSE 0x0800
2299 #define BIOS_CTRL_SCSI_PARITY 0x1000
2300 #define BIOS_CTRL_AIPP_DIS 0x2000
2302 #define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
2303 #define ADV_3550_IOLEN 0x40 /* I/O Port Range in bytes */
2305 #define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2306 #define ADV_38C0800_IOLEN 0x100 /* I/O Port Range in bytes */
2309 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
2310 * a special 16K Adv Library and Microcode version. After the issue is
2311 * resolved, should restore 32K support.
2313 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
2315 #define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2316 #define ADV_38C1600_IOLEN 0x100 /* I/O Port Range 256 bytes */
2317 #define ADV_38C1600_MEMLEN 0x1000 /* Memory Range 4KB bytes */
2320 * Byte I/O register address from base of 'iop_base'.
2322 #define IOPB_INTR_STATUS_REG 0x00
2323 #define IOPB_CHIP_ID_1 0x01
2324 #define IOPB_INTR_ENABLES 0x02
2325 #define IOPB_CHIP_TYPE_REV 0x03
2326 #define IOPB_RES_ADDR_4 0x04
2327 #define IOPB_RES_ADDR_5 0x05
2328 #define IOPB_RAM_DATA 0x06
2329 #define IOPB_RES_ADDR_7 0x07
2330 #define IOPB_FLAG_REG 0x08
2331 #define IOPB_RES_ADDR_9 0x09
2332 #define IOPB_RISC_CSR 0x0A
2333 #define IOPB_RES_ADDR_B 0x0B
2334 #define IOPB_RES_ADDR_C 0x0C
2335 #define IOPB_RES_ADDR_D 0x0D
2336 #define IOPB_SOFT_OVER_WR 0x0E
2337 #define IOPB_RES_ADDR_F 0x0F
2338 #define IOPB_MEM_CFG 0x10
2339 #define IOPB_RES_ADDR_11 0x11
2340 #define IOPB_GPIO_DATA 0x12
2341 #define IOPB_RES_ADDR_13 0x13
2342 #define IOPB_FLASH_PAGE 0x14
2343 #define IOPB_RES_ADDR_15 0x15
2344 #define IOPB_GPIO_CNTL 0x16
2345 #define IOPB_RES_ADDR_17 0x17
2346 #define IOPB_FLASH_DATA 0x18
2347 #define IOPB_RES_ADDR_19 0x19
2348 #define IOPB_RES_ADDR_1A 0x1A
2349 #define IOPB_RES_ADDR_1B 0x1B
2350 #define IOPB_RES_ADDR_1C 0x1C
2351 #define IOPB_RES_ADDR_1D 0x1D
2352 #define IOPB_RES_ADDR_1E 0x1E
2353 #define IOPB_RES_ADDR_1F 0x1F
2354 #define IOPB_DMA_CFG0 0x20
2355 #define IOPB_DMA_CFG1 0x21
2356 #define IOPB_TICKLE 0x22
2357 #define IOPB_DMA_REG_WR 0x23
2358 #define IOPB_SDMA_STATUS 0x24
2359 #define IOPB_SCSI_BYTE_CNT 0x25
2360 #define IOPB_HOST_BYTE_CNT 0x26
2361 #define IOPB_BYTE_LEFT_TO_XFER 0x27
2362 #define IOPB_BYTE_TO_XFER_0 0x28
2363 #define IOPB_BYTE_TO_XFER_1 0x29
2364 #define IOPB_BYTE_TO_XFER_2 0x2A
2365 #define IOPB_BYTE_TO_XFER_3 0x2B
2366 #define IOPB_ACC_GRP 0x2C
2367 #define IOPB_RES_ADDR_2D 0x2D
2368 #define IOPB_DEV_ID 0x2E
2369 #define IOPB_RES_ADDR_2F 0x2F
2370 #define IOPB_SCSI_DATA 0x30
2371 #define IOPB_RES_ADDR_31 0x31
2372 #define IOPB_RES_ADDR_32 0x32
2373 #define IOPB_SCSI_DATA_HSHK 0x33
2374 #define IOPB_SCSI_CTRL 0x34
2375 #define IOPB_RES_ADDR_35 0x35
2376 #define IOPB_RES_ADDR_36 0x36
2377 #define IOPB_RES_ADDR_37 0x37
2378 #define IOPB_RAM_BIST 0x38
2379 #define IOPB_PLL_TEST 0x39
2380 #define IOPB_PCI_INT_CFG 0x3A
2381 #define IOPB_RES_ADDR_3B 0x3B
2382 #define IOPB_RFIFO_CNT 0x3C
2383 #define IOPB_RES_ADDR_3D 0x3D
2384 #define IOPB_RES_ADDR_3E 0x3E
2385 #define IOPB_RES_ADDR_3F 0x3F
2388 * Word I/O register address from base of 'iop_base'.
2390 #define IOPW_CHIP_ID_0 0x00 /* CID0 */
2391 #define IOPW_CTRL_REG 0x02 /* CC */
2392 #define IOPW_RAM_ADDR 0x04 /* LA */
2393 #define IOPW_RAM_DATA 0x06 /* LD */
2394 #define IOPW_RES_ADDR_08 0x08
2395 #define IOPW_RISC_CSR 0x0A /* CSR */
2396 #define IOPW_SCSI_CFG0 0x0C /* CFG0 */
2397 #define IOPW_SCSI_CFG1 0x0E /* CFG1 */
2398 #define IOPW_RES_ADDR_10 0x10
2399 #define IOPW_SEL_MASK 0x12 /* SM */
2400 #define IOPW_RES_ADDR_14 0x14
2401 #define IOPW_FLASH_ADDR 0x16 /* FA */
2402 #define IOPW_RES_ADDR_18 0x18
2403 #define IOPW_EE_CMD 0x1A /* EC */
2404 #define IOPW_EE_DATA 0x1C /* ED */
2405 #define IOPW_SFIFO_CNT 0x1E /* SFC */
2406 #define IOPW_RES_ADDR_20 0x20
2407 #define IOPW_Q_BASE 0x22 /* QB */
2408 #define IOPW_QP 0x24 /* QP */
2409 #define IOPW_IX 0x26 /* IX */
2410 #define IOPW_SP 0x28 /* SP */
2411 #define IOPW_PC 0x2A /* PC */
2412 #define IOPW_RES_ADDR_2C 0x2C
2413 #define IOPW_RES_ADDR_2E 0x2E
2414 #define IOPW_SCSI_DATA 0x30 /* SD */
2415 #define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
2416 #define IOPW_SCSI_CTRL 0x34 /* SC */
2417 #define IOPW_HSHK_CFG 0x36 /* HCFG */
2418 #define IOPW_SXFR_STATUS 0x36 /* SXS */
2419 #define IOPW_SXFR_CNTL 0x38 /* SXL */
2420 #define IOPW_SXFR_CNTH 0x3A /* SXH */
2421 #define IOPW_RES_ADDR_3C 0x3C
2422 #define IOPW_RFIFO_DATA 0x3E /* RFD */
2425 * Doubleword I/O register address from base of 'iop_base'.
2427 #define IOPDW_RES_ADDR_0 0x00
2428 #define IOPDW_RAM_DATA 0x04
2429 #define IOPDW_RES_ADDR_8 0x08
2430 #define IOPDW_RES_ADDR_C 0x0C
2431 #define IOPDW_RES_ADDR_10 0x10
2432 #define IOPDW_COMMA 0x14
2433 #define IOPDW_COMMB 0x18
2434 #define IOPDW_RES_ADDR_1C 0x1C
2435 #define IOPDW_SDMA_ADDR0 0x20
2436 #define IOPDW_SDMA_ADDR1 0x24
2437 #define IOPDW_SDMA_COUNT 0x28
2438 #define IOPDW_SDMA_ERROR 0x2C
2439 #define IOPDW_RDMA_ADDR0 0x30
2440 #define IOPDW_RDMA_ADDR1 0x34
2441 #define IOPDW_RDMA_COUNT 0x38
2442 #define IOPDW_RDMA_ERROR 0x3C
2444 #define ADV_CHIP_ID_BYTE 0x25
2445 #define ADV_CHIP_ID_WORD 0x04C1
2447 #define ADV_SC_SCSI_BUS_RESET 0x2000
2449 #define ADV_INTR_ENABLE_HOST_INTR 0x01
2450 #define ADV_INTR_ENABLE_SEL_INTR 0x02
2451 #define ADV_INTR_ENABLE_DPR_INTR 0x04
2452 #define ADV_INTR_ENABLE_RTA_INTR 0x08
2453 #define ADV_INTR_ENABLE_RMA_INTR 0x10
2454 #define ADV_INTR_ENABLE_RST_INTR 0x20
2455 #define ADV_INTR_ENABLE_DPE_INTR 0x40
2456 #define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
2458 #define ADV_INTR_STATUS_INTRA 0x01
2459 #define ADV_INTR_STATUS_INTRB 0x02
2460 #define ADV_INTR_STATUS_INTRC 0x04
2462 #define ADV_RISC_CSR_STOP (0x0000)
2463 #define ADV_RISC_TEST_COND (0x2000)
2464 #define ADV_RISC_CSR_RUN (0x4000)
2465 #define ADV_RISC_CSR_SINGLE_STEP (0x8000)
2467 #define ADV_CTRL_REG_HOST_INTR 0x0100
2468 #define ADV_CTRL_REG_SEL_INTR 0x0200
2469 #define ADV_CTRL_REG_DPR_INTR 0x0400
2470 #define ADV_CTRL_REG_RTA_INTR 0x0800
2471 #define ADV_CTRL_REG_RMA_INTR 0x1000
2472 #define ADV_CTRL_REG_RES_BIT14 0x2000
2473 #define ADV_CTRL_REG_DPE_INTR 0x4000
2474 #define ADV_CTRL_REG_POWER_DONE 0x8000
2475 #define ADV_CTRL_REG_ANY_INTR 0xFF00
2477 #define ADV_CTRL_REG_CMD_RESET 0x00C6
2478 #define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
2479 #define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
2480 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
2481 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
2483 #define ADV_TICKLE_NOP 0x00
2484 #define ADV_TICKLE_A 0x01
2485 #define ADV_TICKLE_B 0x02
2486 #define ADV_TICKLE_C 0x03
2488 #define ADV_SCSI_CTRL_RSTOUT 0x2000
2490 #define AdvIsIntPending(port) \
2491 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2494 * SCSI_CFG0 Register bit definitions
2496 #define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
2497 #define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
2498 #define EVEN_PARITY 0x1000 /* Select Even Parity */
2499 #define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2500 #define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
2501 #define PRIM_MODE 0x0100 /* Primitive SCSI mode */
2502 #define SCAM_EN 0x0080 /* Enable SCAM selection */
2503 #define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2504 #define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2505 #define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
2506 #define OUR_ID 0x000F /* SCSI ID */
2509 * SCSI_CFG1 Register bit definitions
2511 #define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
2512 #define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2513 #define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
2514 #define FILTER_SEL 0x0C00 /* Filter Period Selection */
2515 #define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
2516 #define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
2517 #define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
2518 #define ACTIVE_DBL 0x0200 /* Disable Active Negation */
2519 #define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
2520 #define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
2521 #define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
2522 #define TERM_CTL 0x0030 /* External SCSI Termination Bits */
2523 #define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
2524 #define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
2525 #define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
2528 * Addendum for ASC-38C0800 Chip
2530 * The ASC-38C1600 Chip uses the same definitions except that the
2531 * bus mode override bits [12:10] have been moved to byte register
2532 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
2533 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
2534 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
2535 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
2536 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
2538 #define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
2539 #define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
2540 #define HVD 0x1000 /* HVD Device Detect */
2541 #define LVD 0x0800 /* LVD Device Detect */
2542 #define SE 0x0400 /* SE Device Detect */
2543 #define TERM_LVD 0x00C0 /* LVD Termination Bits */
2544 #define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
2545 #define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
2546 #define TERM_SE 0x0030 /* SE Termination Bits */
2547 #define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
2548 #define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
2549 #define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
2550 #define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
2551 #define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
2552 #define C_DET_SE 0x0003 /* SE Cable Detect Bits */
2553 #define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
2554 #define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
2556 #define CABLE_ILLEGAL_A 0x7
2557 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
2559 #define CABLE_ILLEGAL_B 0xB
2560 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
2563 * MEM_CFG Register bit definitions
2565 #define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
2566 #define FAST_EE_CLK 0x20 /* Diagnostic Bit */
2567 #define RAM_SZ 0x1C /* Specify size of RAM to RISC */
2568 #define RAM_SZ_2KB 0x00 /* 2 KB */
2569 #define RAM_SZ_4KB 0x04 /* 4 KB */
2570 #define RAM_SZ_8KB 0x08 /* 8 KB */
2571 #define RAM_SZ_16KB 0x0C /* 16 KB */
2572 #define RAM_SZ_32KB 0x10 /* 32 KB */
2573 #define RAM_SZ_64KB 0x14 /* 64 KB */
2576 * DMA_CFG0 Register bit definitions
2578 * This register is only accessible to the host.
2580 #define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
2581 #define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
2582 #define FIFO_THRESH_16B 0x00 /* 16 bytes */
2583 #define FIFO_THRESH_32B 0x20 /* 32 bytes */
2584 #define FIFO_THRESH_48B 0x30 /* 48 bytes */
2585 #define FIFO_THRESH_64B 0x40 /* 64 bytes */
2586 #define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
2587 #define FIFO_THRESH_96B 0x60 /* 96 bytes */
2588 #define FIFO_THRESH_112B 0x70 /* 112 bytes */
2589 #define START_CTL 0x0C /* DMA start conditions */
2590 #define START_CTL_TH 0x00 /* Wait threshold level (default) */
2591 #define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
2592 #define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
2593 #define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
2594 #define READ_CMD 0x03 /* Memory Read Method */
2595 #define READ_CMD_MR 0x00 /* Memory Read */
2596 #define READ_CMD_MRL 0x02 /* Memory Read Long */
2597 #define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
2600 * ASC-38C0800 RAM BIST Register bit definitions
2602 #define RAM_TEST_MODE 0x80
2603 #define PRE_TEST_MODE 0x40
2604 #define NORMAL_MODE 0x00
2605 #define RAM_TEST_DONE 0x10
2606 #define RAM_TEST_STATUS 0x0F
2607 #define RAM_TEST_HOST_ERROR 0x08
2608 #define RAM_TEST_INTRAM_ERROR 0x04
2609 #define RAM_TEST_RISC_ERROR 0x02
2610 #define RAM_TEST_SCSI_ERROR 0x01
2611 #define RAM_TEST_SUCCESS 0x00
2612 #define PRE_TEST_VALUE 0x05
2613 #define NORMAL_VALUE 0x00
2616 * ASC38C1600 Definitions
2618 * IOPB_PCI_INT_CFG Bit Field Definitions
2621 #define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
2624 * Bit 1 can be set to change the interrupt for the Function to operate in
2625 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
2626 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
2627 * mode, otherwise the operating mode is undefined.
2629 #define TOTEMPOLE 0x02
2632 * Bit 0 can be used to change the Int Pin for the Function. The value is
2633 * 0 by default for both Functions with Function 0 using INT A and Function
2634 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
2635 * INT A is used.
2637 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
2638 * value specified in the PCI Configuration Space.
2640 #define INTAB 0x01
2642 /* a_advlib.h */
2645 * Adv Library Status Definitions
2647 #define ADV_TRUE 1
2648 #define ADV_FALSE 0
2649 #define ADV_NOERROR 1
2650 #define ADV_SUCCESS 1
2651 #define ADV_BUSY 0
2652 #define ADV_ERROR (-1)
2655 * ADV_DVC_VAR 'warn_code' values
2657 #define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
2658 #define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
2659 #define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
2660 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */
2661 #define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
2663 #define ADV_MAX_TID 15 /* max. target identifier */
2664 #define ADV_MAX_LUN 7 /* max. logical unit number */
2667 * Error code values are set in ADV_DVC_VAR 'err_code'.
2669 #define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */
2670 #define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
2671 #define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */
2672 #define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
2673 #define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */
2674 #define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
2675 #define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */
2676 #define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
2677 #define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
2678 #define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */
2679 #define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */
2680 #define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */
2681 #define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */
2682 #define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */
2685 * Fixed locations of microcode operating variables.
2687 #define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
2688 #define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
2689 #define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
2690 #define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
2691 #define ASC_MC_VERSION_NUM 0x003A /* microcode number */
2692 #define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
2693 #define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
2694 #define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
2695 #define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
2696 #define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
2697 #define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
2698 #define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
2699 #define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
2700 #define ASC_MC_CHIP_TYPE 0x009A
2701 #define ASC_MC_INTRB_CODE 0x009B
2702 #define ASC_MC_WDTR_ABLE 0x009C
2703 #define ASC_MC_SDTR_ABLE 0x009E
2704 #define ASC_MC_TAGQNG_ABLE 0x00A0
2705 #define ASC_MC_DISC_ENABLE 0x00A2
2706 #define ASC_MC_IDLE_CMD_STATUS 0x00A4
2707 #define ASC_MC_IDLE_CMD 0x00A6
2708 #define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
2709 #define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
2710 #define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
2711 #define ASC_MC_DEFAULT_MEM_CFG 0x00B0
2712 #define ASC_MC_DEFAULT_SEL_MASK 0x00B2
2713 #define ASC_MC_SDTR_DONE 0x00B6
2714 #define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
2715 #define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
2716 #define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
2717 #define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
2718 #define ASC_MC_WDTR_DONE 0x0124
2719 #define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
2720 #define ASC_MC_ICQ 0x0160
2721 #define ASC_MC_IRQ 0x0164
2722 #define ASC_MC_PPR_ABLE 0x017A
2725 * BIOS LRAM variable absolute offsets.
2727 #define BIOS_CODESEG 0x54
2728 #define BIOS_CODELEN 0x56
2729 #define BIOS_SIGNATURE 0x58
2730 #define BIOS_VERSION 0x5A
2733 * Microcode Control Flags
2735 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2736 * and handled by the microcode.
2738 #define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
2739 #define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
2742 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2744 #define HSHK_CFG_WIDE_XFR 0x8000
2745 #define HSHK_CFG_RATE 0x0F00
2746 #define HSHK_CFG_OFFSET 0x001F
2748 #define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
2749 #define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
2750 #define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
2751 #define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
2753 #define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2754 #define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
2755 #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2756 #define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
2757 #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2759 #define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
2760 #define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
2761 #define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
2762 #define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
2763 #define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
2765 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
2766 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
2768 #define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
2769 #define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
2772 * All fields here are accessed by the board microcode and need to be
2773 * little-endian.
2775 typedef struct adv_carr_t {
2776 ADV_VADDR carr_va; /* Carrier Virtual Address */
2777 ADV_PADDR carr_pa; /* Carrier Physical Address */
2778 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
2780 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
2782 * next_vpa [3:1] Reserved Bits
2783 * next_vpa [0] Done Flag set in Response Queue.
2785 ADV_VADDR next_vpa;
2786 } ADV_CARR_T;
2789 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2791 #define ASC_NEXT_VPA_MASK 0xFFFFFFF0
2793 #define ASC_RQ_DONE 0x00000001
2794 #define ASC_RQ_GOOD 0x00000002
2795 #define ASC_CQ_STOPPER 0x00000000
2797 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2799 #define ADV_CARRIER_NUM_PAGE_CROSSING \
2800 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2801 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2803 #define ADV_CARRIER_BUFSIZE \
2804 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2807 * ASC_SCSI_REQ_Q 'a_flag' definitions
2809 * The Adv Library should limit use to the lower nibble (4 bits) of
2810 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2812 #define ADV_POLL_REQUEST 0x01 /* poll for request completion */
2813 #define ADV_SCSIQ_DONE 0x02 /* request done */
2814 #define ADV_DONT_RETRY 0x08 /* don't do retry */
2816 #define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
2817 #define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
2818 #define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
2821 * Adapter temporary configuration structure
2823 * This structure can be discarded after initialization. Don't add
2824 * fields here needed after initialization.
2826 * Field naming convention:
2828 * *_enable indicates the field enables or disables a feature. The
2829 * value of the field is never reset.
2831 typedef struct adv_dvc_cfg {
2832 ushort disc_enable; /* enable disconnection */
2833 uchar chip_version; /* chip version */
2834 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2835 ushort lib_version; /* Adv Library version number */
2836 ushort control_flag; /* Microcode Control Flag */
2837 ushort mcode_date; /* Microcode date */
2838 ushort mcode_version; /* Microcode version */
2839 ushort pci_slot_info; /* high byte device/function number */
2840 /* bits 7-3 device num., bits 2-0 function num. */
2841 /* low byte bus num. */
2842 ushort serial1; /* EEPROM serial number word 1 */
2843 ushort serial2; /* EEPROM serial number word 2 */
2844 ushort serial3; /* EEPROM serial number word 3 */
2845 struct device *dev; /* pointer to the pci dev structure for this board */
2846 } ADV_DVC_CFG;
2848 struct adv_dvc_var;
2849 struct adv_scsi_req_q;
2851 typedef void (*ADV_ISR_CALLBACK)
2852 (struct adv_dvc_var *, struct adv_scsi_req_q *);
2854 typedef void (*ADV_ASYNC_CALLBACK)
2855 (struct adv_dvc_var *, uchar);
2858 * Adapter operation variable structure.
2860 * One structure is required per host adapter.
2862 * Field naming convention:
2864 * *_able indicates both whether a feature should be enabled or disabled
2865 * and whether a device isi capable of the feature. At initialization
2866 * this field may be set, but later if a device is found to be incapable
2867 * of the feature, the field is cleared.
2869 typedef struct adv_dvc_var {
2870 AdvPortAddr iop_base; /* I/O port address */
2871 ushort err_code; /* fatal error code */
2872 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
2873 ADV_ISR_CALLBACK isr_callback;
2874 ADV_ASYNC_CALLBACK async_callback;
2875 ushort wdtr_able; /* try WDTR for a device */
2876 ushort sdtr_able; /* try SDTR for a device */
2877 ushort ultra_able; /* try SDTR Ultra speed for a device */
2878 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
2879 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
2880 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
2881 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
2882 ushort tagqng_able; /* try tagged queuing with a device */
2883 ushort ppr_able; /* PPR message capable per TID bitmask. */
2884 uchar max_dvc_qng; /* maximum number of tagged commands per device */
2885 ushort start_motor; /* start motor command allowed */
2886 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
2887 uchar chip_no; /* should be assigned by caller */
2888 uchar max_host_qng; /* maximum number of Q'ed command allowed */
2889 uchar irq_no; /* IRQ number */
2890 ushort no_scam; /* scam_tolerant of EEPROM */
2891 struct asc_board *drv_ptr; /* driver pointer to private structure */
2892 uchar chip_scsi_id; /* chip SCSI target ID */
2893 uchar chip_type;
2894 uchar bist_err_code;
2895 ADV_CARR_T *carrier_buf;
2896 ADV_CARR_T *carr_freelist; /* Carrier free list. */
2897 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
2898 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
2899 ushort carr_pending_cnt; /* Count of pending carriers. */
2901 * Note: The following fields will not be used after initialization. The
2902 * driver may discard the buffer after initialization is done.
2904 ADV_DVC_CFG *cfg; /* temporary configuration structure */
2905 } ADV_DVC_VAR;
2907 #define NO_OF_SG_PER_BLOCK 15
2909 typedef struct asc_sg_block {
2910 uchar reserved1;
2911 uchar reserved2;
2912 uchar reserved3;
2913 uchar sg_cnt; /* Valid entries in block. */
2914 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
2915 struct {
2916 ADV_PADDR sg_addr; /* SG element address. */
2917 ADV_DCNT sg_count; /* SG element count. */
2918 } sg_list[NO_OF_SG_PER_BLOCK];
2919 } ADV_SG_BLOCK;
2922 * ADV_SCSI_REQ_Q - microcode request structure
2924 * All fields in this structure up to byte 60 are used by the microcode.
2925 * The microcode makes assumptions about the size and ordering of fields
2926 * in this structure. Do not change the structure definition here without
2927 * coordinating the change with the microcode.
2929 * All fields accessed by microcode must be maintained in little_endian
2930 * order.
2932 typedef struct adv_scsi_req_q {
2933 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
2934 uchar target_cmd;
2935 uchar target_id; /* Device target identifier. */
2936 uchar target_lun; /* Device target logical unit number. */
2937 ADV_PADDR data_addr; /* Data buffer physical address. */
2938 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
2939 ADV_PADDR sense_addr;
2940 ADV_PADDR carr_pa;
2941 uchar mflag;
2942 uchar sense_len;
2943 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
2944 uchar scsi_cntl;
2945 uchar done_status; /* Completion status. */
2946 uchar scsi_status; /* SCSI status byte. */
2947 uchar host_status; /* Ucode host status. */
2948 uchar sg_working_ix;
2949 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
2950 ADV_PADDR sg_real_addr; /* SG list physical address. */
2951 ADV_PADDR scsiq_rptr;
2952 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
2953 ADV_VADDR scsiq_ptr;
2954 ADV_VADDR carr_va;
2956 * End of microcode structure - 60 bytes. The rest of the structure
2957 * is used by the Adv Library and ignored by the microcode.
2959 ADV_VADDR srb_ptr;
2960 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
2961 char *vdata_addr; /* Data buffer virtual address. */
2962 uchar a_flag;
2963 uchar pad[2]; /* Pad out to a word boundary. */
2964 } ADV_SCSI_REQ_Q;
2967 * Microcode idle loop commands
2969 #define IDLE_CMD_COMPLETED 0
2970 #define IDLE_CMD_STOP_CHIP 0x0001
2971 #define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
2972 #define IDLE_CMD_SEND_INT 0x0004
2973 #define IDLE_CMD_ABORT 0x0008
2974 #define IDLE_CMD_DEVICE_RESET 0x0010
2975 #define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
2976 #define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
2977 #define IDLE_CMD_SCSIREQ 0x0080
2979 #define IDLE_CMD_STATUS_SUCCESS 0x0001
2980 #define IDLE_CMD_STATUS_FAILURE 0x0002
2983 * AdvSendIdleCmd() flag definitions.
2985 #define ADV_NOWAIT 0x01
2988 * Wait loop time out values.
2990 #define SCSI_WAIT_10_SEC 10UL /* 10 seconds */
2991 #define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
2992 #define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
2993 #define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */
2994 #define SCSI_MAX_RETRY 10 /* retry count */
2996 #define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
2997 #define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
2998 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
2999 #define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
3001 #define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
3004 * Device drivers must define the following functions.
3006 static inline ulong DvcEnterCritical(void);
3007 static inline void DvcLeaveCritical(ulong);
3008 static void DvcSleepMilliSecond(ADV_DCNT);
3009 static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
3010 uchar *, ASC_SDCNT *, int);
3011 static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
3014 * Adv Library functions available to drivers.
3016 static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3017 static int AdvISR(ADV_DVC_VAR *);
3018 static int AdvInitGetConfig(ADV_DVC_VAR *);
3019 static int AdvInitAsc3550Driver(ADV_DVC_VAR *);
3020 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
3021 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
3022 static int AdvResetChipAndSB(ADV_DVC_VAR *);
3023 static int AdvResetSB(ADV_DVC_VAR *asc_dvc);
3026 * Internal Adv Library functions.
3028 static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
3029 static int AdvInitFrom3550EEP(ADV_DVC_VAR *);
3030 static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
3031 static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
3032 static ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3033 static void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3034 static ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3035 static void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3036 static ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3037 static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3038 static void AdvWaitEEPCmd(AdvPortAddr);
3039 static ushort AdvReadEEPWord(AdvPortAddr, int);
3041 /* Read byte from a register. */
3042 #define AdvReadByteRegister(iop_base, reg_off) \
3043 (ADV_MEM_READB((iop_base) + (reg_off)))
3045 /* Write byte to a register. */
3046 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
3047 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3049 /* Read word (2 bytes) from a register. */
3050 #define AdvReadWordRegister(iop_base, reg_off) \
3051 (ADV_MEM_READW((iop_base) + (reg_off)))
3053 /* Write word (2 bytes) to a register. */
3054 #define AdvWriteWordRegister(iop_base, reg_off, word) \
3055 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
3057 /* Write dword (4 bytes) to a register. */
3058 #define AdvWriteDWordRegister(iop_base, reg_off, dword) \
3059 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
3061 /* Read byte from LRAM. */
3062 #define AdvReadByteLram(iop_base, addr, byte) \
3063 do { \
3064 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3065 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3066 } while (0)
3068 /* Write byte to LRAM. */
3069 #define AdvWriteByteLram(iop_base, addr, byte) \
3070 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3071 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3073 /* Read word (2 bytes) from LRAM. */
3074 #define AdvReadWordLram(iop_base, addr, word) \
3075 do { \
3076 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3077 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3078 } while (0)
3080 /* Write word (2 bytes) to LRAM. */
3081 #define AdvWriteWordLram(iop_base, addr, word) \
3082 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3083 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3085 /* Write little-endian double word (4 bytes) to LRAM */
3086 /* Because of unspecified C language ordering don't use auto-increment. */
3087 #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
3088 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3089 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3090 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3091 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3092 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3093 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3095 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
3096 #define AdvReadWordAutoIncLram(iop_base) \
3097 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3099 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
3100 #define AdvWriteWordAutoIncLram(iop_base, word) \
3101 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3104 * Define macro to check for Condor signature.
3106 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3107 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3109 #define AdvFindSignature(iop_base) \
3110 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3111 ADV_CHIP_ID_BYTE) && \
3112 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3113 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
3116 * Define macro to Return the version number of the chip at 'iop_base'.
3118 * The second parameter 'bus_type' is currently unused.
3120 #define AdvGetChipVersion(iop_base, bus_type) \
3121 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3124 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3125 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3127 * If the request has not yet been sent to the device it will simply be
3128 * aborted from RISC memory. If the request is disconnected it will be
3129 * aborted on reselection by sending an Abort Message to the target ID.
3131 * Return value:
3132 * ADV_TRUE(1) - Queue was successfully aborted.
3133 * ADV_FALSE(0) - Queue was not found on the active queue list.
3135 #define AdvAbortQueue(asc_dvc, scsiq) \
3136 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3137 (ADV_DCNT) (scsiq))
3140 * Send a Bus Device Reset Message to the specified target ID.
3142 * All outstanding commands will be purged if sending the
3143 * Bus Device Reset Message is successful.
3145 * Return Value:
3146 * ADV_TRUE(1) - All requests on the target are purged.
3147 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3148 * are not purged.
3150 #define AdvResetDevice(asc_dvc, target_id) \
3151 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3152 (ADV_DCNT) (target_id))
3155 * SCSI Wide Type definition.
3157 #define ADV_SCSI_BIT_ID_TYPE ushort
3160 * AdvInitScsiTarget() 'cntl_flag' options.
3162 #define ADV_SCAN_LUN 0x01
3163 #define ADV_CAPINFO_NOLUN 0x02
3166 * Convert target id to target id bit mask.
3168 #define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
3171 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3174 #define QD_NO_STATUS 0x00 /* Request not completed yet. */
3175 #define QD_NO_ERROR 0x01
3176 #define QD_ABORTED_BY_HOST 0x02
3177 #define QD_WITH_ERROR 0x04
3179 #define QHSTA_NO_ERROR 0x00
3180 #define QHSTA_M_SEL_TIMEOUT 0x11
3181 #define QHSTA_M_DATA_OVER_RUN 0x12
3182 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3183 #define QHSTA_M_QUEUE_ABORTED 0x15
3184 #define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
3185 #define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
3186 #define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
3187 #define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
3188 #define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
3189 #define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
3190 #define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
3191 /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
3192 #define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
3193 #define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
3194 #define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
3195 #define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
3196 #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
3197 #define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
3198 #define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
3199 #define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
3200 #define QHSTA_M_WTM_TIMEOUT 0x41
3201 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
3202 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
3203 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
3204 #define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
3205 #define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
3206 #define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
3209 * Default EEPROM Configuration structure defined in a_init.c.
3211 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
3212 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
3213 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
3216 * DvcGetPhyAddr() flag arguments
3218 #define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
3219 #define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
3220 #define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
3221 #define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
3222 #define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
3223 #define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
3225 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
3226 #define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
3227 #define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
3228 #define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
3231 * Total contiguous memory needed for driver SG blocks.
3233 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3234 * number of scatter-gather elements the driver supports in a
3235 * single request.
3238 #define ADV_SG_LIST_MAX_BYTE_SIZE \
3239 (sizeof(ADV_SG_BLOCK) * \
3240 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3243 * --- Driver Constants and Macros
3246 /* Reference Scsi_Host hostdata */
3247 #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3249 /* asc_board_t flags */
3250 #define ASC_HOST_IN_RESET 0x01
3251 #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
3252 #define ASC_SELECT_QUEUE_DEPTHS 0x08
3254 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3255 #define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD)
3257 #define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
3259 #define ASC_INFO_SIZE 128 /* advansys_info() line size */
3261 #ifdef CONFIG_PROC_FS
3262 /* /proc/scsi/advansys/[0...] related definitions */
3263 #define ASC_PRTBUF_SIZE 2048
3264 #define ASC_PRTLINE_SIZE 160
3266 #define ASC_PRT_NEXT() \
3267 if (cp) { \
3268 totlen += len; \
3269 leftlen -= len; \
3270 if (leftlen == 0) { \
3271 return totlen; \
3273 cp += len; \
3275 #endif /* CONFIG_PROC_FS */
3277 /* Asc Library return codes */
3278 #define ASC_TRUE 1
3279 #define ASC_FALSE 0
3280 #define ASC_NOERROR 1
3281 #define ASC_BUSY 0
3282 #define ASC_ERROR (-1)
3284 /* struct scsi_cmnd function return codes */
3285 #define STATUS_BYTE(byte) (byte)
3286 #define MSG_BYTE(byte) ((byte) << 8)
3287 #define HOST_BYTE(byte) ((byte) << 16)
3288 #define DRIVER_BYTE(byte) ((byte) << 24)
3291 * The following definitions and macros are OS independent interfaces to
3292 * the queue functions:
3293 * REQ - SCSI request structure
3294 * REQP - pointer to SCSI request structure
3295 * REQPTID(reqp) - reqp's target id
3296 * REQPNEXT(reqp) - reqp's next pointer
3297 * REQPNEXTP(reqp) - pointer to reqp's next pointer
3298 * REQPTIME(reqp) - reqp's time stamp value
3299 * REQTIMESTAMP() - system time stamp value
3301 typedef struct scsi_cmnd REQ, *REQP;
3302 #define REQPNEXT(reqp) ((REQP) ((reqp)->host_scribble))
3303 #define REQPNEXTP(reqp) ((REQP *) &((reqp)->host_scribble))
3304 #define REQPTID(reqp) ((reqp)->device->id)
3305 #define REQPTIME(reqp) ((reqp)->SCp.this_residual)
3306 #define REQTIMESTAMP() (jiffies)
3308 #define REQTIMESTAT(function, ascq, reqp, tid) \
3311 * If the request time stamp is less than the system time stamp, then \
3312 * maybe the system time stamp wrapped. Set the request time to zero.\
3313 */ \
3314 if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3315 REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3316 } else { \
3317 /* Indicate an error occurred with the assertion. */ \
3318 ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3319 REQPTIME(reqp) = 0; \
3321 /* Handle first minimum time case without external initialization. */ \
3322 if (((ascq)->q_tot_cnt[tid] == 1) || \
3323 (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3324 (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3325 ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3326 (function), (tid), (ascq)->q_min_tim[tid]); \
3328 if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3329 (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3330 ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3331 (function), tid, (ascq)->q_max_tim[tid]); \
3333 (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3334 /* Reset the time stamp field. */ \
3335 REQPTIME(reqp) = 0; \
3338 /* asc_enqueue() flags */
3339 #define ASC_FRONT 1
3340 #define ASC_BACK 2
3342 /* asc_dequeue_list() argument */
3343 #define ASC_TID_ALL (-1)
3345 /* Return non-zero, if the queue is empty. */
3346 #define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0)
3348 #ifndef ADVANSYS_STATS
3349 #define ASC_STATS(shost, counter)
3350 #define ASC_STATS_ADD(shost, counter, count)
3351 #else /* ADVANSYS_STATS */
3352 #define ASC_STATS(shost, counter) \
3353 (ASC_BOARDP(shost)->asc_stats.counter++)
3355 #define ASC_STATS_ADD(shost, counter, count) \
3356 (ASC_BOARDP(shost)->asc_stats.counter += (count))
3357 #endif /* ADVANSYS_STATS */
3359 #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3361 /* If the result wraps when calculating tenths, return 0. */
3362 #define ASC_TENTHS(num, den) \
3363 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3364 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3367 * Display a message to the console.
3369 #define ASC_PRINT(s) \
3371 printk("advansys: "); \
3372 printk(s); \
3375 #define ASC_PRINT1(s, a1) \
3377 printk("advansys: "); \
3378 printk((s), (a1)); \
3381 #define ASC_PRINT2(s, a1, a2) \
3383 printk("advansys: "); \
3384 printk((s), (a1), (a2)); \
3387 #define ASC_PRINT3(s, a1, a2, a3) \
3389 printk("advansys: "); \
3390 printk((s), (a1), (a2), (a3)); \
3393 #define ASC_PRINT4(s, a1, a2, a3, a4) \
3395 printk("advansys: "); \
3396 printk((s), (a1), (a2), (a3), (a4)); \
3399 #ifndef ADVANSYS_DEBUG
3401 #define ASC_DBG(lvl, s)
3402 #define ASC_DBG1(lvl, s, a1)
3403 #define ASC_DBG2(lvl, s, a1, a2)
3404 #define ASC_DBG3(lvl, s, a1, a2, a3)
3405 #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3406 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3407 #define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3408 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3409 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3410 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3411 #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3412 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
3413 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
3414 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
3415 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3417 #else /* ADVANSYS_DEBUG */
3420 * Debugging Message Levels:
3421 * 0: Errors Only
3422 * 1: High-Level Tracing
3423 * 2-N: Verbose Tracing
3426 #define ASC_DBG(lvl, s) \
3428 if (asc_dbglvl >= (lvl)) { \
3429 printk(s); \
3433 #define ASC_DBG1(lvl, s, a1) \
3435 if (asc_dbglvl >= (lvl)) { \
3436 printk((s), (a1)); \
3440 #define ASC_DBG2(lvl, s, a1, a2) \
3442 if (asc_dbglvl >= (lvl)) { \
3443 printk((s), (a1), (a2)); \
3447 #define ASC_DBG3(lvl, s, a1, a2, a3) \
3449 if (asc_dbglvl >= (lvl)) { \
3450 printk((s), (a1), (a2), (a3)); \
3454 #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3456 if (asc_dbglvl >= (lvl)) { \
3457 printk((s), (a1), (a2), (a3), (a4)); \
3461 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3463 if (asc_dbglvl >= (lvl)) { \
3464 asc_prt_scsi_host(s); \
3468 #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3470 if (asc_dbglvl >= (lvl)) { \
3471 asc_prt_scsi_cmnd(s); \
3475 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3477 if (asc_dbglvl >= (lvl)) { \
3478 asc_prt_asc_scsi_q(scsiqp); \
3482 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3484 if (asc_dbglvl >= (lvl)) { \
3485 asc_prt_asc_qdone_info(qdone); \
3489 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3491 if (asc_dbglvl >= (lvl)) { \
3492 asc_prt_adv_scsi_req_q(scsiqp); \
3496 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3498 if (asc_dbglvl >= (lvl)) { \
3499 asc_prt_hex((name), (start), (length)); \
3503 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3504 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3506 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3507 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3509 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3510 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3511 #endif /* ADVANSYS_DEBUG */
3513 #ifndef ADVANSYS_ASSERT
3514 #define ASC_ASSERT(a)
3515 #else /* ADVANSYS_ASSERT */
3517 #define ASC_ASSERT(a) \
3519 if (!(a)) { \
3520 printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3521 __FILE__, __LINE__); \
3525 #endif /* ADVANSYS_ASSERT */
3528 * --- Driver Structures
3531 #ifdef ADVANSYS_STATS
3533 /* Per board statistics structure */
3534 struct asc_stats {
3535 /* Driver Entrypoint Statistics */
3536 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
3537 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
3538 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
3539 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
3540 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
3541 ADV_DCNT done; /* # calls to request's scsi_done function */
3542 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
3543 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
3544 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
3545 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3546 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
3547 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
3548 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
3549 ADV_DCNT exe_unknown; /* # unknown returns. */
3550 /* Data Transfer Statistics */
3551 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
3552 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
3553 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
3554 ADV_DCNT sg_elem; /* # scatter-gather elements */
3555 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
3557 #endif /* ADVANSYS_STATS */
3560 * Request queuing structure
3562 typedef struct asc_queue {
3563 ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */
3564 REQP q_first[ADV_MAX_TID + 1]; /* first queued request */
3565 REQP q_last[ADV_MAX_TID + 1]; /* last queued request */
3566 #ifdef ADVANSYS_STATS
3567 short q_cur_cnt[ADV_MAX_TID + 1]; /* current queue count */
3568 short q_max_cnt[ADV_MAX_TID + 1]; /* maximum queue count */
3569 ADV_DCNT q_tot_cnt[ADV_MAX_TID + 1]; /* total enqueue count */
3570 ADV_DCNT q_tot_tim[ADV_MAX_TID + 1]; /* total time queued */
3571 ushort q_max_tim[ADV_MAX_TID + 1]; /* maximum time queued */
3572 ushort q_min_tim[ADV_MAX_TID + 1]; /* minimum time queued */
3573 #endif /* ADVANSYS_STATS */
3574 } asc_queue_t;
3577 * Adv Library Request Structures
3579 * The following two structures are used to process Wide Board requests.
3581 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
3582 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
3583 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
3584 * Mid-Level SCSI request structure.
3586 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
3587 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
3588 * up to 255 scatter-gather elements may be used per request or
3589 * ADV_SCSI_REQ_Q.
3591 * Both structures must be 32 byte aligned.
3593 typedef struct adv_sgblk {
3594 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
3595 uchar align[32]; /* Sgblock structure padding. */
3596 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
3597 } adv_sgblk_t;
3599 typedef struct adv_req {
3600 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
3601 uchar align[32]; /* Request structure padding. */
3602 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
3603 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
3604 struct adv_req *next_reqp; /* Next Request Structure. */
3605 } adv_req_t;
3608 * Structure allocated for each board.
3610 * This structure is allocated by scsi_host_alloc() at the end
3611 * of the 'Scsi_Host' structure starting at the 'hostdata'
3612 * field. It is guaranteed to be allocated from DMA-able memory.
3614 typedef struct asc_board {
3615 int id; /* Board Id */
3616 uint flags; /* Board flags */
3617 union {
3618 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
3619 ADV_DVC_VAR adv_dvc_var; /* Wide board */
3620 } dvc_var;
3621 union {
3622 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
3623 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
3624 } dvc_cfg;
3625 ushort asc_n_io_port; /* Number I/O ports. */
3626 asc_queue_t active; /* Active command queue */
3627 asc_queue_t waiting; /* Waiting command queue */
3628 asc_queue_t done; /* Done command queue */
3629 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
3630 struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */
3631 ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
3632 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
3633 ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
3634 union {
3635 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
3636 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
3637 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
3638 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
3639 } eep_config;
3640 ulong last_reset; /* Saved last reset time */
3641 spinlock_t lock; /* Board spinlock */
3642 /* /proc/scsi/advansys/[0...] */
3643 char *prtbuf; /* /proc print buffer */
3644 #ifdef ADVANSYS_STATS
3645 struct asc_stats asc_stats; /* Board statistics */
3646 #endif /* ADVANSYS_STATS */
3648 * The following fields are used only for Narrow Boards.
3650 uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */
3652 * The following fields are used only for Wide Boards.
3654 void __iomem *ioremap_addr; /* I/O Memory remap address. */
3655 ushort ioport; /* I/O Port address. */
3656 ADV_CARR_T *carrp; /* ADV_CARR_T memory block. */
3657 adv_req_t *orig_reqp; /* adv_req_t memory block. */
3658 adv_req_t *adv_reqp; /* Request structures. */
3659 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
3660 ushort bios_signature; /* BIOS Signature. */
3661 ushort bios_version; /* BIOS Version. */
3662 ushort bios_codeseg; /* BIOS Code Segment. */
3663 ushort bios_codelen; /* BIOS Code Segment Length. */
3664 } asc_board_t;
3666 /* Number of boards detected in system. */
3667 static int asc_board_count;
3669 /* Overrun buffer used by all narrow boards. */
3670 static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
3673 * Global structures required to issue a command.
3675 static ASC_SCSI_Q asc_scsi_q = { {0} };
3676 static ASC_SG_HEAD asc_sg_head = { 0 };
3678 #ifdef ADVANSYS_DEBUG
3679 static int asc_dbglvl = 3;
3680 #endif /* ADVANSYS_DEBUG */
3683 * --- Driver Function Prototypes
3686 static int advansys_slave_configure(struct scsi_device *);
3687 static void asc_scsi_done_list(struct scsi_cmnd *);
3688 static int asc_execute_scsi_cmnd(struct scsi_cmnd *);
3689 static int asc_build_req(asc_board_t *, struct scsi_cmnd *);
3690 static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
3691 static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
3692 static void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
3693 static void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3694 static void adv_async_callback(ADV_DVC_VAR *, uchar);
3695 static void asc_enqueue(asc_queue_t *, REQP, int);
3696 static REQP asc_dequeue(asc_queue_t *, int);
3697 static REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
3698 static int asc_rmqueue(asc_queue_t *, REQP);
3699 static void asc_execute_queue(asc_queue_t *);
3700 #ifdef CONFIG_PROC_FS
3701 static int asc_proc_copy(off_t, off_t, char *, int, char *, int);
3702 static int asc_prt_board_devices(struct Scsi_Host *, char *, int);
3703 static int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
3704 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
3705 static int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
3706 static int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
3707 static int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
3708 static int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
3709 static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
3710 static int asc_prt_line(char *, int, char *fmt, ...);
3711 #endif /* CONFIG_PROC_FS */
3713 /* Declaration for Asc Library internal functions referenced by driver. */
3714 static int AscFindSignature(PortAddr);
3715 static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
3717 /* Statistics function prototypes. */
3718 #ifdef ADVANSYS_STATS
3719 #ifdef CONFIG_PROC_FS
3720 static int asc_prt_board_stats(struct Scsi_Host *, char *, int);
3721 static int asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
3722 #endif /* CONFIG_PROC_FS */
3723 #endif /* ADVANSYS_STATS */
3725 /* Debug function prototypes. */
3726 #ifdef ADVANSYS_DEBUG
3727 static void asc_prt_scsi_host(struct Scsi_Host *);
3728 static void asc_prt_scsi_cmnd(struct scsi_cmnd *);
3729 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
3730 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
3731 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
3732 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
3733 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
3734 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
3735 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
3736 static void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
3737 static void asc_prt_hex(char *f, uchar *, int);
3738 #endif /* ADVANSYS_DEBUG */
3740 #ifdef CONFIG_PROC_FS
3742 * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
3744 * *buffer: I/O buffer
3745 * **start: if inout == FALSE pointer into buffer where user read should start
3746 * offset: current offset into a /proc/scsi/advansys/[0...] file
3747 * length: length of buffer
3748 * hostno: Scsi_Host host_no
3749 * inout: TRUE - user is writing; FALSE - user is reading
3751 * Return the number of bytes read from or written to a
3752 * /proc/scsi/advansys/[0...] file.
3754 * Note: This function uses the per board buffer 'prtbuf' which is
3755 * allocated when the board is initialized in advansys_detect(). The
3756 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
3757 * used to write to the buffer. The way asc_proc_copy() is written
3758 * if 'prtbuf' is too small it will not be overwritten. Instead the
3759 * user just won't get all the available statistics.
3761 static int
3762 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
3763 off_t offset, int length, int inout)
3765 asc_board_t *boardp;
3766 char *cp;
3767 int cplen;
3768 int cnt;
3769 int totcnt;
3770 int leftlen;
3771 char *curbuf;
3772 off_t advoffset;
3773 #ifdef ADVANSYS_STATS
3774 int tgt_id;
3775 #endif /* ADVANSYS_STATS */
3777 ASC_DBG(1, "advansys_proc_info: begin\n");
3780 * User write not supported.
3782 if (inout == TRUE) {
3783 return (-ENOSYS);
3787 * User read of /proc/scsi/advansys/[0...] file.
3790 boardp = ASC_BOARDP(shost);
3792 /* Copy read data starting at the beginning of the buffer. */
3793 *start = buffer;
3794 curbuf = buffer;
3795 advoffset = 0;
3796 totcnt = 0;
3797 leftlen = length;
3800 * Get board configuration information.
3802 * advansys_info() returns the board string from its own static buffer.
3804 cp = (char *)advansys_info(shost);
3805 strcat(cp, "\n");
3806 cplen = strlen(cp);
3807 /* Copy board information. */
3808 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3809 totcnt += cnt;
3810 leftlen -= cnt;
3811 if (leftlen == 0) {
3812 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3813 return totcnt;
3815 advoffset += cplen;
3816 curbuf += cnt;
3819 * Display Wide Board BIOS Information.
3821 if (ASC_WIDE_BOARD(boardp)) {
3822 cp = boardp->prtbuf;
3823 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
3824 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3825 cnt =
3826 asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
3827 cplen);
3828 totcnt += cnt;
3829 leftlen -= cnt;
3830 if (leftlen == 0) {
3831 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3832 return totcnt;
3834 advoffset += cplen;
3835 curbuf += cnt;
3839 * Display driver information for each device attached to the board.
3841 cp = boardp->prtbuf;
3842 cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
3843 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3844 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3845 totcnt += cnt;
3846 leftlen -= cnt;
3847 if (leftlen == 0) {
3848 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3849 return totcnt;
3851 advoffset += cplen;
3852 curbuf += cnt;
3855 * Display EEPROM configuration for the board.
3857 cp = boardp->prtbuf;
3858 if (ASC_NARROW_BOARD(boardp)) {
3859 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
3860 } else {
3861 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
3863 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3864 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3865 totcnt += cnt;
3866 leftlen -= cnt;
3867 if (leftlen == 0) {
3868 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3869 return totcnt;
3871 advoffset += cplen;
3872 curbuf += cnt;
3875 * Display driver configuration and information for the board.
3877 cp = boardp->prtbuf;
3878 cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
3879 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3880 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3881 totcnt += cnt;
3882 leftlen -= cnt;
3883 if (leftlen == 0) {
3884 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3885 return totcnt;
3887 advoffset += cplen;
3888 curbuf += cnt;
3890 #ifdef ADVANSYS_STATS
3892 * Display driver statistics for the board.
3894 cp = boardp->prtbuf;
3895 cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
3896 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
3897 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3898 totcnt += cnt;
3899 leftlen -= cnt;
3900 if (leftlen == 0) {
3901 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3902 return totcnt;
3904 advoffset += cplen;
3905 curbuf += cnt;
3908 * Display driver statistics for each target.
3910 for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
3911 cp = boardp->prtbuf;
3912 cplen = asc_prt_target_stats(shost, tgt_id, cp,
3913 ASC_PRTBUF_SIZE);
3914 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
3915 cnt =
3916 asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
3917 cplen);
3918 totcnt += cnt;
3919 leftlen -= cnt;
3920 if (leftlen == 0) {
3921 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3922 return totcnt;
3924 advoffset += cplen;
3925 curbuf += cnt;
3927 #endif /* ADVANSYS_STATS */
3930 * Display Asc Library dynamic configuration information
3931 * for the board.
3933 cp = boardp->prtbuf;
3934 if (ASC_NARROW_BOARD(boardp)) {
3935 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
3936 } else {
3937 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
3939 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3940 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3941 totcnt += cnt;
3942 leftlen -= cnt;
3943 if (leftlen == 0) {
3944 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3945 return totcnt;
3947 advoffset += cplen;
3948 curbuf += cnt;
3950 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3952 return totcnt;
3954 #endif /* CONFIG_PROC_FS */
3957 * advansys_info()
3959 * Return suitable for printing on the console with the argument
3960 * adapter's configuration information.
3962 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
3963 * otherwise the static 'info' array will be overrun.
3965 static const char *advansys_info(struct Scsi_Host *shost)
3967 static char info[ASC_INFO_SIZE];
3968 asc_board_t *boardp;
3969 ASC_DVC_VAR *asc_dvc_varp;
3970 ADV_DVC_VAR *adv_dvc_varp;
3971 char *busname;
3972 int iolen;
3973 char *widename = NULL;
3975 boardp = ASC_BOARDP(shost);
3976 if (ASC_NARROW_BOARD(boardp)) {
3977 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3978 ASC_DBG(1, "advansys_info: begin\n");
3979 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
3980 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
3981 ASC_IS_ISAPNP) {
3982 busname = "ISA PnP";
3983 } else {
3984 busname = "ISA";
3986 /* Don't reference 'shost->n_io_port'; It may be truncated. */
3987 sprintf(info,
3988 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
3989 ASC_VERSION, busname,
3990 (ulong)shost->io_port,
3991 (ulong)shost->io_port + boardp->asc_n_io_port -
3992 1, shost->irq, shost->dma_channel);
3993 } else {
3994 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
3995 busname = "VL";
3996 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
3997 busname = "EISA";
3998 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
3999 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
4000 == ASC_IS_PCI_ULTRA) {
4001 busname = "PCI Ultra";
4002 } else {
4003 busname = "PCI";
4005 } else {
4006 busname = "?";
4007 ASC_PRINT2
4008 ("advansys_info: board %d: unknown bus type %d\n",
4009 boardp->id, asc_dvc_varp->bus_type);
4011 /* Don't reference 'shost->n_io_port'; It may be truncated. */
4012 sprintf(info,
4013 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
4014 ASC_VERSION, busname,
4015 (ulong)shost->io_port,
4016 (ulong)shost->io_port + boardp->asc_n_io_port -
4017 1, shost->irq);
4019 } else {
4021 * Wide Adapter Information
4023 * Memory-mapped I/O is used instead of I/O space to access
4024 * the adapter, but display the I/O Port range. The Memory
4025 * I/O address is displayed through the driver /proc file.
4027 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4028 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4029 iolen = ADV_3550_IOLEN;
4030 widename = "Ultra-Wide";
4031 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4032 iolen = ADV_38C0800_IOLEN;
4033 widename = "Ultra2-Wide";
4034 } else {
4035 iolen = ADV_38C1600_IOLEN;
4036 widename = "Ultra3-Wide";
4038 sprintf(info,
4039 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
4040 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
4041 (ulong)adv_dvc_varp->iop_base + iolen - 1, shost->irq);
4043 ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
4044 ASC_DBG(1, "advansys_info: end\n");
4045 return info;
4049 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
4051 * This function always returns 0. Command return status is saved
4052 * in the 'scp' result field.
4054 static int
4055 advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *))
4057 struct Scsi_Host *shost;
4058 asc_board_t *boardp;
4059 ulong flags;
4060 struct scsi_cmnd *done_scp;
4062 shost = scp->device->host;
4063 boardp = ASC_BOARDP(shost);
4064 ASC_STATS(shost, queuecommand);
4066 /* host_lock taken by mid-level prior to call but need to protect */
4067 /* against own ISR */
4068 spin_lock_irqsave(&boardp->lock, flags);
4071 * Block new commands while handling a reset or abort request.
4073 if (boardp->flags & ASC_HOST_IN_RESET) {
4074 ASC_DBG1(1,
4075 "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
4076 (ulong)scp);
4077 scp->result = HOST_BYTE(DID_RESET);
4080 * Add blocked requests to the board's 'done' queue. The queued
4081 * requests will be completed at the end of the abort or reset
4082 * handling.
4084 asc_enqueue(&boardp->done, scp, ASC_BACK);
4085 spin_unlock_irqrestore(&boardp->lock, flags);
4086 return 0;
4090 * Attempt to execute any waiting commands for the board.
4092 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4093 ASC_DBG(1,
4094 "advansys_queuecommand: before asc_execute_queue() waiting\n");
4095 asc_execute_queue(&boardp->waiting);
4099 * Save the function pointer to Linux mid-level 'done' function
4100 * and attempt to execute the command.
4102 * If ASC_NOERROR is returned the request has been added to the
4103 * board's 'active' queue and will be completed by the interrupt
4104 * handler.
4106 * If ASC_BUSY is returned add the request to the board's per
4107 * target waiting list. This is the first time the request has
4108 * been tried. Add it to the back of the waiting list. It will be
4109 * retried later.
4111 * If an error occurred, the request will have been placed on the
4112 * board's 'done' queue and must be completed before returning.
4114 scp->scsi_done = done;
4115 switch (asc_execute_scsi_cmnd(scp)) {
4116 case ASC_NOERROR:
4117 break;
4118 case ASC_BUSY:
4119 asc_enqueue(&boardp->waiting, scp, ASC_BACK);
4120 break;
4121 case ASC_ERROR:
4122 default:
4123 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
4124 /* Interrupts could be enabled here. */
4125 asc_scsi_done_list(done_scp);
4126 break;
4128 spin_unlock_irqrestore(&boardp->lock, flags);
4130 return 0;
4134 * advansys_reset()
4136 * Reset the bus associated with the command 'scp'.
4138 * This function runs its own thread. Interrupts must be blocked but
4139 * sleeping is allowed and no locking other than for host structures is
4140 * required. Returns SUCCESS or FAILED.
4142 static int advansys_reset(struct scsi_cmnd *scp)
4144 struct Scsi_Host *shost;
4145 asc_board_t *boardp;
4146 ASC_DVC_VAR *asc_dvc_varp;
4147 ADV_DVC_VAR *adv_dvc_varp;
4148 ulong flags;
4149 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4150 struct scsi_cmnd *tscp, *new_last_scp;
4151 int status;
4152 int ret = SUCCESS;
4154 ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp);
4156 #ifdef ADVANSYS_STATS
4157 if (scp->device->host != NULL) {
4158 ASC_STATS(scp->device->host, reset);
4160 #endif /* ADVANSYS_STATS */
4162 if ((shost = scp->device->host) == NULL) {
4163 scp->result = HOST_BYTE(DID_ERROR);
4164 return FAILED;
4167 boardp = ASC_BOARDP(shost);
4169 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
4170 boardp->id);
4172 * Check for re-entrancy.
4174 spin_lock_irqsave(&boardp->lock, flags);
4175 if (boardp->flags & ASC_HOST_IN_RESET) {
4176 spin_unlock_irqrestore(&boardp->lock, flags);
4177 return FAILED;
4179 boardp->flags |= ASC_HOST_IN_RESET;
4180 spin_unlock_irqrestore(&boardp->lock, flags);
4182 if (ASC_NARROW_BOARD(boardp)) {
4184 * Narrow Board
4186 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4189 * Reset the chip and SCSI bus.
4191 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
4192 status = AscInitAsc1000Driver(asc_dvc_varp);
4194 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
4195 if (asc_dvc_varp->err_code) {
4196 ASC_PRINT2
4197 ("advansys_reset: board %d: SCSI bus reset error: 0x%x\n",
4198 boardp->id, asc_dvc_varp->err_code);
4199 ret = FAILED;
4200 } else if (status) {
4201 ASC_PRINT2
4202 ("advansys_reset: board %d: SCSI bus reset warning: 0x%x\n",
4203 boardp->id, status);
4204 } else {
4205 ASC_PRINT1
4206 ("advansys_reset: board %d: SCSI bus reset successful.\n",
4207 boardp->id);
4210 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
4211 spin_lock_irqsave(&boardp->lock, flags);
4213 } else {
4215 * Wide Board
4217 * If the suggest reset bus flags are set, then reset the bus.
4218 * Otherwise only reset the device.
4220 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4223 * Reset the target's SCSI bus.
4225 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
4226 switch (AdvResetChipAndSB(adv_dvc_varp)) {
4227 case ASC_TRUE:
4228 ASC_PRINT1
4229 ("advansys_reset: board %d: SCSI bus reset successful.\n",
4230 boardp->id);
4231 break;
4232 case ASC_FALSE:
4233 default:
4234 ASC_PRINT1
4235 ("advansys_reset: board %d: SCSI bus reset error.\n",
4236 boardp->id);
4237 ret = FAILED;
4238 break;
4240 spin_lock_irqsave(&boardp->lock, flags);
4241 (void)AdvISR(adv_dvc_varp);
4243 /* Board lock is held. */
4246 * Dequeue all board 'done' requests. A pointer to the last request
4247 * is returned in 'last_scp'.
4249 done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
4252 * Dequeue all board 'active' requests for all devices and set
4253 * the request status to DID_RESET. A pointer to the last request
4254 * is returned in 'last_scp'.
4256 if (done_scp == NULL) {
4257 done_scp =
4258 asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL);
4259 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4260 tscp->result = HOST_BYTE(DID_RESET);
4262 } else {
4263 /* Append to 'done_scp' at the end with 'last_scp'. */
4264 ASC_ASSERT(last_scp != NULL);
4265 last_scp->host_scribble =
4266 (unsigned char *)asc_dequeue_list(&boardp->active,
4267 &new_last_scp,
4268 ASC_TID_ALL);
4269 if (new_last_scp != NULL) {
4270 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4271 for (tscp = REQPNEXT(last_scp); tscp;
4272 tscp = REQPNEXT(tscp)) {
4273 tscp->result = HOST_BYTE(DID_RESET);
4275 last_scp = new_last_scp;
4280 * Dequeue all 'waiting' requests and set the request status
4281 * to DID_RESET.
4283 if (done_scp == NULL) {
4284 done_scp =
4285 asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL);
4286 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4287 tscp->result = HOST_BYTE(DID_RESET);
4289 } else {
4290 /* Append to 'done_scp' at the end with 'last_scp'. */
4291 ASC_ASSERT(last_scp != NULL);
4292 last_scp->host_scribble =
4293 (unsigned char *)asc_dequeue_list(&boardp->waiting,
4294 &new_last_scp,
4295 ASC_TID_ALL);
4296 if (new_last_scp != NULL) {
4297 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4298 for (tscp = REQPNEXT(last_scp); tscp;
4299 tscp = REQPNEXT(tscp)) {
4300 tscp->result = HOST_BYTE(DID_RESET);
4302 last_scp = new_last_scp;
4306 /* Save the time of the most recently completed reset. */
4307 boardp->last_reset = jiffies;
4309 /* Clear reset flag. */
4310 boardp->flags &= ~ASC_HOST_IN_RESET;
4311 spin_unlock_irqrestore(&boardp->lock, flags);
4314 * Complete all the 'done_scp' requests.
4316 if (done_scp != NULL) {
4317 asc_scsi_done_list(done_scp);
4320 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
4322 return ret;
4326 * advansys_biosparam()
4328 * Translate disk drive geometry if the "BIOS greater than 1 GB"
4329 * support is enabled for a drive.
4331 * ip (information pointer) is an int array with the following definition:
4332 * ip[0]: heads
4333 * ip[1]: sectors
4334 * ip[2]: cylinders
4336 static int
4337 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
4338 sector_t capacity, int ip[])
4340 asc_board_t *boardp;
4342 ASC_DBG(1, "advansys_biosparam: begin\n");
4343 ASC_STATS(sdev->host, biosparam);
4344 boardp = ASC_BOARDP(sdev->host);
4345 if (ASC_NARROW_BOARD(boardp)) {
4346 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
4347 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
4348 ip[0] = 255;
4349 ip[1] = 63;
4350 } else {
4351 ip[0] = 64;
4352 ip[1] = 32;
4354 } else {
4355 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
4356 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
4357 ip[0] = 255;
4358 ip[1] = 63;
4359 } else {
4360 ip[0] = 64;
4361 ip[1] = 32;
4364 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
4365 ASC_DBG(1, "advansys_biosparam: end\n");
4366 return 0;
4369 static struct scsi_host_template advansys_template = {
4370 .proc_name = "advansys",
4371 #ifdef CONFIG_PROC_FS
4372 .proc_info = advansys_proc_info,
4373 #endif
4374 .name = "advansys",
4375 .info = advansys_info,
4376 .queuecommand = advansys_queuecommand,
4377 .eh_bus_reset_handler = advansys_reset,
4378 .bios_param = advansys_biosparam,
4379 .slave_configure = advansys_slave_configure,
4381 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
4382 * must be set. The flag will be cleared in advansys_board_found
4383 * for non-ISA adapters.
4385 .unchecked_isa_dma = 1,
4387 * All adapters controlled by this driver are capable of large
4388 * scatter-gather lists. According to the mid-level SCSI documentation
4389 * this obviates any performance gain provided by setting
4390 * 'use_clustering'. But empirically while CPU utilization is increased
4391 * by enabling clustering, I/O throughput increases as well.
4393 .use_clustering = ENABLE_CLUSTERING,
4397 * --- Miscellaneous Driver Functions
4401 * First-level interrupt handler.
4403 * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
4404 * all boards are currently checked for interrupts on each interrupt, 'dev_id'
4405 * is not referenced. 'dev_id' could be used to identify an interrupt passed
4406 * to the AdvanSys driver which is for a device sharing an interrupt with
4407 * an AdvanSys adapter.
4409 static irqreturn_t advansys_interrupt(int irq, void *dev_id)
4411 unsigned long flags;
4412 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4413 struct scsi_cmnd *new_last_scp;
4414 struct Scsi_Host *shost = dev_id;
4415 asc_board_t *boardp = ASC_BOARDP(shost);
4416 irqreturn_t result = IRQ_NONE;
4418 ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp);
4419 spin_lock_irqsave(&boardp->lock, flags);
4420 if (ASC_NARROW_BOARD(boardp)) {
4422 * Narrow Board
4424 if (AscIsIntPending(shost->io_port)) {
4425 result = IRQ_HANDLED;
4426 ASC_STATS(shost, interrupt);
4427 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
4428 AscISR(&boardp->dvc_var.asc_dvc_var);
4430 } else {
4432 * Wide Board
4434 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
4435 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
4436 result = IRQ_HANDLED;
4437 ASC_STATS(shost, interrupt);
4442 * Start waiting requests and create a list of completed requests.
4444 * If a reset request is being performed for the board, the reset
4445 * handler will complete pending requests after it has completed.
4447 if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
4448 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%p, "
4449 "last_scp 0x%p\n", done_scp, last_scp);
4451 /* Start any waiting commands for the board. */
4452 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4453 ASC_DBG(1, "advansys_interrupt: before "
4454 "asc_execute_queue()\n");
4455 asc_execute_queue(&boardp->waiting);
4459 * Add to the list of requests that must be completed.
4461 * 'done_scp' will always be NULL on the first iteration of
4462 * this loop. 'last_scp' is set at the same time as 'done_scp'.
4464 if (done_scp == NULL) {
4465 done_scp = asc_dequeue_list(&boardp->done,
4466 &last_scp, ASC_TID_ALL);
4467 } else {
4468 ASC_ASSERT(last_scp != NULL);
4469 last_scp->host_scribble =
4470 (unsigned char *)asc_dequeue_list(&boardp->
4471 done,
4472 &new_last_scp,
4473 ASC_TID_ALL);
4474 if (new_last_scp != NULL) {
4475 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4476 last_scp = new_last_scp;
4480 spin_unlock_irqrestore(&boardp->lock, flags);
4483 * If interrupts were enabled on entry, then they
4484 * are now enabled here.
4486 * Complete all requests on the done list.
4489 asc_scsi_done_list(done_scp);
4491 ASC_DBG(1, "advansys_interrupt: end\n");
4492 return result;
4495 static void
4496 advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
4498 ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
4499 ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
4501 if (sdev->lun == 0) {
4502 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
4503 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
4504 asc_dvc->init_sdtr |= tid_bit;
4505 } else {
4506 asc_dvc->init_sdtr &= ~tid_bit;
4509 if (orig_init_sdtr != asc_dvc->init_sdtr)
4510 AscAsyncFix(asc_dvc, sdev);
4513 if (sdev->tagged_supported) {
4514 if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
4515 if (sdev->lun == 0) {
4516 asc_dvc->cfg->can_tagged_qng |= tid_bit;
4517 asc_dvc->use_tagged_qng |= tid_bit;
4519 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
4520 asc_dvc->max_dvc_qng[sdev->id]);
4522 } else {
4523 if (sdev->lun == 0) {
4524 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
4525 asc_dvc->use_tagged_qng &= ~tid_bit;
4527 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
4530 if ((sdev->lun == 0) &&
4531 (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
4532 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
4533 asc_dvc->cfg->disc_enable);
4534 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
4535 asc_dvc->use_tagged_qng);
4536 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
4537 asc_dvc->cfg->can_tagged_qng);
4539 asc_dvc->max_dvc_qng[sdev->id] =
4540 asc_dvc->cfg->max_tag_qng[sdev->id];
4541 AscWriteLramByte(asc_dvc->iop_base,
4542 (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
4543 asc_dvc->max_dvc_qng[sdev->id]);
4548 * Wide Transfers
4550 * If the EEPROM enabled WDTR for the device and the device supports wide
4551 * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and
4552 * write the new value to the microcode.
4554 static void
4555 advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
4557 unsigned short cfg_word;
4558 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
4559 if ((cfg_word & tidmask) != 0)
4560 return;
4562 cfg_word |= tidmask;
4563 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
4566 * Clear the microcode SDTR and WDTR negotiation done indicators for
4567 * the target to cause it to negotiate with the new setting set above.
4568 * WDTR when accepted causes the target to enter asynchronous mode, so
4569 * SDTR must be negotiated.
4571 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
4572 cfg_word &= ~tidmask;
4573 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
4574 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
4575 cfg_word &= ~tidmask;
4576 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
4580 * Synchronous Transfers
4582 * If the EEPROM enabled SDTR for the device and the device
4583 * supports synchronous transfers, then turn on the device's
4584 * 'sdtr_able' bit. Write the new value to the microcode.
4586 static void
4587 advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
4589 unsigned short cfg_word;
4590 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
4591 if ((cfg_word & tidmask) != 0)
4592 return;
4594 cfg_word |= tidmask;
4595 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
4598 * Clear the microcode "SDTR negotiation" done indicator for the
4599 * target to cause it to negotiate with the new setting set above.
4601 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
4602 cfg_word &= ~tidmask;
4603 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
4607 * PPR (Parallel Protocol Request) Capable
4609 * If the device supports DT mode, then it must be PPR capable.
4610 * The PPR message will be used in place of the SDTR and WDTR
4611 * messages to negotiate synchronous speed and offset, transfer
4612 * width, and protocol options.
4614 static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
4615 AdvPortAddr iop_base, unsigned short tidmask)
4617 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
4618 adv_dvc->ppr_able |= tidmask;
4619 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
4622 static void
4623 advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
4625 AdvPortAddr iop_base = adv_dvc->iop_base;
4626 unsigned short tidmask = 1 << sdev->id;
4628 if (sdev->lun == 0) {
4630 * Handle WDTR, SDTR, and Tag Queuing. If the feature
4631 * is enabled in the EEPROM and the device supports the
4632 * feature, then enable it in the microcode.
4635 if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
4636 advansys_wide_enable_wdtr(iop_base, tidmask);
4637 if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
4638 advansys_wide_enable_sdtr(iop_base, tidmask);
4639 if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
4640 advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
4643 * Tag Queuing is disabled for the BIOS which runs in polled
4644 * mode and would see no benefit from Tag Queuing. Also by
4645 * disabling Tag Queuing in the BIOS devices with Tag Queuing
4646 * bugs will at least work with the BIOS.
4648 if ((adv_dvc->tagqng_able & tidmask) &&
4649 sdev->tagged_supported) {
4650 unsigned short cfg_word;
4651 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
4652 cfg_word |= tidmask;
4653 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
4654 cfg_word);
4655 AdvWriteByteLram(iop_base,
4656 ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
4657 adv_dvc->max_dvc_qng);
4661 if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) {
4662 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
4663 adv_dvc->max_dvc_qng);
4664 } else {
4665 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
4670 * Set the number of commands to queue per device for the
4671 * specified host adapter.
4673 static int advansys_slave_configure(struct scsi_device *sdev)
4675 asc_board_t *boardp = ASC_BOARDP(sdev->host);
4676 boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
4679 * Save a pointer to the sdev and set its initial/maximum
4680 * queue depth. Only save the pointer for a lun0 dev though.
4682 if (sdev->lun == 0)
4683 boardp->device[sdev->id] = sdev;
4685 if (ASC_NARROW_BOARD(boardp))
4686 advansys_narrow_slave_configure(sdev,
4687 &boardp->dvc_var.asc_dvc_var);
4688 else
4689 advansys_wide_slave_configure(sdev,
4690 &boardp->dvc_var.adv_dvc_var);
4692 return 0;
4696 * Complete all requests on the singly linked list pointed
4697 * to by 'scp'.
4699 * Interrupts can be enabled on entry.
4701 static void asc_scsi_done_list(struct scsi_cmnd *scp)
4703 struct scsi_cmnd *tscp;
4705 ASC_DBG(2, "asc_scsi_done_list: begin\n");
4706 while (scp != NULL) {
4707 asc_board_t *boardp;
4708 struct device *dev;
4710 ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp);
4711 tscp = REQPNEXT(scp);
4712 scp->host_scribble = NULL;
4714 boardp = ASC_BOARDP(scp->device->host);
4716 if (ASC_NARROW_BOARD(boardp))
4717 dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
4718 else
4719 dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
4721 if (scp->use_sg)
4722 dma_unmap_sg(dev,
4723 (struct scatterlist *)scp->request_buffer,
4724 scp->use_sg, scp->sc_data_direction);
4725 else if (scp->request_bufflen)
4726 dma_unmap_single(dev, scp->SCp.dma_handle,
4727 scp->request_bufflen,
4728 scp->sc_data_direction);
4730 ASC_STATS(scp->device->host, done);
4731 ASC_ASSERT(scp->scsi_done != NULL);
4733 scp->scsi_done(scp);
4735 scp = tscp;
4737 ASC_DBG(2, "asc_scsi_done_list: done\n");
4738 return;
4742 * Execute a single 'Scsi_Cmnd'.
4744 * The function 'done' is called when the request has been completed.
4746 * Scsi_Cmnd:
4748 * host - board controlling device
4749 * device - device to send command
4750 * target - target of device
4751 * lun - lun of device
4752 * cmd_len - length of SCSI CDB
4753 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
4754 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
4756 * if (use_sg == 0) {
4757 * request_buffer - buffer address for request
4758 * request_bufflen - length of request buffer
4759 * } else {
4760 * request_buffer - pointer to scatterlist structure
4763 * sense_buffer - sense command buffer
4765 * result (4 bytes of an int):
4766 * Byte Meaning
4767 * 0 SCSI Status Byte Code
4768 * 1 SCSI One Byte Message Code
4769 * 2 Host Error Code
4770 * 3 Mid-Level Error Code
4772 * host driver fields:
4773 * SCp - Scsi_Pointer used for command processing status
4774 * scsi_done - used to save caller's done function
4775 * host_scribble - used for pointer to another struct scsi_cmnd
4777 * If this function returns ASC_NOERROR the request has been enqueued
4778 * on the board's 'active' queue and will be completed from the
4779 * interrupt handler.
4781 * If this function returns ASC_NOERROR the request has been enqueued
4782 * on the board's 'done' queue and must be completed by the caller.
4784 * If ASC_BUSY is returned the request will be enqueued by the
4785 * caller on the target's waiting queue and re-tried later.
4787 static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
4789 asc_board_t *boardp;
4790 ASC_DVC_VAR *asc_dvc_varp;
4791 ADV_DVC_VAR *adv_dvc_varp;
4792 ADV_SCSI_REQ_Q *adv_scsiqp;
4793 struct scsi_device *device;
4794 int ret;
4796 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
4797 (ulong)scp, (ulong)scp->scsi_done);
4799 boardp = ASC_BOARDP(scp->device->host);
4800 device = boardp->device[scp->device->id];
4802 if (ASC_NARROW_BOARD(boardp)) {
4804 * Build and execute Narrow Board request.
4807 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4810 * Build Asc Library request structure using the
4811 * global structures 'asc_scsi_req' and 'asc_sg_head'.
4813 * If an error is returned, then the request has been
4814 * queued on the board done queue. It will be completed
4815 * by the caller.
4817 * asc_build_req() can not return ASC_BUSY.
4819 if (asc_build_req(boardp, scp) == ASC_ERROR) {
4820 ASC_STATS(scp->device->host, build_error);
4821 return ASC_ERROR;
4825 * Execute the command. If there is no error, add the command
4826 * to the active queue.
4828 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
4829 case ASC_NOERROR:
4830 ASC_STATS(scp->device->host, exe_noerror);
4832 * Increment monotonically increasing per device successful
4833 * request counter. Wrapping doesn't matter.
4835 boardp->reqcnt[scp->device->id]++;
4836 asc_enqueue(&boardp->active, scp, ASC_BACK);
4837 ASC_DBG(1,
4838 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
4839 break;
4840 case ASC_BUSY:
4842 * Caller will enqueue request on the target's waiting queue
4843 * and retry later.
4845 ASC_STATS(scp->device->host, exe_busy);
4846 break;
4847 case ASC_ERROR:
4848 ASC_PRINT2
4849 ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4850 boardp->id, asc_dvc_varp->err_code);
4851 ASC_STATS(scp->device->host, exe_error);
4852 scp->result = HOST_BYTE(DID_ERROR);
4853 asc_enqueue(&boardp->done, scp, ASC_BACK);
4854 break;
4855 default:
4856 ASC_PRINT2
4857 ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
4858 boardp->id, asc_dvc_varp->err_code);
4859 ASC_STATS(scp->device->host, exe_unknown);
4860 scp->result = HOST_BYTE(DID_ERROR);
4861 asc_enqueue(&boardp->done, scp, ASC_BACK);
4862 break;
4864 } else {
4866 * Build and execute Wide Board request.
4868 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4871 * Build and get a pointer to an Adv Library request structure.
4873 * If the request is successfully built then send it below,
4874 * otherwise return with an error.
4876 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
4877 case ASC_NOERROR:
4878 ASC_DBG(3,
4879 "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
4880 break;
4881 case ASC_BUSY:
4882 ASC_DBG(1,
4883 "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
4885 * If busy is returned the request has not been enqueued.
4886 * It will be enqueued by the caller on the target's waiting
4887 * queue and retried later.
4889 * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg'
4890 * count wide board busy conditions. They are updated in
4891 * adv_build_req and adv_get_sglist, respectively.
4893 return ASC_BUSY;
4894 case ASC_ERROR:
4896 * If an error is returned, then the request has been
4897 * queued on the board done queue. It will be completed
4898 * by the caller.
4900 default:
4901 ASC_DBG(1,
4902 "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
4903 ASC_STATS(scp->device->host, build_error);
4904 return ASC_ERROR;
4908 * Execute the command. If there is no error, add the command
4909 * to the active queue.
4911 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
4912 case ASC_NOERROR:
4913 ASC_STATS(scp->device->host, exe_noerror);
4915 * Increment monotonically increasing per device successful
4916 * request counter. Wrapping doesn't matter.
4918 boardp->reqcnt[scp->device->id]++;
4919 asc_enqueue(&boardp->active, scp, ASC_BACK);
4920 ASC_DBG(1,
4921 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
4922 break;
4923 case ASC_BUSY:
4925 * Caller will enqueue request on the target's waiting queue
4926 * and retry later.
4928 ASC_STATS(scp->device->host, exe_busy);
4929 break;
4930 case ASC_ERROR:
4931 ASC_PRINT2
4932 ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4933 boardp->id, adv_dvc_varp->err_code);
4934 ASC_STATS(scp->device->host, exe_error);
4935 scp->result = HOST_BYTE(DID_ERROR);
4936 asc_enqueue(&boardp->done, scp, ASC_BACK);
4937 break;
4938 default:
4939 ASC_PRINT2
4940 ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
4941 boardp->id, adv_dvc_varp->err_code);
4942 ASC_STATS(scp->device->host, exe_unknown);
4943 scp->result = HOST_BYTE(DID_ERROR);
4944 asc_enqueue(&boardp->done, scp, ASC_BACK);
4945 break;
4949 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
4950 return ret;
4954 * Build a request structure for the Asc Library (Narrow Board).
4956 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
4957 * used to build the request.
4959 * If an error occurs, then queue the request on the board done
4960 * queue and return ASC_ERROR.
4962 static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
4964 struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
4967 * Mutually exclusive access is required to 'asc_scsi_q' and
4968 * 'asc_sg_head' until after the request is started.
4970 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
4973 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
4975 asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
4978 * Build the ASC_SCSI_Q request.
4980 * For narrow boards a CDB length maximum of 12 bytes
4981 * is supported.
4983 if (scp->cmd_len > ASC_MAX_CDB_LEN) {
4984 ASC_PRINT3
4985 ("asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN %d\n",
4986 boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN);
4987 scp->result = HOST_BYTE(DID_ERROR);
4988 asc_enqueue(&boardp->done, scp, ASC_BACK);
4989 return ASC_ERROR;
4991 asc_scsi_q.cdbptr = &scp->cmnd[0];
4992 asc_scsi_q.q2.cdb_len = scp->cmd_len;
4993 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
4994 asc_scsi_q.q1.target_lun = scp->device->lun;
4995 asc_scsi_q.q2.target_ix =
4996 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
4997 asc_scsi_q.q1.sense_addr =
4998 cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
4999 asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
5002 * If there are any outstanding requests for the current target,
5003 * then every 255th request send an ORDERED request. This heuristic
5004 * tries to retain the benefit of request sorting while preventing
5005 * request starvation. 255 is the max number of tags or pending commands
5006 * a device may have outstanding.
5008 * The request count is incremented below for every successfully
5009 * started request.
5012 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
5013 (boardp->reqcnt[scp->device->id] % 255) == 0) {
5014 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
5015 } else {
5016 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
5020 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
5021 * buffer command.
5023 if (scp->use_sg == 0) {
5025 * CDB request of single contiguous buffer.
5027 ASC_STATS(scp->device->host, cont_cnt);
5028 scp->SCp.dma_handle = scp->request_bufflen ?
5029 dma_map_single(dev, scp->request_buffer,
5030 scp->request_bufflen,
5031 scp->sc_data_direction) : 0;
5032 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
5033 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
5034 ASC_STATS_ADD(scp->device->host, cont_xfer,
5035 ASC_CEILING(scp->request_bufflen, 512));
5036 asc_scsi_q.q1.sg_queue_cnt = 0;
5037 asc_scsi_q.sg_head = NULL;
5038 } else {
5040 * CDB scatter-gather request list.
5042 int sgcnt;
5043 int use_sg;
5044 struct scatterlist *slp;
5046 slp = (struct scatterlist *)scp->request_buffer;
5047 use_sg =
5048 dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
5050 if (use_sg > scp->device->host->sg_tablesize) {
5051 ASC_PRINT3
5052 ("asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
5053 boardp->id, use_sg,
5054 scp->device->host->sg_tablesize);
5055 dma_unmap_sg(dev, slp, scp->use_sg,
5056 scp->sc_data_direction);
5057 scp->result = HOST_BYTE(DID_ERROR);
5058 asc_enqueue(&boardp->done, scp, ASC_BACK);
5059 return ASC_ERROR;
5062 ASC_STATS(scp->device->host, sg_cnt);
5065 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
5066 * structure to point to it.
5068 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
5070 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
5071 asc_scsi_q.sg_head = &asc_sg_head;
5072 asc_scsi_q.q1.data_cnt = 0;
5073 asc_scsi_q.q1.data_addr = 0;
5074 /* This is a byte value, otherwise it would need to be swapped. */
5075 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
5076 ASC_STATS_ADD(scp->device->host, sg_elem,
5077 asc_sg_head.entry_cnt);
5080 * Convert scatter-gather list into ASC_SG_HEAD list.
5082 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
5083 asc_sg_head.sg_list[sgcnt].addr =
5084 cpu_to_le32(sg_dma_address(slp));
5085 asc_sg_head.sg_list[sgcnt].bytes =
5086 cpu_to_le32(sg_dma_len(slp));
5087 ASC_STATS_ADD(scp->device->host, sg_xfer,
5088 ASC_CEILING(sg_dma_len(slp), 512));
5092 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
5093 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
5095 return ASC_NOERROR;
5099 * Build a request structure for the Adv Library (Wide Board).
5101 * If an adv_req_t can not be allocated to issue the request,
5102 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
5104 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
5105 * microcode for DMA addresses or math operations are byte swapped
5106 * to little-endian order.
5108 static int
5109 adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
5110 ADV_SCSI_REQ_Q **adv_scsiqpp)
5112 adv_req_t *reqp;
5113 ADV_SCSI_REQ_Q *scsiqp;
5114 int i;
5115 int ret;
5116 struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
5119 * Allocate an adv_req_t structure from the board to execute
5120 * the command.
5122 if (boardp->adv_reqp == NULL) {
5123 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
5124 ASC_STATS(scp->device->host, adv_build_noreq);
5125 return ASC_BUSY;
5126 } else {
5127 reqp = boardp->adv_reqp;
5128 boardp->adv_reqp = reqp->next_reqp;
5129 reqp->next_reqp = NULL;
5133 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
5135 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5138 * Initialize the structure.
5140 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
5143 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
5145 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
5148 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
5150 reqp->cmndp = scp;
5153 * Build the ADV_SCSI_REQ_Q request.
5157 * Set CDB length and copy it to the request structure.
5158 * For wide boards a CDB length maximum of 16 bytes
5159 * is supported.
5161 if (scp->cmd_len > ADV_MAX_CDB_LEN) {
5162 ASC_PRINT3
5163 ("adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n",
5164 boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
5165 scp->result = HOST_BYTE(DID_ERROR);
5166 asc_enqueue(&boardp->done, scp, ASC_BACK);
5167 return ASC_ERROR;
5169 scsiqp->cdb_len = scp->cmd_len;
5170 /* Copy first 12 CDB bytes to cdb[]. */
5171 for (i = 0; i < scp->cmd_len && i < 12; i++) {
5172 scsiqp->cdb[i] = scp->cmnd[i];
5174 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
5175 for (; i < scp->cmd_len; i++) {
5176 scsiqp->cdb16[i - 12] = scp->cmnd[i];
5179 scsiqp->target_id = scp->device->id;
5180 scsiqp->target_lun = scp->device->lun;
5182 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
5183 scsiqp->sense_len = sizeof(scp->sense_buffer);
5186 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
5187 * buffer command.
5190 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
5191 scsiqp->vdata_addr = scp->request_buffer;
5192 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
5194 if (scp->use_sg == 0) {
5196 * CDB request of single contiguous buffer.
5198 reqp->sgblkp = NULL;
5199 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
5200 if (scp->request_bufflen) {
5201 scsiqp->vdata_addr = scp->request_buffer;
5202 scp->SCp.dma_handle =
5203 dma_map_single(dev, scp->request_buffer,
5204 scp->request_bufflen,
5205 scp->sc_data_direction);
5206 } else {
5207 scsiqp->vdata_addr = NULL;
5208 scp->SCp.dma_handle = 0;
5210 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
5211 scsiqp->sg_list_ptr = NULL;
5212 scsiqp->sg_real_addr = 0;
5213 ASC_STATS(scp->device->host, cont_cnt);
5214 ASC_STATS_ADD(scp->device->host, cont_xfer,
5215 ASC_CEILING(scp->request_bufflen, 512));
5216 } else {
5218 * CDB scatter-gather request list.
5220 struct scatterlist *slp;
5221 int use_sg;
5223 slp = (struct scatterlist *)scp->request_buffer;
5224 use_sg =
5225 dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
5227 if (use_sg > ADV_MAX_SG_LIST) {
5228 ASC_PRINT3
5229 ("adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
5230 boardp->id, use_sg,
5231 scp->device->host->sg_tablesize);
5232 dma_unmap_sg(dev, slp, scp->use_sg,
5233 scp->sc_data_direction);
5234 scp->result = HOST_BYTE(DID_ERROR);
5235 asc_enqueue(&boardp->done, scp, ASC_BACK);
5238 * Free the 'adv_req_t' structure by adding it back to the
5239 * board free list.
5241 reqp->next_reqp = boardp->adv_reqp;
5242 boardp->adv_reqp = reqp;
5244 return ASC_ERROR;
5247 if ((ret =
5248 adv_get_sglist(boardp, reqp, scp,
5249 use_sg)) != ADV_SUCCESS) {
5251 * Free the adv_req_t structure by adding it back to the
5252 * board free list.
5254 reqp->next_reqp = boardp->adv_reqp;
5255 boardp->adv_reqp = reqp;
5257 return ret;
5260 ASC_STATS(scp->device->host, sg_cnt);
5261 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
5264 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5265 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
5267 *adv_scsiqpp = scsiqp;
5269 return ASC_NOERROR;
5273 * Build scatter-gather list for Adv Library (Wide Board).
5275 * Additional ADV_SG_BLOCK structures will need to be allocated
5276 * if the total number of scatter-gather elements exceeds
5277 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
5278 * assumed to be physically contiguous.
5280 * Return:
5281 * ADV_SUCCESS(1) - SG List successfully created
5282 * ADV_ERROR(-1) - SG List creation failed
5284 static int
5285 adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
5286 int use_sg)
5288 adv_sgblk_t *sgblkp;
5289 ADV_SCSI_REQ_Q *scsiqp;
5290 struct scatterlist *slp;
5291 int sg_elem_cnt;
5292 ADV_SG_BLOCK *sg_block, *prev_sg_block;
5293 ADV_PADDR sg_block_paddr;
5294 int i;
5296 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5297 slp = (struct scatterlist *)scp->request_buffer;
5298 sg_elem_cnt = use_sg;
5299 prev_sg_block = NULL;
5300 reqp->sgblkp = NULL;
5302 do {
5304 * Allocate a 'adv_sgblk_t' structure from the board free
5305 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
5306 * (15) scatter-gather elements.
5308 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
5309 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
5310 ASC_STATS(scp->device->host, adv_build_nosg);
5313 * Allocation failed. Free 'adv_sgblk_t' structures already
5314 * allocated for the request.
5316 while ((sgblkp = reqp->sgblkp) != NULL) {
5317 /* Remove 'sgblkp' from the request list. */
5318 reqp->sgblkp = sgblkp->next_sgblkp;
5320 /* Add 'sgblkp' to the board free list. */
5321 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5322 boardp->adv_sgblkp = sgblkp;
5324 return ASC_BUSY;
5325 } else {
5326 /* Complete 'adv_sgblk_t' board allocation. */
5327 boardp->adv_sgblkp = sgblkp->next_sgblkp;
5328 sgblkp->next_sgblkp = NULL;
5331 * Get 8 byte aligned virtual and physical addresses for
5332 * the allocated ADV_SG_BLOCK structure.
5334 sg_block =
5335 (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
5336 sg_block_paddr = virt_to_bus(sg_block);
5339 * Check if this is the first 'adv_sgblk_t' for the request.
5341 if (reqp->sgblkp == NULL) {
5342 /* Request's first scatter-gather block. */
5343 reqp->sgblkp = sgblkp;
5346 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
5347 * address pointers.
5349 scsiqp->sg_list_ptr = sg_block;
5350 scsiqp->sg_real_addr =
5351 cpu_to_le32(sg_block_paddr);
5352 } else {
5353 /* Request's second or later scatter-gather block. */
5354 sgblkp->next_sgblkp = reqp->sgblkp;
5355 reqp->sgblkp = sgblkp;
5358 * Point the previous ADV_SG_BLOCK structure to
5359 * the newly allocated ADV_SG_BLOCK structure.
5361 ASC_ASSERT(prev_sg_block != NULL);
5362 prev_sg_block->sg_ptr =
5363 cpu_to_le32(sg_block_paddr);
5367 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
5368 sg_block->sg_list[i].sg_addr =
5369 cpu_to_le32(sg_dma_address(slp));
5370 sg_block->sg_list[i].sg_count =
5371 cpu_to_le32(sg_dma_len(slp));
5372 ASC_STATS_ADD(scp->device->host, sg_xfer,
5373 ASC_CEILING(sg_dma_len(slp), 512));
5375 if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */
5376 sg_block->sg_cnt = i + 1;
5377 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
5378 return ADV_SUCCESS;
5380 slp++;
5382 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
5383 prev_sg_block = sg_block;
5385 while (1);
5386 /* NOTREACHED */
5390 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
5392 * Interrupt callback function for the Narrow SCSI Asc Library.
5394 static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
5396 asc_board_t *boardp;
5397 struct scsi_cmnd *scp;
5398 struct Scsi_Host *shost;
5400 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
5401 (ulong)asc_dvc_varp, (ulong)qdonep);
5402 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
5405 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5406 * command that has been completed.
5408 scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
5409 ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp);
5411 if (scp == NULL) {
5412 ASC_PRINT("asc_isr_callback: scp is NULL\n");
5413 return;
5415 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5417 shost = scp->device->host;
5418 ASC_STATS(shost, callback);
5419 ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
5422 * If the request isn't found on the active queue, it may
5423 * have been removed to handle a reset request.
5424 * Display a message and return.
5426 boardp = ASC_BOARDP(shost);
5427 ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
5428 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5429 ASC_PRINT2
5430 ("asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
5431 boardp->id, (ulong)scp);
5432 return;
5436 * 'qdonep' contains the command's ending status.
5438 switch (qdonep->d3.done_stat) {
5439 case QD_NO_ERROR:
5440 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
5441 scp->result = 0;
5444 * Check for an underrun condition.
5446 * If there was no error and an underrun condition, then
5447 * return the number of underrun bytes.
5449 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
5450 qdonep->remain_bytes <= scp->request_bufflen) {
5451 ASC_DBG1(1,
5452 "asc_isr_callback: underrun condition %u bytes\n",
5453 (unsigned)qdonep->remain_bytes);
5454 scp->resid = qdonep->remain_bytes;
5456 break;
5458 case QD_WITH_ERROR:
5459 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
5460 switch (qdonep->d3.host_stat) {
5461 case QHSTA_NO_ERROR:
5462 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
5463 ASC_DBG(2,
5464 "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5465 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5466 sizeof(scp->sense_buffer));
5468 * Note: The 'status_byte()' macro used by target drivers
5469 * defined in scsi.h shifts the status byte returned by
5470 * host drivers right by 1 bit. This is why target drivers
5471 * also use right shifted status byte definitions. For
5472 * instance target drivers use CHECK_CONDITION, defined to
5473 * 0x1, instead of the SCSI defined check condition value
5474 * of 0x2. Host drivers are supposed to return the status
5475 * byte as it is defined by SCSI.
5477 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5478 STATUS_BYTE(qdonep->d3.scsi_stat);
5479 } else {
5480 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
5482 break;
5484 default:
5485 /* QHSTA error occurred */
5486 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
5487 qdonep->d3.host_stat);
5488 scp->result = HOST_BYTE(DID_BAD_TARGET);
5489 break;
5491 break;
5493 case QD_ABORTED_BY_HOST:
5494 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
5495 scp->result =
5496 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
5497 scsi_msg) |
5498 STATUS_BYTE(qdonep->d3.scsi_stat);
5499 break;
5501 default:
5502 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n",
5503 qdonep->d3.done_stat);
5504 scp->result =
5505 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
5506 scsi_msg) |
5507 STATUS_BYTE(qdonep->d3.scsi_stat);
5508 break;
5512 * If the 'init_tidmask' bit isn't already set for the target and the
5513 * current request finished normally, then set the bit for the target
5514 * to indicate that a device is present.
5516 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5517 qdonep->d3.done_stat == QD_NO_ERROR &&
5518 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
5519 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5523 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5524 * function, add the command to the end of the board's done queue.
5525 * The done function for the command will be called from
5526 * advansys_interrupt().
5528 asc_enqueue(&boardp->done, scp, ASC_BACK);
5530 return;
5534 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
5536 * Callback function for the Wide SCSI Adv Library.
5538 static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
5540 asc_board_t *boardp;
5541 adv_req_t *reqp;
5542 adv_sgblk_t *sgblkp;
5543 struct scsi_cmnd *scp;
5544 struct Scsi_Host *shost;
5545 ADV_DCNT resid_cnt;
5547 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
5548 (ulong)adv_dvc_varp, (ulong)scsiqp);
5549 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5552 * Get the adv_req_t structure for the command that has been
5553 * completed. The adv_req_t structure actually contains the
5554 * completed ADV_SCSI_REQ_Q structure.
5556 reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
5557 ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp);
5558 if (reqp == NULL) {
5559 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
5560 return;
5564 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5565 * command that has been completed.
5567 * Note: The adv_req_t request structure and adv_sgblk_t structure,
5568 * if any, are dropped, because a board structure pointer can not be
5569 * determined.
5571 scp = reqp->cmndp;
5572 ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp);
5573 if (scp == NULL) {
5574 ASC_PRINT
5575 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
5576 return;
5578 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5580 shost = scp->device->host;
5581 ASC_STATS(shost, callback);
5582 ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
5585 * If the request isn't found on the active queue, it may have been
5586 * removed to handle a reset request. Display a message and return.
5588 * Note: Because the structure may still be in use don't attempt
5589 * to free the adv_req_t and adv_sgblk_t, if any, structures.
5591 boardp = ASC_BOARDP(shost);
5592 ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
5593 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5594 ASC_PRINT2
5595 ("adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
5596 boardp->id, (ulong)scp);
5597 return;
5601 * 'done_status' contains the command's ending status.
5603 switch (scsiqp->done_status) {
5604 case QD_NO_ERROR:
5605 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
5606 scp->result = 0;
5609 * Check for an underrun condition.
5611 * If there was no error and an underrun condition, then
5612 * then return the number of underrun bytes.
5614 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
5615 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
5616 resid_cnt <= scp->request_bufflen) {
5617 ASC_DBG1(1,
5618 "adv_isr_callback: underrun condition %lu bytes\n",
5619 (ulong)resid_cnt);
5620 scp->resid = resid_cnt;
5622 break;
5624 case QD_WITH_ERROR:
5625 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
5626 switch (scsiqp->host_status) {
5627 case QHSTA_NO_ERROR:
5628 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
5629 ASC_DBG(2,
5630 "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5631 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5632 sizeof(scp->sense_buffer));
5634 * Note: The 'status_byte()' macro used by target drivers
5635 * defined in scsi.h shifts the status byte returned by
5636 * host drivers right by 1 bit. This is why target drivers
5637 * also use right shifted status byte definitions. For
5638 * instance target drivers use CHECK_CONDITION, defined to
5639 * 0x1, instead of the SCSI defined check condition value
5640 * of 0x2. Host drivers are supposed to return the status
5641 * byte as it is defined by SCSI.
5643 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5644 STATUS_BYTE(scsiqp->scsi_status);
5645 } else {
5646 scp->result = STATUS_BYTE(scsiqp->scsi_status);
5648 break;
5650 default:
5651 /* Some other QHSTA error occurred. */
5652 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
5653 scsiqp->host_status);
5654 scp->result = HOST_BYTE(DID_BAD_TARGET);
5655 break;
5657 break;
5659 case QD_ABORTED_BY_HOST:
5660 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
5661 scp->result =
5662 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
5663 break;
5665 default:
5666 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n",
5667 scsiqp->done_status);
5668 scp->result =
5669 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
5670 break;
5674 * If the 'init_tidmask' bit isn't already set for the target and the
5675 * current request finished normally, then set the bit for the target
5676 * to indicate that a device is present.
5678 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5679 scsiqp->done_status == QD_NO_ERROR &&
5680 scsiqp->host_status == QHSTA_NO_ERROR) {
5681 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5685 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5686 * function, add the command to the end of the board's done queue.
5687 * The done function for the command will be called from
5688 * advansys_interrupt().
5690 asc_enqueue(&boardp->done, scp, ASC_BACK);
5693 * Free all 'adv_sgblk_t' structures allocated for the request.
5695 while ((sgblkp = reqp->sgblkp) != NULL) {
5696 /* Remove 'sgblkp' from the request list. */
5697 reqp->sgblkp = sgblkp->next_sgblkp;
5699 /* Add 'sgblkp' to the board free list. */
5700 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5701 boardp->adv_sgblkp = sgblkp;
5705 * Free the adv_req_t structure used with the command by adding
5706 * it back to the board free list.
5708 reqp->next_reqp = boardp->adv_reqp;
5709 boardp->adv_reqp = reqp;
5711 ASC_DBG(1, "adv_isr_callback: done\n");
5713 return;
5717 * adv_async_callback() - Adv Library asynchronous event callback function.
5719 static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
5721 switch (code) {
5722 case ADV_ASYNC_SCSI_BUS_RESET_DET:
5724 * The firmware detected a SCSI Bus reset.
5726 ASC_DBG(0,
5727 "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
5728 break;
5730 case ADV_ASYNC_RDMA_FAILURE:
5732 * Handle RDMA failure by resetting the SCSI Bus and
5733 * possibly the chip if it is unresponsive. Log the error
5734 * with a unique code.
5736 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
5737 AdvResetChipAndSB(adv_dvc_varp);
5738 break;
5740 case ADV_HOST_SCSI_BUS_RESET:
5742 * Host generated SCSI bus reset occurred.
5744 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
5745 break;
5747 default:
5748 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
5749 break;
5754 * Add a 'REQP' to the end of specified queue. Set 'tidmask'
5755 * to indicate a command is queued for the device.
5757 * 'flag' may be either ASC_FRONT or ASC_BACK.
5759 * 'REQPNEXT(reqp)' returns reqp's next pointer.
5761 static void asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
5763 int tid;
5765 ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
5766 (ulong)ascq, (ulong)reqp, flag);
5767 ASC_ASSERT(reqp != NULL);
5768 ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
5769 tid = REQPTID(reqp);
5770 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5771 if (flag == ASC_FRONT) {
5772 reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
5773 ascq->q_first[tid] = reqp;
5774 /* If the queue was empty, set the last pointer. */
5775 if (ascq->q_last[tid] == NULL) {
5776 ascq->q_last[tid] = reqp;
5778 } else { /* ASC_BACK */
5779 if (ascq->q_last[tid] != NULL) {
5780 ascq->q_last[tid]->host_scribble =
5781 (unsigned char *)reqp;
5783 ascq->q_last[tid] = reqp;
5784 reqp->host_scribble = NULL;
5785 /* If the queue was empty, set the first pointer. */
5786 if (ascq->q_first[tid] == NULL) {
5787 ascq->q_first[tid] = reqp;
5790 /* The queue has at least one entry, set its bit. */
5791 ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
5792 #ifdef ADVANSYS_STATS
5793 /* Maintain request queue statistics. */
5794 ascq->q_tot_cnt[tid]++;
5795 ascq->q_cur_cnt[tid]++;
5796 if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
5797 ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
5798 ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
5799 tid, ascq->q_max_cnt[tid]);
5801 REQPTIME(reqp) = REQTIMESTAMP();
5802 #endif /* ADVANSYS_STATS */
5803 ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong)reqp);
5804 return;
5808 * Return first queued 'REQP' on the specified queue for
5809 * the specified target device. Clear the 'tidmask' bit for
5810 * the device if no more commands are left queued for it.
5812 * 'REQPNEXT(reqp)' returns reqp's next pointer.
5814 static REQP asc_dequeue(asc_queue_t *ascq, int tid)
5816 REQP reqp;
5818 ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5819 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5820 if ((reqp = ascq->q_first[tid]) != NULL) {
5821 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
5822 ascq->q_first[tid] = REQPNEXT(reqp);
5823 /* If the queue is empty, clear its bit and the last pointer. */
5824 if (ascq->q_first[tid] == NULL) {
5825 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5826 ASC_ASSERT(ascq->q_last[tid] == reqp);
5827 ascq->q_last[tid] = NULL;
5829 #ifdef ADVANSYS_STATS
5830 /* Maintain request queue statistics. */
5831 ascq->q_cur_cnt[tid]--;
5832 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
5833 REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
5834 #endif /* ADVANSYS_STATS */
5836 ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong)reqp);
5837 return reqp;
5841 * Return a pointer to a singly linked list of all the requests queued
5842 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
5844 * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
5845 * the last request returned in the singly linked list.
5847 * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
5848 * then all queued requests are concatenated into one list and
5849 * returned.
5851 * Note: If 'lastpp' is used to append a new list to the end of
5852 * an old list, only change the old list last pointer if '*lastpp'
5853 * (or the function return value) is not NULL, i.e. use a temporary
5854 * variable for 'lastpp' and check its value after the function return
5855 * before assigning it to the list last pointer.
5857 * Unfortunately collecting queuing time statistics adds overhead to
5858 * the function that isn't inherent to the function's algorithm.
5860 static REQP asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
5862 REQP firstp, lastp;
5863 int i;
5865 ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5866 ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
5869 * If 'tid' is not ASC_TID_ALL, return requests only for
5870 * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
5871 * requests for all tids.
5873 if (tid != ASC_TID_ALL) {
5874 /* Return all requests for the specified 'tid'. */
5875 if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
5876 /* List is empty; Set first and last return pointers to NULL. */
5877 firstp = lastp = NULL;
5878 } else {
5879 firstp = ascq->q_first[tid];
5880 lastp = ascq->q_last[tid];
5881 ascq->q_first[tid] = ascq->q_last[tid] = NULL;
5882 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5883 #ifdef ADVANSYS_STATS
5885 REQP reqp;
5886 ascq->q_cur_cnt[tid] = 0;
5887 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
5888 REQTIMESTAT("asc_dequeue_list", ascq,
5889 reqp, tid);
5892 #endif /* ADVANSYS_STATS */
5894 } else {
5895 /* Return all requests for all tids. */
5896 firstp = lastp = NULL;
5897 for (i = 0; i <= ADV_MAX_TID; i++) {
5898 if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
5899 if (firstp == NULL) {
5900 firstp = ascq->q_first[i];
5901 lastp = ascq->q_last[i];
5902 } else {
5903 ASC_ASSERT(lastp != NULL);
5904 lastp->host_scribble =
5905 (unsigned char *)ascq->q_first[i];
5906 lastp = ascq->q_last[i];
5908 ascq->q_first[i] = ascq->q_last[i] = NULL;
5909 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
5910 #ifdef ADVANSYS_STATS
5911 ascq->q_cur_cnt[i] = 0;
5912 #endif /* ADVANSYS_STATS */
5915 #ifdef ADVANSYS_STATS
5917 REQP reqp;
5918 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
5919 REQTIMESTAT("asc_dequeue_list", ascq, reqp,
5920 reqp->device->id);
5923 #endif /* ADVANSYS_STATS */
5925 if (lastpp) {
5926 *lastpp = lastp;
5928 ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong)firstp);
5929 return firstp;
5933 * Remove the specified 'REQP' from the specified queue for
5934 * the specified target device. Clear the 'tidmask' bit for the
5935 * device if no more commands are left queued for it.
5937 * 'REQPNEXT(reqp)' returns reqp's the next pointer.
5939 * Return ASC_TRUE if the command was found and removed,
5940 * otherwise return ASC_FALSE.
5942 static int asc_rmqueue(asc_queue_t *ascq, REQP reqp)
5944 REQP currp, prevp;
5945 int tid;
5946 int ret = ASC_FALSE;
5948 ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
5949 (ulong)ascq, (ulong)reqp);
5950 ASC_ASSERT(reqp != NULL);
5952 tid = REQPTID(reqp);
5953 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5956 * Handle the common case of 'reqp' being the first
5957 * entry on the queue.
5959 if (reqp == ascq->q_first[tid]) {
5960 ret = ASC_TRUE;
5961 ascq->q_first[tid] = REQPNEXT(reqp);
5962 /* If the queue is now empty, clear its bit and the last pointer. */
5963 if (ascq->q_first[tid] == NULL) {
5964 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5965 ASC_ASSERT(ascq->q_last[tid] == reqp);
5966 ascq->q_last[tid] = NULL;
5968 } else if (ascq->q_first[tid] != NULL) {
5969 ASC_ASSERT(ascq->q_last[tid] != NULL);
5971 * Because the case of 'reqp' being the first entry has been
5972 * handled above and it is known the queue is not empty, if
5973 * 'reqp' is found on the queue it is guaranteed the queue will
5974 * not become empty and that 'q_first[tid]' will not be changed.
5976 * Set 'prevp' to the first entry, 'currp' to the second entry,
5977 * and search for 'reqp'.
5979 for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
5980 currp; prevp = currp, currp = REQPNEXT(currp)) {
5981 if (currp == reqp) {
5982 ret = ASC_TRUE;
5983 prevp->host_scribble =
5984 (unsigned char *)REQPNEXT(currp);
5985 reqp->host_scribble = NULL;
5986 if (ascq->q_last[tid] == reqp) {
5987 ascq->q_last[tid] = prevp;
5989 break;
5993 #ifdef ADVANSYS_STATS
5994 /* Maintain request queue statistics. */
5995 if (ret == ASC_TRUE) {
5996 ascq->q_cur_cnt[tid]--;
5997 REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
5999 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
6000 #endif /* ADVANSYS_STATS */
6001 ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong)reqp, ret);
6002 return ret;
6006 * Execute as many queued requests as possible for the specified queue.
6008 * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd.
6010 static void asc_execute_queue(asc_queue_t *ascq)
6012 ADV_SCSI_BIT_ID_TYPE scan_tidmask;
6013 REQP reqp;
6014 int i;
6016 ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong)ascq);
6018 * Execute queued commands for devices attached to
6019 * the current board in round-robin fashion.
6021 scan_tidmask = ascq->q_tidmask;
6022 do {
6023 for (i = 0; i <= ADV_MAX_TID; i++) {
6024 if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
6025 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
6026 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
6027 } else
6028 if (asc_execute_scsi_cmnd
6029 ((struct scsi_cmnd *)reqp)
6030 == ASC_BUSY) {
6031 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
6033 * The request returned ASC_BUSY. Enqueue at the front of
6034 * target's waiting list to maintain correct ordering.
6036 asc_enqueue(ascq, reqp, ASC_FRONT);
6040 } while (scan_tidmask);
6041 return;
6044 #ifdef CONFIG_PROC_FS
6046 * asc_prt_board_devices()
6048 * Print driver information for devices attached to the board.
6050 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6051 * cf. asc_prt_line().
6053 * Return the number of characters copied into 'cp'. No more than
6054 * 'cplen' characters will be copied to 'cp'.
6056 static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
6058 asc_board_t *boardp;
6059 int leftlen;
6060 int totlen;
6061 int len;
6062 int chip_scsi_id;
6063 int i;
6065 boardp = ASC_BOARDP(shost);
6066 leftlen = cplen;
6067 totlen = len = 0;
6069 len = asc_prt_line(cp, leftlen,
6070 "\nDevice Information for AdvanSys SCSI Host %d:\n",
6071 shost->host_no);
6072 ASC_PRT_NEXT();
6074 if (ASC_NARROW_BOARD(boardp)) {
6075 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6076 } else {
6077 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6080 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
6081 ASC_PRT_NEXT();
6082 for (i = 0; i <= ADV_MAX_TID; i++) {
6083 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
6084 len = asc_prt_line(cp, leftlen, " %X,", i);
6085 ASC_PRT_NEXT();
6088 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
6089 ASC_PRT_NEXT();
6091 return totlen;
6095 * Display Wide Board BIOS Information.
6097 static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
6099 asc_board_t *boardp;
6100 int leftlen;
6101 int totlen;
6102 int len;
6103 ushort major, minor, letter;
6105 boardp = ASC_BOARDP(shost);
6106 leftlen = cplen;
6107 totlen = len = 0;
6109 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
6110 ASC_PRT_NEXT();
6113 * If the BIOS saved a valid signature, then fill in
6114 * the BIOS code segment base address.
6116 if (boardp->bios_signature != 0x55AA) {
6117 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
6118 ASC_PRT_NEXT();
6119 len = asc_prt_line(cp, leftlen,
6120 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
6121 ASC_PRT_NEXT();
6122 len = asc_prt_line(cp, leftlen,
6123 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
6124 ASC_PRT_NEXT();
6125 } else {
6126 major = (boardp->bios_version >> 12) & 0xF;
6127 minor = (boardp->bios_version >> 8) & 0xF;
6128 letter = (boardp->bios_version & 0xFF);
6130 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
6131 major, minor,
6132 letter >= 26 ? '?' : letter + 'A');
6133 ASC_PRT_NEXT();
6136 * Current available ROM BIOS release is 3.1I for UW
6137 * and 3.2I for U2W. This code doesn't differentiate
6138 * UW and U2W boards.
6140 if (major < 3 || (major <= 3 && minor < 1) ||
6141 (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
6142 len = asc_prt_line(cp, leftlen,
6143 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
6144 ASC_PRT_NEXT();
6145 len = asc_prt_line(cp, leftlen,
6146 "ftp://ftp.connectcom.net/pub\n");
6147 ASC_PRT_NEXT();
6151 return totlen;
6155 * Add serial number to information bar if signature AAh
6156 * is found in at bit 15-9 (7 bits) of word 1.
6158 * Serial Number consists fo 12 alpha-numeric digits.
6160 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
6161 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
6162 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
6163 * 5 - Product revision (A-J) Word0: " "
6165 * Signature Word1: 15-9 (7 bits)
6166 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
6167 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
6169 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
6171 * Note 1: Only production cards will have a serial number.
6173 * Note 2: Signature is most significant 7 bits (0xFE).
6175 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
6177 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
6179 ushort w, num;
6181 if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
6182 return ASC_FALSE;
6183 } else {
6185 * First word - 6 digits.
6187 w = serialnum[0];
6189 /* Product type - 1st digit. */
6190 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
6191 /* Product type is P=Prototype */
6192 *cp += 0x8;
6194 cp++;
6196 /* Manufacturing location - 2nd digit. */
6197 *cp++ = 'A' + ((w & 0x1C00) >> 10);
6199 /* Product ID - 3rd, 4th digits. */
6200 num = w & 0x3FF;
6201 *cp++ = '0' + (num / 100);
6202 num %= 100;
6203 *cp++ = '0' + (num / 10);
6205 /* Product revision - 5th digit. */
6206 *cp++ = 'A' + (num % 10);
6209 * Second word
6211 w = serialnum[1];
6214 * Year - 6th digit.
6216 * If bit 15 of third word is set, then the
6217 * last digit of the year is greater than 7.
6219 if (serialnum[2] & 0x8000) {
6220 *cp++ = '8' + ((w & 0x1C0) >> 6);
6221 } else {
6222 *cp++ = '0' + ((w & 0x1C0) >> 6);
6225 /* Week of year - 7th, 8th digits. */
6226 num = w & 0x003F;
6227 *cp++ = '0' + num / 10;
6228 num %= 10;
6229 *cp++ = '0' + num;
6232 * Third word
6234 w = serialnum[2] & 0x7FFF;
6236 /* Serial number - 9th digit. */
6237 *cp++ = 'A' + (w / 1000);
6239 /* 10th, 11th, 12th digits. */
6240 num = w % 1000;
6241 *cp++ = '0' + num / 100;
6242 num %= 100;
6243 *cp++ = '0' + num / 10;
6244 num %= 10;
6245 *cp++ = '0' + num;
6247 *cp = '\0'; /* Null Terminate the string. */
6248 return ASC_TRUE;
6253 * asc_prt_asc_board_eeprom()
6255 * Print board EEPROM configuration.
6257 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6258 * cf. asc_prt_line().
6260 * Return the number of characters copied into 'cp'. No more than
6261 * 'cplen' characters will be copied to 'cp'.
6263 static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
6265 asc_board_t *boardp;
6266 ASC_DVC_VAR *asc_dvc_varp;
6267 int leftlen;
6268 int totlen;
6269 int len;
6270 ASCEEP_CONFIG *ep;
6271 int i;
6272 #ifdef CONFIG_ISA
6273 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
6274 #endif /* CONFIG_ISA */
6275 uchar serialstr[13];
6277 boardp = ASC_BOARDP(shost);
6278 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6279 ep = &boardp->eep_config.asc_eep;
6281 leftlen = cplen;
6282 totlen = len = 0;
6284 len = asc_prt_line(cp, leftlen,
6285 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6286 shost->host_no);
6287 ASC_PRT_NEXT();
6289 if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
6290 == ASC_TRUE) {
6291 len =
6292 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6293 serialstr);
6294 ASC_PRT_NEXT();
6295 } else {
6296 if (ep->adapter_info[5] == 0xBB) {
6297 len = asc_prt_line(cp, leftlen,
6298 " Default Settings Used for EEPROM-less Adapter.\n");
6299 ASC_PRT_NEXT();
6300 } else {
6301 len = asc_prt_line(cp, leftlen,
6302 " Serial Number Signature Not Present.\n");
6303 ASC_PRT_NEXT();
6307 len = asc_prt_line(cp, leftlen,
6308 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6309 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
6310 ep->max_tag_qng);
6311 ASC_PRT_NEXT();
6313 len = asc_prt_line(cp, leftlen,
6314 " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
6315 ASC_PRT_NEXT();
6317 len = asc_prt_line(cp, leftlen, " Target ID: ");
6318 ASC_PRT_NEXT();
6319 for (i = 0; i <= ASC_MAX_TID; i++) {
6320 len = asc_prt_line(cp, leftlen, " %d", i);
6321 ASC_PRT_NEXT();
6323 len = asc_prt_line(cp, leftlen, "\n");
6324 ASC_PRT_NEXT();
6326 len = asc_prt_line(cp, leftlen, " Disconnects: ");
6327 ASC_PRT_NEXT();
6328 for (i = 0; i <= ASC_MAX_TID; i++) {
6329 len = asc_prt_line(cp, leftlen, " %c",
6330 (ep->
6331 disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6332 'N');
6333 ASC_PRT_NEXT();
6335 len = asc_prt_line(cp, leftlen, "\n");
6336 ASC_PRT_NEXT();
6338 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
6339 ASC_PRT_NEXT();
6340 for (i = 0; i <= ASC_MAX_TID; i++) {
6341 len = asc_prt_line(cp, leftlen, " %c",
6342 (ep->
6343 use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6344 'N');
6345 ASC_PRT_NEXT();
6347 len = asc_prt_line(cp, leftlen, "\n");
6348 ASC_PRT_NEXT();
6350 len = asc_prt_line(cp, leftlen, " Start Motor: ");
6351 ASC_PRT_NEXT();
6352 for (i = 0; i <= ASC_MAX_TID; i++) {
6353 len = asc_prt_line(cp, leftlen, " %c",
6354 (ep->
6355 start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6356 'N');
6357 ASC_PRT_NEXT();
6359 len = asc_prt_line(cp, leftlen, "\n");
6360 ASC_PRT_NEXT();
6362 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6363 ASC_PRT_NEXT();
6364 for (i = 0; i <= ASC_MAX_TID; i++) {
6365 len = asc_prt_line(cp, leftlen, " %c",
6366 (ep->
6367 init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6368 'N');
6369 ASC_PRT_NEXT();
6371 len = asc_prt_line(cp, leftlen, "\n");
6372 ASC_PRT_NEXT();
6374 #ifdef CONFIG_ISA
6375 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
6376 len = asc_prt_line(cp, leftlen,
6377 " Host ISA DMA speed: %d MB/S\n",
6378 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
6379 ASC_PRT_NEXT();
6381 #endif /* CONFIG_ISA */
6383 return totlen;
6387 * asc_prt_adv_board_eeprom()
6389 * Print board EEPROM configuration.
6391 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6392 * cf. asc_prt_line().
6394 * Return the number of characters copied into 'cp'. No more than
6395 * 'cplen' characters will be copied to 'cp'.
6397 static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
6399 asc_board_t *boardp;
6400 ADV_DVC_VAR *adv_dvc_varp;
6401 int leftlen;
6402 int totlen;
6403 int len;
6404 int i;
6405 char *termstr;
6406 uchar serialstr[13];
6407 ADVEEP_3550_CONFIG *ep_3550 = NULL;
6408 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
6409 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
6410 ushort word;
6411 ushort *wordp;
6412 ushort sdtr_speed = 0;
6414 boardp = ASC_BOARDP(shost);
6415 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6416 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6417 ep_3550 = &boardp->eep_config.adv_3550_eep;
6418 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6419 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
6420 } else {
6421 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
6424 leftlen = cplen;
6425 totlen = len = 0;
6427 len = asc_prt_line(cp, leftlen,
6428 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6429 shost->host_no);
6430 ASC_PRT_NEXT();
6432 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6433 wordp = &ep_3550->serial_number_word1;
6434 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6435 wordp = &ep_38C0800->serial_number_word1;
6436 } else {
6437 wordp = &ep_38C1600->serial_number_word1;
6440 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
6441 len =
6442 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6443 serialstr);
6444 ASC_PRT_NEXT();
6445 } else {
6446 len = asc_prt_line(cp, leftlen,
6447 " Serial Number Signature Not Present.\n");
6448 ASC_PRT_NEXT();
6451 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6452 len = asc_prt_line(cp, leftlen,
6453 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6454 ep_3550->adapter_scsi_id,
6455 ep_3550->max_host_qng, ep_3550->max_dvc_qng);
6456 ASC_PRT_NEXT();
6457 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6458 len = asc_prt_line(cp, leftlen,
6459 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6460 ep_38C0800->adapter_scsi_id,
6461 ep_38C0800->max_host_qng,
6462 ep_38C0800->max_dvc_qng);
6463 ASC_PRT_NEXT();
6464 } else {
6465 len = asc_prt_line(cp, leftlen,
6466 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6467 ep_38C1600->adapter_scsi_id,
6468 ep_38C1600->max_host_qng,
6469 ep_38C1600->max_dvc_qng);
6470 ASC_PRT_NEXT();
6472 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6473 word = ep_3550->termination;
6474 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6475 word = ep_38C0800->termination_lvd;
6476 } else {
6477 word = ep_38C1600->termination_lvd;
6479 switch (word) {
6480 case 1:
6481 termstr = "Low Off/High Off";
6482 break;
6483 case 2:
6484 termstr = "Low Off/High On";
6485 break;
6486 case 3:
6487 termstr = "Low On/High On";
6488 break;
6489 default:
6490 case 0:
6491 termstr = "Automatic";
6492 break;
6495 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6496 len = asc_prt_line(cp, leftlen,
6497 " termination: %u (%s), bios_ctrl: 0x%x\n",
6498 ep_3550->termination, termstr,
6499 ep_3550->bios_ctrl);
6500 ASC_PRT_NEXT();
6501 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6502 len = asc_prt_line(cp, leftlen,
6503 " termination: %u (%s), bios_ctrl: 0x%x\n",
6504 ep_38C0800->termination_lvd, termstr,
6505 ep_38C0800->bios_ctrl);
6506 ASC_PRT_NEXT();
6507 } else {
6508 len = asc_prt_line(cp, leftlen,
6509 " termination: %u (%s), bios_ctrl: 0x%x\n",
6510 ep_38C1600->termination_lvd, termstr,
6511 ep_38C1600->bios_ctrl);
6512 ASC_PRT_NEXT();
6515 len = asc_prt_line(cp, leftlen, " Target ID: ");
6516 ASC_PRT_NEXT();
6517 for (i = 0; i <= ADV_MAX_TID; i++) {
6518 len = asc_prt_line(cp, leftlen, " %X", i);
6519 ASC_PRT_NEXT();
6521 len = asc_prt_line(cp, leftlen, "\n");
6522 ASC_PRT_NEXT();
6524 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6525 word = ep_3550->disc_enable;
6526 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6527 word = ep_38C0800->disc_enable;
6528 } else {
6529 word = ep_38C1600->disc_enable;
6531 len = asc_prt_line(cp, leftlen, " Disconnects: ");
6532 ASC_PRT_NEXT();
6533 for (i = 0; i <= ADV_MAX_TID; i++) {
6534 len = asc_prt_line(cp, leftlen, " %c",
6535 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6536 ASC_PRT_NEXT();
6538 len = asc_prt_line(cp, leftlen, "\n");
6539 ASC_PRT_NEXT();
6541 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6542 word = ep_3550->tagqng_able;
6543 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6544 word = ep_38C0800->tagqng_able;
6545 } else {
6546 word = ep_38C1600->tagqng_able;
6548 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
6549 ASC_PRT_NEXT();
6550 for (i = 0; i <= ADV_MAX_TID; i++) {
6551 len = asc_prt_line(cp, leftlen, " %c",
6552 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6553 ASC_PRT_NEXT();
6555 len = asc_prt_line(cp, leftlen, "\n");
6556 ASC_PRT_NEXT();
6558 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6559 word = ep_3550->start_motor;
6560 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6561 word = ep_38C0800->start_motor;
6562 } else {
6563 word = ep_38C1600->start_motor;
6565 len = asc_prt_line(cp, leftlen, " Start Motor: ");
6566 ASC_PRT_NEXT();
6567 for (i = 0; i <= ADV_MAX_TID; i++) {
6568 len = asc_prt_line(cp, leftlen, " %c",
6569 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6570 ASC_PRT_NEXT();
6572 len = asc_prt_line(cp, leftlen, "\n");
6573 ASC_PRT_NEXT();
6575 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6576 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6577 ASC_PRT_NEXT();
6578 for (i = 0; i <= ADV_MAX_TID; i++) {
6579 len = asc_prt_line(cp, leftlen, " %c",
6580 (ep_3550->
6581 sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
6582 'Y' : 'N');
6583 ASC_PRT_NEXT();
6585 len = asc_prt_line(cp, leftlen, "\n");
6586 ASC_PRT_NEXT();
6589 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6590 len = asc_prt_line(cp, leftlen, " Ultra Transfer: ");
6591 ASC_PRT_NEXT();
6592 for (i = 0; i <= ADV_MAX_TID; i++) {
6593 len = asc_prt_line(cp, leftlen, " %c",
6594 (ep_3550->
6595 ultra_able & ADV_TID_TO_TIDMASK(i))
6596 ? 'Y' : 'N');
6597 ASC_PRT_NEXT();
6599 len = asc_prt_line(cp, leftlen, "\n");
6600 ASC_PRT_NEXT();
6603 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6604 word = ep_3550->wdtr_able;
6605 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6606 word = ep_38C0800->wdtr_able;
6607 } else {
6608 word = ep_38C1600->wdtr_able;
6610 len = asc_prt_line(cp, leftlen, " Wide Transfer: ");
6611 ASC_PRT_NEXT();
6612 for (i = 0; i <= ADV_MAX_TID; i++) {
6613 len = asc_prt_line(cp, leftlen, " %c",
6614 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6615 ASC_PRT_NEXT();
6617 len = asc_prt_line(cp, leftlen, "\n");
6618 ASC_PRT_NEXT();
6620 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
6621 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
6622 len = asc_prt_line(cp, leftlen,
6623 " Synchronous Transfer Speed (Mhz):\n ");
6624 ASC_PRT_NEXT();
6625 for (i = 0; i <= ADV_MAX_TID; i++) {
6626 char *speed_str;
6628 if (i == 0) {
6629 sdtr_speed = adv_dvc_varp->sdtr_speed1;
6630 } else if (i == 4) {
6631 sdtr_speed = adv_dvc_varp->sdtr_speed2;
6632 } else if (i == 8) {
6633 sdtr_speed = adv_dvc_varp->sdtr_speed3;
6634 } else if (i == 12) {
6635 sdtr_speed = adv_dvc_varp->sdtr_speed4;
6637 switch (sdtr_speed & ADV_MAX_TID) {
6638 case 0:
6639 speed_str = "Off";
6640 break;
6641 case 1:
6642 speed_str = " 5";
6643 break;
6644 case 2:
6645 speed_str = " 10";
6646 break;
6647 case 3:
6648 speed_str = " 20";
6649 break;
6650 case 4:
6651 speed_str = " 40";
6652 break;
6653 case 5:
6654 speed_str = " 80";
6655 break;
6656 default:
6657 speed_str = "Unk";
6658 break;
6660 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
6661 ASC_PRT_NEXT();
6662 if (i == 7) {
6663 len = asc_prt_line(cp, leftlen, "\n ");
6664 ASC_PRT_NEXT();
6666 sdtr_speed >>= 4;
6668 len = asc_prt_line(cp, leftlen, "\n");
6669 ASC_PRT_NEXT();
6672 return totlen;
6676 * asc_prt_driver_conf()
6678 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6679 * cf. asc_prt_line().
6681 * Return the number of characters copied into 'cp'. No more than
6682 * 'cplen' characters will be copied to 'cp'.
6684 static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
6686 asc_board_t *boardp;
6687 int leftlen;
6688 int totlen;
6689 int len;
6690 int chip_scsi_id;
6692 boardp = ASC_BOARDP(shost);
6694 leftlen = cplen;
6695 totlen = len = 0;
6697 len = asc_prt_line(cp, leftlen,
6698 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
6699 shost->host_no);
6700 ASC_PRT_NEXT();
6702 len = asc_prt_line(cp, leftlen,
6703 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
6704 shost->host_busy, shost->last_reset, shost->max_id,
6705 shost->max_lun, shost->max_channel);
6706 ASC_PRT_NEXT();
6708 len = asc_prt_line(cp, leftlen,
6709 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
6710 shost->unique_id, shost->can_queue, shost->this_id,
6711 shost->sg_tablesize, shost->cmd_per_lun);
6712 ASC_PRT_NEXT();
6714 len = asc_prt_line(cp, leftlen,
6715 " unchecked_isa_dma %d, use_clustering %d\n",
6716 shost->unchecked_isa_dma, shost->use_clustering);
6717 ASC_PRT_NEXT();
6719 len = asc_prt_line(cp, leftlen,
6720 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
6721 boardp->flags, boardp->last_reset, jiffies,
6722 boardp->asc_n_io_port);
6723 ASC_PRT_NEXT();
6725 /* 'shost->n_io_port' may be truncated because it is only one byte. */
6726 len = asc_prt_line(cp, leftlen,
6727 " io_port 0x%x, n_io_port 0x%x\n",
6728 shost->io_port, shost->n_io_port);
6729 ASC_PRT_NEXT();
6731 if (ASC_NARROW_BOARD(boardp)) {
6732 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6733 } else {
6734 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6737 return totlen;
6741 * asc_prt_asc_board_info()
6743 * Print dynamic board configuration information.
6745 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6746 * cf. asc_prt_line().
6748 * Return the number of characters copied into 'cp'. No more than
6749 * 'cplen' characters will be copied to 'cp'.
6751 static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
6753 asc_board_t *boardp;
6754 int chip_scsi_id;
6755 int leftlen;
6756 int totlen;
6757 int len;
6758 ASC_DVC_VAR *v;
6759 ASC_DVC_CFG *c;
6760 int i;
6761 int renegotiate = 0;
6763 boardp = ASC_BOARDP(shost);
6764 v = &boardp->dvc_var.asc_dvc_var;
6765 c = &boardp->dvc_cfg.asc_dvc_cfg;
6766 chip_scsi_id = c->chip_scsi_id;
6768 leftlen = cplen;
6769 totlen = len = 0;
6771 len = asc_prt_line(cp, leftlen,
6772 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6773 shost->host_no);
6774 ASC_PRT_NEXT();
6776 len = asc_prt_line(cp, leftlen,
6777 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
6778 c->chip_version, c->lib_version, c->lib_serial_no,
6779 c->mcode_date);
6780 ASC_PRT_NEXT();
6782 len = asc_prt_line(cp, leftlen,
6783 " mcode_version 0x%x, err_code %u\n",
6784 c->mcode_version, v->err_code);
6785 ASC_PRT_NEXT();
6787 /* Current number of commands waiting for the host. */
6788 len = asc_prt_line(cp, leftlen,
6789 " Total Command Pending: %d\n", v->cur_total_qng);
6790 ASC_PRT_NEXT();
6792 len = asc_prt_line(cp, leftlen, " Command Queuing:");
6793 ASC_PRT_NEXT();
6794 for (i = 0; i <= ASC_MAX_TID; i++) {
6795 if ((chip_scsi_id == i) ||
6796 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6797 continue;
6799 len = asc_prt_line(cp, leftlen, " %X:%c",
6801 (v->
6802 use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
6803 'Y' : 'N');
6804 ASC_PRT_NEXT();
6806 len = asc_prt_line(cp, leftlen, "\n");
6807 ASC_PRT_NEXT();
6809 /* Current number of commands waiting for a device. */
6810 len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
6811 ASC_PRT_NEXT();
6812 for (i = 0; i <= ASC_MAX_TID; i++) {
6813 if ((chip_scsi_id == i) ||
6814 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6815 continue;
6817 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
6818 ASC_PRT_NEXT();
6820 len = asc_prt_line(cp, leftlen, "\n");
6821 ASC_PRT_NEXT();
6823 /* Current limit on number of commands that can be sent to a device. */
6824 len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
6825 ASC_PRT_NEXT();
6826 for (i = 0; i <= ASC_MAX_TID; i++) {
6827 if ((chip_scsi_id == i) ||
6828 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6829 continue;
6831 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
6832 ASC_PRT_NEXT();
6834 len = asc_prt_line(cp, leftlen, "\n");
6835 ASC_PRT_NEXT();
6837 /* Indicate whether the device has returned queue full status. */
6838 len = asc_prt_line(cp, leftlen, " Command Queue Full:");
6839 ASC_PRT_NEXT();
6840 for (i = 0; i <= ASC_MAX_TID; i++) {
6841 if ((chip_scsi_id == i) ||
6842 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6843 continue;
6845 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
6846 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
6847 i, boardp->queue_full_cnt[i]);
6848 } else {
6849 len = asc_prt_line(cp, leftlen, " %X:N", i);
6851 ASC_PRT_NEXT();
6853 len = asc_prt_line(cp, leftlen, "\n");
6854 ASC_PRT_NEXT();
6856 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6857 ASC_PRT_NEXT();
6858 for (i = 0; i <= ASC_MAX_TID; i++) {
6859 if ((chip_scsi_id == i) ||
6860 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6861 continue;
6863 len = asc_prt_line(cp, leftlen, " %X:%c",
6865 (v->
6866 sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6867 'N');
6868 ASC_PRT_NEXT();
6870 len = asc_prt_line(cp, leftlen, "\n");
6871 ASC_PRT_NEXT();
6873 for (i = 0; i <= ASC_MAX_TID; i++) {
6874 uchar syn_period_ix;
6876 if ((chip_scsi_id == i) ||
6877 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
6878 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
6879 continue;
6882 len = asc_prt_line(cp, leftlen, " %X:", i);
6883 ASC_PRT_NEXT();
6885 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
6886 len = asc_prt_line(cp, leftlen, " Asynchronous");
6887 ASC_PRT_NEXT();
6888 } else {
6889 syn_period_ix =
6890 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
6893 len = asc_prt_line(cp, leftlen,
6894 " Transfer Period Factor: %d (%d.%d Mhz),",
6895 v->sdtr_period_tbl[syn_period_ix],
6896 250 /
6897 v->sdtr_period_tbl[syn_period_ix],
6898 ASC_TENTHS(250,
6900 sdtr_period_tbl
6901 [syn_period_ix]));
6902 ASC_PRT_NEXT();
6904 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
6905 boardp->
6906 sdtr_data[i] & ASC_SYN_MAX_OFFSET);
6907 ASC_PRT_NEXT();
6910 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
6911 len = asc_prt_line(cp, leftlen, "*\n");
6912 renegotiate = 1;
6913 } else {
6914 len = asc_prt_line(cp, leftlen, "\n");
6916 ASC_PRT_NEXT();
6919 if (renegotiate) {
6920 len = asc_prt_line(cp, leftlen,
6921 " * = Re-negotiation pending before next command.\n");
6922 ASC_PRT_NEXT();
6925 return totlen;
6929 * asc_prt_adv_board_info()
6931 * Print dynamic board configuration information.
6933 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6934 * cf. asc_prt_line().
6936 * Return the number of characters copied into 'cp'. No more than
6937 * 'cplen' characters will be copied to 'cp'.
6939 static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
6941 asc_board_t *boardp;
6942 int leftlen;
6943 int totlen;
6944 int len;
6945 int i;
6946 ADV_DVC_VAR *v;
6947 ADV_DVC_CFG *c;
6948 AdvPortAddr iop_base;
6949 ushort chip_scsi_id;
6950 ushort lramword;
6951 uchar lrambyte;
6952 ushort tagqng_able;
6953 ushort sdtr_able, wdtr_able;
6954 ushort wdtr_done, sdtr_done;
6955 ushort period = 0;
6956 int renegotiate = 0;
6958 boardp = ASC_BOARDP(shost);
6959 v = &boardp->dvc_var.adv_dvc_var;
6960 c = &boardp->dvc_cfg.adv_dvc_cfg;
6961 iop_base = v->iop_base;
6962 chip_scsi_id = v->chip_scsi_id;
6964 leftlen = cplen;
6965 totlen = len = 0;
6967 len = asc_prt_line(cp, leftlen,
6968 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6969 shost->host_no);
6970 ASC_PRT_NEXT();
6972 len = asc_prt_line(cp, leftlen,
6973 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
6974 v->iop_base,
6975 AdvReadWordRegister(iop_base,
6976 IOPW_SCSI_CFG1) & CABLE_DETECT,
6977 v->err_code);
6978 ASC_PRT_NEXT();
6980 len = asc_prt_line(cp, leftlen,
6981 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
6982 c->chip_version, c->lib_version, c->mcode_date,
6983 c->mcode_version);
6984 ASC_PRT_NEXT();
6986 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
6987 len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
6988 ASC_PRT_NEXT();
6989 for (i = 0; i <= ADV_MAX_TID; i++) {
6990 if ((chip_scsi_id == i) ||
6991 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6992 continue;
6995 len = asc_prt_line(cp, leftlen, " %X:%c",
6997 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6998 'N');
6999 ASC_PRT_NEXT();
7001 len = asc_prt_line(cp, leftlen, "\n");
7002 ASC_PRT_NEXT();
7004 len = asc_prt_line(cp, leftlen, " Queue Limit:");
7005 ASC_PRT_NEXT();
7006 for (i = 0; i <= ADV_MAX_TID; i++) {
7007 if ((chip_scsi_id == i) ||
7008 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7009 continue;
7012 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
7013 lrambyte);
7015 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
7016 ASC_PRT_NEXT();
7018 len = asc_prt_line(cp, leftlen, "\n");
7019 ASC_PRT_NEXT();
7021 len = asc_prt_line(cp, leftlen, " Command Pending:");
7022 ASC_PRT_NEXT();
7023 for (i = 0; i <= ADV_MAX_TID; i++) {
7024 if ((chip_scsi_id == i) ||
7025 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7026 continue;
7029 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
7030 lrambyte);
7032 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
7033 ASC_PRT_NEXT();
7035 len = asc_prt_line(cp, leftlen, "\n");
7036 ASC_PRT_NEXT();
7038 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7039 len = asc_prt_line(cp, leftlen, " Wide Enabled:");
7040 ASC_PRT_NEXT();
7041 for (i = 0; i <= ADV_MAX_TID; i++) {
7042 if ((chip_scsi_id == i) ||
7043 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7044 continue;
7047 len = asc_prt_line(cp, leftlen, " %X:%c",
7049 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7050 'N');
7051 ASC_PRT_NEXT();
7053 len = asc_prt_line(cp, leftlen, "\n");
7054 ASC_PRT_NEXT();
7056 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
7057 len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
7058 ASC_PRT_NEXT();
7059 for (i = 0; i <= ADV_MAX_TID; i++) {
7060 if ((chip_scsi_id == i) ||
7061 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7062 continue;
7065 AdvReadWordLram(iop_base,
7066 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7067 lramword);
7069 len = asc_prt_line(cp, leftlen, " %X:%d",
7070 i, (lramword & 0x8000) ? 16 : 8);
7071 ASC_PRT_NEXT();
7073 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
7074 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7075 len = asc_prt_line(cp, leftlen, "*");
7076 ASC_PRT_NEXT();
7077 renegotiate = 1;
7080 len = asc_prt_line(cp, leftlen, "\n");
7081 ASC_PRT_NEXT();
7083 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7084 len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
7085 ASC_PRT_NEXT();
7086 for (i = 0; i <= ADV_MAX_TID; i++) {
7087 if ((chip_scsi_id == i) ||
7088 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7089 continue;
7092 len = asc_prt_line(cp, leftlen, " %X:%c",
7094 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7095 'N');
7096 ASC_PRT_NEXT();
7098 len = asc_prt_line(cp, leftlen, "\n");
7099 ASC_PRT_NEXT();
7101 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
7102 for (i = 0; i <= ADV_MAX_TID; i++) {
7104 AdvReadWordLram(iop_base,
7105 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7106 lramword);
7107 lramword &= ~0x8000;
7109 if ((chip_scsi_id == i) ||
7110 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
7111 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
7112 continue;
7115 len = asc_prt_line(cp, leftlen, " %X:", i);
7116 ASC_PRT_NEXT();
7118 if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */
7119 len = asc_prt_line(cp, leftlen, " Asynchronous");
7120 ASC_PRT_NEXT();
7121 } else {
7122 len =
7123 asc_prt_line(cp, leftlen,
7124 " Transfer Period Factor: ");
7125 ASC_PRT_NEXT();
7127 if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */
7128 len =
7129 asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
7130 ASC_PRT_NEXT();
7131 } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */
7132 len =
7133 asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
7134 ASC_PRT_NEXT();
7135 } else { /* 20 Mhz or below. */
7137 period = (((lramword >> 8) * 25) + 50) / 4;
7139 if (period == 0) { /* Should never happen. */
7140 len =
7141 asc_prt_line(cp, leftlen,
7142 "%d (? Mhz), ");
7143 ASC_PRT_NEXT();
7144 } else {
7145 len = asc_prt_line(cp, leftlen,
7146 "%d (%d.%d Mhz),",
7147 period, 250 / period,
7148 ASC_TENTHS(250,
7149 period));
7150 ASC_PRT_NEXT();
7154 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
7155 lramword & 0x1F);
7156 ASC_PRT_NEXT();
7159 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7160 len = asc_prt_line(cp, leftlen, "*\n");
7161 renegotiate = 1;
7162 } else {
7163 len = asc_prt_line(cp, leftlen, "\n");
7165 ASC_PRT_NEXT();
7168 if (renegotiate) {
7169 len = asc_prt_line(cp, leftlen,
7170 " * = Re-negotiation pending before next command.\n");
7171 ASC_PRT_NEXT();
7174 return totlen;
7178 * asc_proc_copy()
7180 * Copy proc information to a read buffer taking into account the current
7181 * read offset in the file and the remaining space in the read buffer.
7183 static int
7184 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
7185 char *cp, int cplen)
7187 int cnt = 0;
7189 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
7190 (unsigned)offset, (unsigned)advoffset, cplen);
7191 if (offset <= advoffset) {
7192 /* Read offset below current offset, copy everything. */
7193 cnt = min(cplen, leftlen);
7194 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7195 (ulong)curbuf, (ulong)cp, cnt);
7196 memcpy(curbuf, cp, cnt);
7197 } else if (offset < advoffset + cplen) {
7198 /* Read offset within current range, partial copy. */
7199 cnt = (advoffset + cplen) - offset;
7200 cp = (cp + cplen) - cnt;
7201 cnt = min(cnt, leftlen);
7202 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7203 (ulong)curbuf, (ulong)cp, cnt);
7204 memcpy(curbuf, cp, cnt);
7206 return cnt;
7210 * asc_prt_line()
7212 * If 'cp' is NULL print to the console, otherwise print to a buffer.
7214 * Return 0 if printing to the console, otherwise return the number of
7215 * bytes written to the buffer.
7217 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
7218 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
7220 static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
7222 va_list args;
7223 int ret;
7224 char s[ASC_PRTLINE_SIZE];
7226 va_start(args, fmt);
7227 ret = vsprintf(s, fmt, args);
7228 ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
7229 if (buf == NULL) {
7230 (void)printk(s);
7231 ret = 0;
7232 } else {
7233 ret = min(buflen, ret);
7234 memcpy(buf, s, ret);
7236 va_end(args);
7237 return ret;
7239 #endif /* CONFIG_PROC_FS */
7242 * --- Functions Required by the Asc Library
7246 * Delay for 'n' milliseconds. Don't use the 'jiffies'
7247 * global variable which is incremented once every 5 ms
7248 * from a timer interrupt, because this function may be
7249 * called when interrupts are disabled.
7251 static void DvcSleepMilliSecond(ADV_DCNT n)
7253 ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong)n);
7254 mdelay(n);
7258 * Currently and inline noop but leave as a placeholder.
7259 * Leave DvcEnterCritical() as a noop placeholder.
7261 static inline ulong DvcEnterCritical(void)
7263 return 0;
7267 * Critical sections are all protected by the board spinlock.
7268 * Leave DvcLeaveCritical() as a noop placeholder.
7270 static inline void DvcLeaveCritical(ulong flags)
7272 return;
7276 * void
7277 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7279 * Calling/Exit State:
7280 * none
7282 * Description:
7283 * Output an ASC_SCSI_Q structure to the chip
7285 static void
7286 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7288 int i;
7290 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
7291 AscSetChipLramAddr(iop_base, s_addr);
7292 for (i = 0; i < 2 * words; i += 2) {
7293 if (i == 4 || i == 20) {
7294 continue;
7296 outpw(iop_base + IOP_RAM_DATA,
7297 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
7302 * void
7303 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7305 * Calling/Exit State:
7306 * none
7308 * Description:
7309 * Input an ASC_QDONE_INFO structure from the chip
7311 static void
7312 DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7314 int i;
7315 ushort word;
7317 AscSetChipLramAddr(iop_base, s_addr);
7318 for (i = 0; i < 2 * words; i += 2) {
7319 if (i == 10) {
7320 continue;
7322 word = inpw(iop_base + IOP_RAM_DATA);
7323 inbuf[i] = word & 0xff;
7324 inbuf[i + 1] = (word >> 8) & 0xff;
7326 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
7330 * Return the BIOS address of the adapter at the specified
7331 * I/O port and with the specified bus type.
7333 static ushort __devinit AscGetChipBiosAddress(PortAddr iop_base, ushort bus_type)
7335 ushort cfg_lsw;
7336 ushort bios_addr;
7339 * The PCI BIOS is re-located by the motherboard BIOS. Because
7340 * of this the driver can not determine where a PCI BIOS is
7341 * loaded and executes.
7343 if (bus_type & ASC_IS_PCI) {
7344 return (0);
7346 #ifdef CONFIG_ISA
7347 if ((bus_type & ASC_IS_EISA) != 0) {
7348 cfg_lsw = AscGetEisaChipCfg(iop_base);
7349 cfg_lsw &= 0x000F;
7350 bios_addr = (ushort)(ASC_BIOS_MIN_ADDR +
7351 (cfg_lsw * ASC_BIOS_BANK_SIZE));
7352 return (bios_addr);
7353 } /* if */
7354 #endif /* CONFIG_ISA */
7356 cfg_lsw = AscGetChipCfgLsw(iop_base);
7359 * ISA PnP uses the top bit as the 32K BIOS flag
7361 if (bus_type == ASC_IS_ISAPNP) {
7362 cfg_lsw &= 0x7FFF;
7364 /* if */
7365 bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
7366 ASC_BIOS_MIN_ADDR);
7367 return (bios_addr);
7371 * --- Functions Required by the Adv Library
7375 * DvcGetPhyAddr()
7377 * Return the physical address of 'vaddr' and set '*lenp' to the
7378 * number of physically contiguous bytes that follow 'vaddr'.
7379 * 'flag' indicates the type of structure whose physical address
7380 * is being translated.
7382 * Note: Because Linux currently doesn't page the kernel and all
7383 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
7385 ADV_PADDR
7386 DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
7387 uchar *vaddr, ADV_SDCNT *lenp, int flag)
7389 ADV_PADDR paddr;
7391 paddr = virt_to_bus(vaddr);
7393 ASC_DBG4(4,
7394 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
7395 (ulong)vaddr, (ulong)lenp, (ulong)*((ulong *)lenp),
7396 (ulong)paddr);
7398 return paddr;
7402 * --- Tracing and Debugging Functions
7405 #ifdef ADVANSYS_STATS
7406 #ifdef CONFIG_PROC_FS
7408 * asc_prt_board_stats()
7410 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7411 * cf. asc_prt_line().
7413 * Return the number of characters copied into 'cp'. No more than
7414 * 'cplen' characters will be copied to 'cp'.
7416 static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
7418 int leftlen;
7419 int totlen;
7420 int len;
7421 struct asc_stats *s;
7422 asc_board_t *boardp;
7424 leftlen = cplen;
7425 totlen = len = 0;
7427 boardp = ASC_BOARDP(shost);
7428 s = &boardp->asc_stats;
7430 len = asc_prt_line(cp, leftlen,
7431 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
7432 shost->host_no);
7433 ASC_PRT_NEXT();
7435 len = asc_prt_line(cp, leftlen,
7436 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
7437 s->queuecommand, s->reset, s->biosparam,
7438 s->interrupt);
7439 ASC_PRT_NEXT();
7441 len = asc_prt_line(cp, leftlen,
7442 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
7443 s->callback, s->done, s->build_error,
7444 s->adv_build_noreq, s->adv_build_nosg);
7445 ASC_PRT_NEXT();
7447 len = asc_prt_line(cp, leftlen,
7448 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
7449 s->exe_noerror, s->exe_busy, s->exe_error,
7450 s->exe_unknown);
7451 ASC_PRT_NEXT();
7454 * Display data transfer statistics.
7456 if (s->cont_cnt > 0) {
7457 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
7458 ASC_PRT_NEXT();
7460 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
7461 s->cont_xfer / 2,
7462 ASC_TENTHS(s->cont_xfer, 2));
7463 ASC_PRT_NEXT();
7465 /* Contiguous transfer average size */
7466 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
7467 (s->cont_xfer / 2) / s->cont_cnt,
7468 ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
7469 ASC_PRT_NEXT();
7472 if (s->sg_cnt > 0) {
7474 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
7475 s->sg_cnt, s->sg_elem);
7476 ASC_PRT_NEXT();
7478 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
7479 s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
7480 ASC_PRT_NEXT();
7482 /* Scatter gather transfer statistics */
7483 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
7484 s->sg_elem / s->sg_cnt,
7485 ASC_TENTHS(s->sg_elem, s->sg_cnt));
7486 ASC_PRT_NEXT();
7488 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
7489 (s->sg_xfer / 2) / s->sg_elem,
7490 ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
7491 ASC_PRT_NEXT();
7493 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
7494 (s->sg_xfer / 2) / s->sg_cnt,
7495 ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
7496 ASC_PRT_NEXT();
7500 * Display request queuing statistics.
7502 len = asc_prt_line(cp, leftlen,
7503 " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
7504 HZ);
7505 ASC_PRT_NEXT();
7507 return totlen;
7511 * asc_prt_target_stats()
7513 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7514 * cf. asc_prt_line().
7516 * This is separated from asc_prt_board_stats because a full set
7517 * of targets will overflow ASC_PRTBUF_SIZE.
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_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen)
7525 int leftlen;
7526 int totlen;
7527 int len;
7528 struct asc_stats *s;
7529 ushort chip_scsi_id;
7530 asc_board_t *boardp;
7531 asc_queue_t *active;
7532 asc_queue_t *waiting;
7534 leftlen = cplen;
7535 totlen = len = 0;
7537 boardp = ASC_BOARDP(shost);
7538 s = &boardp->asc_stats;
7540 active = &ASC_BOARDP(shost)->active;
7541 waiting = &ASC_BOARDP(shost)->waiting;
7543 if (ASC_NARROW_BOARD(boardp)) {
7544 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7545 } else {
7546 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7549 if ((chip_scsi_id == tgt_id) ||
7550 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
7551 return 0;
7554 do {
7555 if (active->q_tot_cnt[tgt_id] > 0
7556 || waiting->q_tot_cnt[tgt_id] > 0) {
7557 len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
7558 ASC_PRT_NEXT();
7560 len = asc_prt_line(cp, leftlen,
7561 " active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
7562 active->q_cur_cnt[tgt_id],
7563 active->q_max_cnt[tgt_id],
7564 active->q_tot_cnt[tgt_id],
7565 active->q_min_tim[tgt_id],
7566 active->q_max_tim[tgt_id],
7567 (active->q_tot_cnt[tgt_id] ==
7568 0) ? 0 : (active->
7569 q_tot_tim[tgt_id] /
7570 active->
7571 q_tot_cnt[tgt_id]),
7572 (active->q_tot_cnt[tgt_id] ==
7573 0) ? 0 : ASC_TENTHS(active->
7574 q_tot_tim
7575 [tgt_id],
7576 active->
7577 q_tot_cnt
7578 [tgt_id]));
7579 ASC_PRT_NEXT();
7581 len = asc_prt_line(cp, leftlen,
7582 " waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
7583 waiting->q_cur_cnt[tgt_id],
7584 waiting->q_max_cnt[tgt_id],
7585 waiting->q_tot_cnt[tgt_id],
7586 waiting->q_min_tim[tgt_id],
7587 waiting->q_max_tim[tgt_id],
7588 (waiting->q_tot_cnt[tgt_id] ==
7589 0) ? 0 : (waiting->
7590 q_tot_tim[tgt_id] /
7591 waiting->
7592 q_tot_cnt[tgt_id]),
7593 (waiting->q_tot_cnt[tgt_id] ==
7594 0) ? 0 : ASC_TENTHS(waiting->
7595 q_tot_tim
7596 [tgt_id],
7597 waiting->
7598 q_tot_cnt
7599 [tgt_id]));
7600 ASC_PRT_NEXT();
7602 } while (0);
7604 return totlen;
7606 #endif /* CONFIG_PROC_FS */
7607 #endif /* ADVANSYS_STATS */
7609 #ifdef ADVANSYS_DEBUG
7611 * asc_prt_scsi_host()
7613 static void asc_prt_scsi_host(struct Scsi_Host *s)
7615 asc_board_t *boardp;
7617 boardp = ASC_BOARDP(s);
7619 printk("Scsi_Host at addr 0x%lx\n", (ulong)s);
7620 printk(" host_busy %u, host_no %d, last_reset %d,\n",
7621 s->host_busy, s->host_no, (unsigned)s->last_reset);
7623 printk(" base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
7624 (ulong)s->base, (ulong)s->io_port, s->n_io_port, s->irq);
7626 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
7627 s->dma_channel, s->this_id, s->can_queue);
7629 printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
7630 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
7632 if (ASC_NARROW_BOARD(boardp)) {
7633 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
7634 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
7635 } else {
7636 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
7637 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
7642 * asc_prt_scsi_cmnd()
7644 static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
7646 printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s);
7648 printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
7649 (ulong)s->device->host, (ulong)s->device, s->device->id,
7650 s->device->lun, s->device->channel);
7652 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
7654 printk("sc_data_direction %u, resid %d\n",
7655 s->sc_data_direction, s->resid);
7657 printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len);
7659 printk(" serial_number 0x%x, retries %d, allowed %d\n",
7660 (unsigned)s->serial_number, s->retries, s->allowed);
7662 printk(" timeout_per_command %d\n", s->timeout_per_command);
7664 printk
7665 (" scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
7666 (ulong)s->scsi_done, (ulong)s->done, (ulong)s->host_scribble,
7667 s->result);
7669 printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
7673 * asc_prt_asc_dvc_var()
7675 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
7677 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
7679 printk
7680 (" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n",
7681 h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
7683 printk
7684 (" bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n",
7685 h->bus_type, (ulong)h->isr_callback, (ulong)h->exe_callback,
7686 (unsigned)h->init_sdtr);
7688 printk
7689 (" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n",
7690 (unsigned)h->sdtr_done, (unsigned)h->use_tagged_qng,
7691 (unsigned)h->unit_not_ready, (unsigned)h->chip_no);
7693 printk
7694 (" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n",
7695 (unsigned)h->queue_full_or_busy, (unsigned)h->start_motor,
7696 (unsigned)h->scsi_reset_wait);
7698 printk
7699 (" is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n",
7700 (unsigned)h->is_in_int, (unsigned)h->max_total_qng,
7701 (unsigned)h->cur_total_qng, (unsigned)h->in_critical_cnt);
7703 printk
7704 (" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n",
7705 (unsigned)h->last_q_shortage, (unsigned)h->init_state,
7706 (unsigned)h->no_scam, (unsigned)h->pci_fix_asyn_xfer);
7708 printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no);
7712 * asc_prt_asc_dvc_cfg()
7714 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
7716 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
7718 printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
7719 h->can_tagged_qng, h->cmd_qng_enabled);
7720 printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
7721 h->disc_enable, h->sdtr_enable);
7723 printk
7724 (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
7725 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
7726 h->chip_version);
7728 printk
7729 (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
7730 to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
7731 h->mcode_date);
7733 printk(" mcode_version %d, overrun_buf 0x%lx\n",
7734 h->mcode_version, (ulong)h->overrun_buf);
7738 * asc_prt_asc_scsi_q()
7740 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
7742 ASC_SG_HEAD *sgp;
7743 int i;
7745 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
7747 printk
7748 (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
7749 q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
7750 q->q2.tag_code);
7752 printk
7753 (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7754 (ulong)le32_to_cpu(q->q1.data_addr),
7755 (ulong)le32_to_cpu(q->q1.data_cnt),
7756 (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
7758 printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
7759 (ulong)q->cdbptr, q->q2.cdb_len,
7760 (ulong)q->sg_head, q->q1.sg_queue_cnt);
7762 if (q->sg_head) {
7763 sgp = q->sg_head;
7764 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
7765 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
7766 sgp->queue_cnt);
7767 for (i = 0; i < sgp->entry_cnt; i++) {
7768 printk(" [%u]: addr 0x%lx, bytes %lu\n",
7769 i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
7770 (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
7777 * asc_prt_asc_qdone_info()
7779 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
7781 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
7782 printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
7783 (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
7784 q->d2.tag_code);
7785 printk
7786 (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
7787 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
7791 * asc_prt_adv_dvc_var()
7793 * Display an ADV_DVC_VAR structure.
7795 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
7797 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
7799 printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
7800 (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
7802 printk(" isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
7803 (ulong)h->isr_callback, (unsigned)h->sdtr_able,
7804 (unsigned)h->wdtr_able);
7806 printk(" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
7807 (unsigned)h->start_motor,
7808 (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no);
7810 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
7811 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
7812 (ulong)h->carr_freelist);
7814 printk(" icq_sp 0x%lx, irq_sp 0x%lx\n",
7815 (ulong)h->icq_sp, (ulong)h->irq_sp);
7817 printk(" no_scam 0x%x, tagqng_able 0x%x\n",
7818 (unsigned)h->no_scam, (unsigned)h->tagqng_able);
7820 printk(" chip_scsi_id 0x%x, cfg 0x%lx\n",
7821 (unsigned)h->chip_scsi_id, (ulong)h->cfg);
7825 * asc_prt_adv_dvc_cfg()
7827 * Display an ADV_DVC_CFG structure.
7829 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
7831 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
7833 printk(" disc_enable 0x%x, termination 0x%x\n",
7834 h->disc_enable, h->termination);
7836 printk(" chip_version 0x%x, mcode_date 0x%x\n",
7837 h->chip_version, h->mcode_date);
7839 printk(" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
7840 h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
7842 printk(" control_flag 0x%x, pci_slot_info 0x%x\n",
7843 h->control_flag, h->pci_slot_info);
7847 * asc_prt_adv_scsi_req_q()
7849 * Display an ADV_SCSI_REQ_Q structure.
7851 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
7853 int sg_blk_cnt;
7854 struct asc_sg_block *sg_ptr;
7856 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
7858 printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
7859 q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
7861 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
7862 q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
7864 printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7865 (ulong)le32_to_cpu(q->data_cnt),
7866 (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
7868 printk
7869 (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
7870 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
7872 printk(" sg_working_ix 0x%x, target_cmd %u\n",
7873 q->sg_working_ix, q->target_cmd);
7875 printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
7876 (ulong)le32_to_cpu(q->scsiq_rptr),
7877 (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
7879 /* Display the request's ADV_SG_BLOCK structures. */
7880 if (q->sg_list_ptr != NULL) {
7881 sg_blk_cnt = 0;
7882 while (1) {
7884 * 'sg_ptr' is a physical address. Convert it to a virtual
7885 * address by indexing 'sg_blk_cnt' into the virtual address
7886 * array 'sg_list_ptr'.
7888 * XXX - Assumes all SG physical blocks are virtually contiguous.
7890 sg_ptr =
7891 &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
7892 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
7893 if (sg_ptr->sg_ptr == 0) {
7894 break;
7896 sg_blk_cnt++;
7902 * asc_prt_adv_sgblock()
7904 * Display an ADV_SG_BLOCK structure.
7906 static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
7908 int i;
7910 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
7911 (ulong)b, sgblockno);
7912 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
7913 b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
7914 ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
7915 if (b->sg_ptr != 0) {
7916 ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
7918 for (i = 0; i < b->sg_cnt; i++) {
7919 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
7920 i, (ulong)b->sg_list[i].sg_addr,
7921 (ulong)b->sg_list[i].sg_count);
7926 * asc_prt_hex()
7928 * Print hexadecimal output in 4 byte groupings 32 bytes
7929 * or 8 double-words per line.
7931 static void asc_prt_hex(char *f, uchar *s, int l)
7933 int i;
7934 int j;
7935 int k;
7936 int m;
7938 printk("%s: (%d bytes)\n", f, l);
7940 for (i = 0; i < l; i += 32) {
7942 /* Display a maximum of 8 double-words per line. */
7943 if ((k = (l - i) / 4) >= 8) {
7944 k = 8;
7945 m = 0;
7946 } else {
7947 m = (l - i) % 4;
7950 for (j = 0; j < k; j++) {
7951 printk(" %2.2X%2.2X%2.2X%2.2X",
7952 (unsigned)s[i + (j * 4)],
7953 (unsigned)s[i + (j * 4) + 1],
7954 (unsigned)s[i + (j * 4) + 2],
7955 (unsigned)s[i + (j * 4) + 3]);
7958 switch (m) {
7959 case 0:
7960 default:
7961 break;
7962 case 1:
7963 printk(" %2.2X", (unsigned)s[i + (j * 4)]);
7964 break;
7965 case 2:
7966 printk(" %2.2X%2.2X",
7967 (unsigned)s[i + (j * 4)],
7968 (unsigned)s[i + (j * 4) + 1]);
7969 break;
7970 case 3:
7971 printk(" %2.2X%2.2X%2.2X",
7972 (unsigned)s[i + (j * 4) + 1],
7973 (unsigned)s[i + (j * 4) + 2],
7974 (unsigned)s[i + (j * 4) + 3]);
7975 break;
7978 printk("\n");
7981 #endif /* ADVANSYS_DEBUG */
7984 * --- Asc Library Functions
7987 static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
7989 PortAddr eisa_cfg_iop;
7991 eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
7992 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
7993 return (inpw(eisa_cfg_iop));
7996 static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
7998 ushort cfg_lsw;
8000 if (AscGetChipScsiID(iop_base) == new_host_id) {
8001 return (new_host_id);
8003 cfg_lsw = AscGetChipCfgLsw(iop_base);
8004 cfg_lsw &= 0xF8FF;
8005 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
8006 AscSetChipCfgLsw(iop_base, cfg_lsw);
8007 return (AscGetChipScsiID(iop_base));
8010 static uchar __devinit AscGetChipScsiCtrl(PortAddr iop_base)
8012 uchar sc;
8014 AscSetBank(iop_base, 1);
8015 sc = inp(iop_base + IOP_REG_SC);
8016 AscSetBank(iop_base, 0);
8017 return (sc);
8020 static uchar __devinit AscGetChipVersion(PortAddr iop_base, ushort bus_type)
8022 if ((bus_type & ASC_IS_EISA) != 0) {
8023 PortAddr eisa_iop;
8024 uchar revision;
8025 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8026 (PortAddr) ASC_EISA_REV_IOP_MASK;
8027 revision = inp(eisa_iop);
8028 return ((uchar)((ASC_CHIP_MIN_VER_EISA - 1) + revision));
8030 return (AscGetChipVerNo(iop_base));
8033 static ushort __devinit AscGetChipBusType(PortAddr iop_base)
8035 ushort chip_ver;
8037 chip_ver = AscGetChipVerNo(iop_base);
8038 if ((chip_ver >= ASC_CHIP_MIN_VER_VL)
8039 && (chip_ver <= ASC_CHIP_MAX_VER_VL)
8041 if (((iop_base & 0x0C30) == 0x0C30)
8042 || ((iop_base & 0x0C50) == 0x0C50)
8044 return (ASC_IS_EISA);
8046 return (ASC_IS_VL);
8048 if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
8049 (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
8050 if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
8051 return (ASC_IS_ISAPNP);
8053 return (ASC_IS_ISA);
8054 } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
8055 (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
8056 return (ASC_IS_PCI);
8058 return (0);
8061 static ASC_DCNT
8062 AscLoadMicroCode(PortAddr iop_base,
8063 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
8065 ASC_DCNT chksum;
8066 ushort mcode_word_size;
8067 ushort mcode_chksum;
8069 /* Write the microcode buffer starting at LRAM address 0. */
8070 mcode_word_size = (ushort)(mcode_size >> 1);
8071 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
8072 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
8074 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
8075 ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum);
8076 mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
8077 (ushort)ASC_CODE_SEC_BEG,
8078 (ushort)((mcode_size -
8079 s_addr - (ushort)
8080 ASC_CODE_SEC_BEG) /
8081 2));
8082 ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
8083 (ulong)mcode_chksum);
8084 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
8085 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
8086 return (chksum);
8089 static int AscFindSignature(PortAddr iop_base)
8091 ushort sig_word;
8093 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
8094 iop_base, AscGetChipSignatureByte(iop_base));
8095 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
8096 ASC_DBG2(1,
8097 "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
8098 iop_base, AscGetChipSignatureWord(iop_base));
8099 sig_word = AscGetChipSignatureWord(iop_base);
8100 if ((sig_word == (ushort)ASC_1000_ID0W) ||
8101 (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
8102 return (1);
8105 return (0);
8108 static void __devinit AscToggleIRQAct(PortAddr iop_base)
8110 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
8111 AscSetChipStatus(iop_base, 0);
8112 return;
8115 static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
8117 ushort cfg_lsw;
8118 uchar chip_irq;
8120 if ((bus_type & ASC_IS_EISA) != 0) {
8121 cfg_lsw = AscGetEisaChipCfg(iop_base);
8122 chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10);
8123 if ((chip_irq == 13) || (chip_irq > 15)) {
8124 return (0);
8126 return (chip_irq);
8128 if ((bus_type & ASC_IS_VL) != 0) {
8129 cfg_lsw = AscGetChipCfgLsw(iop_base);
8130 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07));
8131 if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) {
8132 return (0);
8134 return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1)));
8136 cfg_lsw = AscGetChipCfgLsw(iop_base);
8137 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03));
8138 if (chip_irq == 3)
8139 chip_irq += (uchar)2;
8140 return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
8143 static uchar __devinit
8144 AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
8146 ushort cfg_lsw;
8148 if ((bus_type & ASC_IS_VL) != 0) {
8149 if (irq_no != 0) {
8150 if ((irq_no < ASC_MIN_IRQ_NO)
8151 || (irq_no > ASC_MAX_IRQ_NO)) {
8152 irq_no = 0;
8153 } else {
8154 irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1));
8157 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3);
8158 cfg_lsw |= (ushort)0x0010;
8159 AscSetChipCfgLsw(iop_base, cfg_lsw);
8160 AscToggleIRQAct(iop_base);
8161 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0);
8162 cfg_lsw |= (ushort)((irq_no & 0x07) << 2);
8163 AscSetChipCfgLsw(iop_base, cfg_lsw);
8164 AscToggleIRQAct(iop_base);
8165 return (AscGetChipIRQ(iop_base, bus_type));
8167 if ((bus_type & (ASC_IS_ISA)) != 0) {
8168 if (irq_no == 15)
8169 irq_no -= (uchar)2;
8170 irq_no -= (uchar)ASC_MIN_IRQ_NO;
8171 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3);
8172 cfg_lsw |= (ushort)((irq_no & 0x03) << 2);
8173 AscSetChipCfgLsw(iop_base, cfg_lsw);
8174 return (AscGetChipIRQ(iop_base, bus_type));
8176 return (0);
8179 #ifdef CONFIG_ISA
8180 static void __devinit AscEnableIsaDma(uchar dma_channel)
8182 if (dma_channel < 4) {
8183 outp(0x000B, (ushort)(0xC0 | dma_channel));
8184 outp(0x000A, dma_channel);
8185 } else if (dma_channel < 8) {
8186 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
8187 outp(0x00D4, (ushort)(dma_channel - 4));
8189 return;
8191 #endif /* CONFIG_ISA */
8193 static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
8195 EXT_MSG ext_msg;
8196 EXT_MSG out_msg;
8197 ushort halt_q_addr;
8198 int sdtr_accept;
8199 ushort int_halt_code;
8200 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8201 ASC_SCSI_BIT_ID_TYPE target_id;
8202 PortAddr iop_base;
8203 uchar tag_code;
8204 uchar q_status;
8205 uchar halt_qp;
8206 uchar sdtr_data;
8207 uchar target_ix;
8208 uchar q_cntl, tid_no;
8209 uchar cur_dvc_qng;
8210 uchar asyn_sdtr;
8211 uchar scsi_status;
8212 asc_board_t *boardp;
8214 ASC_ASSERT(asc_dvc->drv_ptr != NULL);
8215 boardp = asc_dvc->drv_ptr;
8217 iop_base = asc_dvc->iop_base;
8218 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
8220 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
8221 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
8222 target_ix = AscReadLramByte(iop_base,
8223 (ushort)(halt_q_addr +
8224 (ushort)ASC_SCSIQ_B_TARGET_IX));
8225 q_cntl =
8226 AscReadLramByte(iop_base,
8227 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8228 tid_no = ASC_TIX_TO_TID(target_ix);
8229 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
8230 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8231 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
8232 } else {
8233 asyn_sdtr = 0;
8235 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
8236 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8237 AscSetChipSDTR(iop_base, 0, tid_no);
8238 boardp->sdtr_data[tid_no] = 0;
8240 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8241 return (0);
8242 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
8243 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8244 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8245 boardp->sdtr_data[tid_no] = asyn_sdtr;
8247 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8248 return (0);
8249 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
8251 AscMemWordCopyPtrFromLram(iop_base,
8252 ASCV_MSGIN_BEG,
8253 (uchar *)&ext_msg,
8254 sizeof(EXT_MSG) >> 1);
8256 if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8257 ext_msg.msg_req == EXTENDED_SDTR &&
8258 ext_msg.msg_len == MS_SDTR_LEN) {
8259 sdtr_accept = TRUE;
8260 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
8262 sdtr_accept = FALSE;
8263 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
8265 if ((ext_msg.xfer_period <
8266 asc_dvc->sdtr_period_tbl[asc_dvc->
8267 host_init_sdtr_index])
8268 || (ext_msg.xfer_period >
8269 asc_dvc->sdtr_period_tbl[asc_dvc->
8270 max_sdtr_index])) {
8271 sdtr_accept = FALSE;
8272 ext_msg.xfer_period =
8273 asc_dvc->sdtr_period_tbl[asc_dvc->
8274 host_init_sdtr_index];
8276 if (sdtr_accept) {
8277 sdtr_data =
8278 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
8279 ext_msg.req_ack_offset);
8280 if ((sdtr_data == 0xFF)) {
8282 q_cntl |= QC_MSG_OUT;
8283 asc_dvc->init_sdtr &= ~target_id;
8284 asc_dvc->sdtr_done &= ~target_id;
8285 AscSetChipSDTR(iop_base, asyn_sdtr,
8286 tid_no);
8287 boardp->sdtr_data[tid_no] = asyn_sdtr;
8290 if (ext_msg.req_ack_offset == 0) {
8292 q_cntl &= ~QC_MSG_OUT;
8293 asc_dvc->init_sdtr &= ~target_id;
8294 asc_dvc->sdtr_done &= ~target_id;
8295 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8296 } else {
8297 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
8299 q_cntl &= ~QC_MSG_OUT;
8300 asc_dvc->sdtr_done |= target_id;
8301 asc_dvc->init_sdtr |= target_id;
8302 asc_dvc->pci_fix_asyn_xfer &=
8303 ~target_id;
8304 sdtr_data =
8305 AscCalSDTRData(asc_dvc,
8306 ext_msg.xfer_period,
8307 ext_msg.
8308 req_ack_offset);
8309 AscSetChipSDTR(iop_base, sdtr_data,
8310 tid_no);
8311 boardp->sdtr_data[tid_no] = sdtr_data;
8312 } else {
8314 q_cntl |= QC_MSG_OUT;
8315 AscMsgOutSDTR(asc_dvc,
8316 ext_msg.xfer_period,
8317 ext_msg.req_ack_offset);
8318 asc_dvc->pci_fix_asyn_xfer &=
8319 ~target_id;
8320 sdtr_data =
8321 AscCalSDTRData(asc_dvc,
8322 ext_msg.xfer_period,
8323 ext_msg.
8324 req_ack_offset);
8325 AscSetChipSDTR(iop_base, sdtr_data,
8326 tid_no);
8327 boardp->sdtr_data[tid_no] = sdtr_data;
8328 asc_dvc->sdtr_done |= target_id;
8329 asc_dvc->init_sdtr |= target_id;
8333 AscWriteLramByte(iop_base,
8334 (ushort)(halt_q_addr +
8335 (ushort)ASC_SCSIQ_B_CNTL),
8336 q_cntl);
8337 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8338 return (0);
8339 } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8340 ext_msg.msg_req == EXTENDED_WDTR &&
8341 ext_msg.msg_len == MS_WDTR_LEN) {
8343 ext_msg.wdtr_width = 0;
8344 AscMemWordCopyPtrToLram(iop_base,
8345 ASCV_MSGOUT_BEG,
8346 (uchar *)&ext_msg,
8347 sizeof(EXT_MSG) >> 1);
8348 q_cntl |= QC_MSG_OUT;
8349 AscWriteLramByte(iop_base,
8350 (ushort)(halt_q_addr +
8351 (ushort)ASC_SCSIQ_B_CNTL),
8352 q_cntl);
8353 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8354 return (0);
8355 } else {
8357 ext_msg.msg_type = MESSAGE_REJECT;
8358 AscMemWordCopyPtrToLram(iop_base,
8359 ASCV_MSGOUT_BEG,
8360 (uchar *)&ext_msg,
8361 sizeof(EXT_MSG) >> 1);
8362 q_cntl |= QC_MSG_OUT;
8363 AscWriteLramByte(iop_base,
8364 (ushort)(halt_q_addr +
8365 (ushort)ASC_SCSIQ_B_CNTL),
8366 q_cntl);
8367 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8368 return (0);
8370 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
8372 q_cntl |= QC_REQ_SENSE;
8374 if ((asc_dvc->init_sdtr & target_id) != 0) {
8376 asc_dvc->sdtr_done &= ~target_id;
8378 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8379 q_cntl |= QC_MSG_OUT;
8380 AscMsgOutSDTR(asc_dvc,
8381 asc_dvc->
8382 sdtr_period_tbl[(sdtr_data >> 4) &
8383 (uchar)(asc_dvc->
8384 max_sdtr_index -
8385 1)],
8386 (uchar)(sdtr_data & (uchar)
8387 ASC_SYN_MAX_OFFSET));
8390 AscWriteLramByte(iop_base,
8391 (ushort)(halt_q_addr +
8392 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8394 tag_code = AscReadLramByte(iop_base,
8395 (ushort)(halt_q_addr + (ushort)
8396 ASC_SCSIQ_B_TAG_CODE));
8397 tag_code &= 0xDC;
8398 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
8399 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
8402 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
8403 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
8406 AscWriteLramByte(iop_base,
8407 (ushort)(halt_q_addr +
8408 (ushort)ASC_SCSIQ_B_TAG_CODE),
8409 tag_code);
8411 q_status = AscReadLramByte(iop_base,
8412 (ushort)(halt_q_addr + (ushort)
8413 ASC_SCSIQ_B_STATUS));
8414 q_status |= (QS_READY | QS_BUSY);
8415 AscWriteLramByte(iop_base,
8416 (ushort)(halt_q_addr +
8417 (ushort)ASC_SCSIQ_B_STATUS),
8418 q_status);
8420 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
8421 scsi_busy &= ~target_id;
8422 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8424 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8425 return (0);
8426 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
8428 AscMemWordCopyPtrFromLram(iop_base,
8429 ASCV_MSGOUT_BEG,
8430 (uchar *)&out_msg,
8431 sizeof(EXT_MSG) >> 1);
8433 if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
8434 (out_msg.msg_len == MS_SDTR_LEN) &&
8435 (out_msg.msg_req == EXTENDED_SDTR)) {
8437 asc_dvc->init_sdtr &= ~target_id;
8438 asc_dvc->sdtr_done &= ~target_id;
8439 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8440 boardp->sdtr_data[tid_no] = asyn_sdtr;
8442 q_cntl &= ~QC_MSG_OUT;
8443 AscWriteLramByte(iop_base,
8444 (ushort)(halt_q_addr +
8445 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8446 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8447 return (0);
8448 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
8450 scsi_status = AscReadLramByte(iop_base,
8451 (ushort)((ushort)halt_q_addr +
8452 (ushort)
8453 ASC_SCSIQ_SCSI_STATUS));
8454 cur_dvc_qng =
8455 AscReadLramByte(iop_base,
8456 (ushort)((ushort)ASC_QADR_BEG +
8457 (ushort)target_ix));
8458 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
8460 scsi_busy = AscReadLramByte(iop_base,
8461 (ushort)ASCV_SCSIBUSY_B);
8462 scsi_busy |= target_id;
8463 AscWriteLramByte(iop_base,
8464 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8465 asc_dvc->queue_full_or_busy |= target_id;
8467 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
8468 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
8469 cur_dvc_qng -= 1;
8470 asc_dvc->max_dvc_qng[tid_no] =
8471 cur_dvc_qng;
8473 AscWriteLramByte(iop_base,
8474 (ushort)((ushort)
8475 ASCV_MAX_DVC_QNG_BEG
8476 + (ushort)
8477 tid_no),
8478 cur_dvc_qng);
8481 * Set the device queue depth to the number of
8482 * active requests when the QUEUE FULL condition
8483 * was encountered.
8485 boardp->queue_full |= target_id;
8486 boardp->queue_full_cnt[tid_no] =
8487 cur_dvc_qng;
8491 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8492 return (0);
8494 #if CC_VERY_LONG_SG_LIST
8495 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
8496 uchar q_no;
8497 ushort q_addr;
8498 uchar sg_wk_q_no;
8499 uchar first_sg_wk_q_no;
8500 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
8501 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
8502 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
8503 ushort sg_list_dwords;
8504 ushort sg_entry_cnt;
8505 uchar next_qp;
8506 int i;
8508 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
8509 if (q_no == ASC_QLINK_END) {
8510 return (0);
8513 q_addr = ASC_QNO_TO_QADDR(q_no);
8516 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
8517 * structure pointer using a macro provided by the driver.
8518 * The ASC_SCSI_REQ pointer provides a pointer to the
8519 * host ASC_SG_HEAD structure.
8521 /* Read request's SRB pointer. */
8522 scsiq = (ASC_SCSI_Q *)
8523 ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
8524 (ushort)
8525 (q_addr +
8526 ASC_SCSIQ_D_SRBPTR))));
8529 * Get request's first and working SG queue.
8531 sg_wk_q_no = AscReadLramByte(iop_base,
8532 (ushort)(q_addr +
8533 ASC_SCSIQ_B_SG_WK_QP));
8535 first_sg_wk_q_no = AscReadLramByte(iop_base,
8536 (ushort)(q_addr +
8537 ASC_SCSIQ_B_FIRST_SG_WK_QP));
8540 * Reset request's working SG queue back to the
8541 * first SG queue.
8543 AscWriteLramByte(iop_base,
8544 (ushort)(q_addr +
8545 (ushort)ASC_SCSIQ_B_SG_WK_QP),
8546 first_sg_wk_q_no);
8548 sg_head = scsiq->sg_head;
8551 * Set sg_entry_cnt to the number of SG elements
8552 * that will be completed on this interrupt.
8554 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
8555 * SG elements. The data_cnt and data_addr fields which
8556 * add 1 to the SG element capacity are not used when
8557 * restarting SG handling after a halt.
8559 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
8560 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
8563 * Keep track of remaining number of SG elements that will
8564 * need to be handled on the next interrupt.
8566 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
8567 } else {
8568 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
8569 scsiq->remain_sg_entry_cnt = 0;
8573 * Copy SG elements into the list of allocated SG queues.
8575 * Last index completed is saved in scsiq->next_sg_index.
8577 next_qp = first_sg_wk_q_no;
8578 q_addr = ASC_QNO_TO_QADDR(next_qp);
8579 scsi_sg_q.sg_head_qp = q_no;
8580 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
8581 for (i = 0; i < sg_head->queue_cnt; i++) {
8582 scsi_sg_q.seq_no = i + 1;
8583 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
8584 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
8585 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
8587 * After very first SG queue RISC FW uses next
8588 * SG queue first element then checks sg_list_cnt
8589 * against zero and then decrements, so set
8590 * sg_list_cnt 1 less than number of SG elements
8591 * in each SG queue.
8593 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
8594 scsi_sg_q.sg_cur_list_cnt =
8595 ASC_SG_LIST_PER_Q - 1;
8596 } else {
8598 * This is the last SG queue in the list of
8599 * allocated SG queues. If there are more
8600 * SG elements than will fit in the allocated
8601 * queues, then set the QCSG_SG_XFER_MORE flag.
8603 if (scsiq->remain_sg_entry_cnt != 0) {
8604 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
8605 } else {
8606 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
8608 /* equals sg_entry_cnt * 2 */
8609 sg_list_dwords = sg_entry_cnt << 1;
8610 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
8611 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
8612 sg_entry_cnt = 0;
8615 scsi_sg_q.q_no = next_qp;
8616 AscMemWordCopyPtrToLram(iop_base,
8617 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
8618 (uchar *)&scsi_sg_q,
8619 sizeof(ASC_SG_LIST_Q) >> 1);
8621 AscMemDWordCopyPtrToLram(iop_base,
8622 q_addr + ASC_SGQ_LIST_BEG,
8623 (uchar *)&sg_head->
8624 sg_list[scsiq->next_sg_index],
8625 sg_list_dwords);
8627 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
8630 * If the just completed SG queue contained the
8631 * last SG element, then no more SG queues need
8632 * to be written.
8634 if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
8635 break;
8638 next_qp = AscReadLramByte(iop_base,
8639 (ushort)(q_addr +
8640 ASC_SCSIQ_B_FWD));
8641 q_addr = ASC_QNO_TO_QADDR(next_qp);
8645 * Clear the halt condition so the RISC will be restarted
8646 * after the return.
8648 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8649 return (0);
8651 #endif /* CC_VERY_LONG_SG_LIST */
8652 return (0);
8655 static uchar
8656 _AscCopyLramScsiDoneQ(PortAddr iop_base,
8657 ushort q_addr,
8658 ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
8660 ushort _val;
8661 uchar sg_queue_cnt;
8663 DvcGetQinfo(iop_base,
8664 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
8665 (uchar *)scsiq,
8666 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
8668 _val = AscReadLramWord(iop_base,
8669 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
8670 scsiq->q_status = (uchar)_val;
8671 scsiq->q_no = (uchar)(_val >> 8);
8672 _val = AscReadLramWord(iop_base,
8673 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8674 scsiq->cntl = (uchar)_val;
8675 sg_queue_cnt = (uchar)(_val >> 8);
8676 _val = AscReadLramWord(iop_base,
8677 (ushort)(q_addr +
8678 (ushort)ASC_SCSIQ_B_SENSE_LEN));
8679 scsiq->sense_len = (uchar)_val;
8680 scsiq->extra_bytes = (uchar)(_val >> 8);
8683 * Read high word of remain bytes from alternate location.
8685 scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
8686 (ushort)(q_addr +
8687 (ushort)
8688 ASC_SCSIQ_W_ALT_DC1)))
8689 << 16);
8691 * Read low word of remain bytes from original location.
8693 scsiq->remain_bytes += AscReadLramWord(iop_base,
8694 (ushort)(q_addr + (ushort)
8695 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
8697 scsiq->remain_bytes &= max_dma_count;
8698 return (sg_queue_cnt);
8701 static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
8703 uchar next_qp;
8704 uchar n_q_used;
8705 uchar sg_list_qp;
8706 uchar sg_queue_cnt;
8707 uchar q_cnt;
8708 uchar done_q_tail;
8709 uchar tid_no;
8710 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8711 ASC_SCSI_BIT_ID_TYPE target_id;
8712 PortAddr iop_base;
8713 ushort q_addr;
8714 ushort sg_q_addr;
8715 uchar cur_target_qng;
8716 ASC_QDONE_INFO scsiq_buf;
8717 ASC_QDONE_INFO *scsiq;
8718 int false_overrun;
8719 ASC_ISR_CALLBACK asc_isr_callback;
8721 iop_base = asc_dvc->iop_base;
8722 asc_isr_callback = asc_dvc->isr_callback;
8723 n_q_used = 1;
8724 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
8725 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
8726 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
8727 next_qp = AscReadLramByte(iop_base,
8728 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
8729 if (next_qp != ASC_QLINK_END) {
8730 AscPutVarDoneQTail(iop_base, next_qp);
8731 q_addr = ASC_QNO_TO_QADDR(next_qp);
8732 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
8733 asc_dvc->max_dma_count);
8734 AscWriteLramByte(iop_base,
8735 (ushort)(q_addr +
8736 (ushort)ASC_SCSIQ_B_STATUS),
8737 (uchar)(scsiq->
8738 q_status & (uchar)~(QS_READY |
8739 QS_ABORTED)));
8740 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
8741 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
8742 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
8743 sg_q_addr = q_addr;
8744 sg_list_qp = next_qp;
8745 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
8746 sg_list_qp = AscReadLramByte(iop_base,
8747 (ushort)(sg_q_addr
8748 + (ushort)
8749 ASC_SCSIQ_B_FWD));
8750 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
8751 if (sg_list_qp == ASC_QLINK_END) {
8752 AscSetLibErrorCode(asc_dvc,
8753 ASCQ_ERR_SG_Q_LINKS);
8754 scsiq->d3.done_stat = QD_WITH_ERROR;
8755 scsiq->d3.host_stat =
8756 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
8757 goto FATAL_ERR_QDONE;
8759 AscWriteLramByte(iop_base,
8760 (ushort)(sg_q_addr + (ushort)
8761 ASC_SCSIQ_B_STATUS),
8762 QS_FREE);
8764 n_q_used = sg_queue_cnt + 1;
8765 AscPutVarDoneQTail(iop_base, sg_list_qp);
8767 if (asc_dvc->queue_full_or_busy & target_id) {
8768 cur_target_qng = AscReadLramByte(iop_base,
8769 (ushort)((ushort)
8770 ASC_QADR_BEG
8771 + (ushort)
8772 scsiq->d2.
8773 target_ix));
8774 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
8775 scsi_busy = AscReadLramByte(iop_base, (ushort)
8776 ASCV_SCSIBUSY_B);
8777 scsi_busy &= ~target_id;
8778 AscWriteLramByte(iop_base,
8779 (ushort)ASCV_SCSIBUSY_B,
8780 scsi_busy);
8781 asc_dvc->queue_full_or_busy &= ~target_id;
8784 if (asc_dvc->cur_total_qng >= n_q_used) {
8785 asc_dvc->cur_total_qng -= n_q_used;
8786 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
8787 asc_dvc->cur_dvc_qng[tid_no]--;
8789 } else {
8790 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
8791 scsiq->d3.done_stat = QD_WITH_ERROR;
8792 goto FATAL_ERR_QDONE;
8794 if ((scsiq->d2.srb_ptr == 0UL) ||
8795 ((scsiq->q_status & QS_ABORTED) != 0)) {
8796 return (0x11);
8797 } else if (scsiq->q_status == QS_DONE) {
8798 false_overrun = FALSE;
8799 if (scsiq->extra_bytes != 0) {
8800 scsiq->remain_bytes +=
8801 (ADV_DCNT)scsiq->extra_bytes;
8803 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
8804 if (scsiq->d3.host_stat ==
8805 QHSTA_M_DATA_OVER_RUN) {
8806 if ((scsiq->
8807 cntl & (QC_DATA_IN | QC_DATA_OUT))
8808 == 0) {
8809 scsiq->d3.done_stat =
8810 QD_NO_ERROR;
8811 scsiq->d3.host_stat =
8812 QHSTA_NO_ERROR;
8813 } else if (false_overrun) {
8814 scsiq->d3.done_stat =
8815 QD_NO_ERROR;
8816 scsiq->d3.host_stat =
8817 QHSTA_NO_ERROR;
8819 } else if (scsiq->d3.host_stat ==
8820 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
8821 AscStopChip(iop_base);
8822 AscSetChipControl(iop_base,
8823 (uchar)(CC_SCSI_RESET
8824 | CC_HALT));
8825 DvcDelayNanoSecond(asc_dvc, 60000);
8826 AscSetChipControl(iop_base, CC_HALT);
8827 AscSetChipStatus(iop_base,
8828 CIW_CLR_SCSI_RESET_INT);
8829 AscSetChipStatus(iop_base, 0);
8830 AscSetChipControl(iop_base, 0);
8833 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
8834 (*asc_isr_callback) (asc_dvc, scsiq);
8835 } else {
8836 if ((AscReadLramByte(iop_base,
8837 (ushort)(q_addr + (ushort)
8838 ASC_SCSIQ_CDB_BEG))
8839 == START_STOP)) {
8840 asc_dvc->unit_not_ready &= ~target_id;
8841 if (scsiq->d3.done_stat != QD_NO_ERROR) {
8842 asc_dvc->start_motor &=
8843 ~target_id;
8847 return (1);
8848 } else {
8849 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
8850 FATAL_ERR_QDONE:
8851 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
8852 (*asc_isr_callback) (asc_dvc, scsiq);
8854 return (0x80);
8857 return (0);
8860 static int AscISR(ASC_DVC_VAR *asc_dvc)
8862 ASC_CS_TYPE chipstat;
8863 PortAddr iop_base;
8864 ushort saved_ram_addr;
8865 uchar ctrl_reg;
8866 uchar saved_ctrl_reg;
8867 int int_pending;
8868 int status;
8869 uchar host_flag;
8871 iop_base = asc_dvc->iop_base;
8872 int_pending = FALSE;
8874 if (AscIsIntPending(iop_base) == 0) {
8875 return int_pending;
8878 if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
8879 || (asc_dvc->isr_callback == 0)
8881 return (ERR);
8883 if (asc_dvc->in_critical_cnt != 0) {
8884 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
8885 return (ERR);
8887 if (asc_dvc->is_in_int) {
8888 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
8889 return (ERR);
8891 asc_dvc->is_in_int = TRUE;
8892 ctrl_reg = AscGetChipControl(iop_base);
8893 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
8894 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
8895 chipstat = AscGetChipStatus(iop_base);
8896 if (chipstat & CSW_SCSI_RESET_LATCH) {
8897 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
8898 int i = 10;
8899 int_pending = TRUE;
8900 asc_dvc->sdtr_done = 0;
8901 saved_ctrl_reg &= (uchar)(~CC_HALT);
8902 while ((AscGetChipStatus(iop_base) &
8903 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
8904 DvcSleepMilliSecond(100);
8906 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
8907 AscSetChipControl(iop_base, CC_HALT);
8908 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
8909 AscSetChipStatus(iop_base, 0);
8910 chipstat = AscGetChipStatus(iop_base);
8913 saved_ram_addr = AscGetChipLramAddr(iop_base);
8914 host_flag = AscReadLramByte(iop_base,
8915 ASCV_HOST_FLAG_B) &
8916 (uchar)(~ASC_HOST_FLAG_IN_ISR);
8917 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
8918 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
8919 if ((chipstat & CSW_INT_PENDING)
8920 || (int_pending)
8922 AscAckInterrupt(iop_base);
8923 int_pending = TRUE;
8924 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
8925 if (AscIsrChipHalted(asc_dvc) == ERR) {
8926 goto ISR_REPORT_QDONE_FATAL_ERROR;
8927 } else {
8928 saved_ctrl_reg &= (uchar)(~CC_HALT);
8930 } else {
8931 ISR_REPORT_QDONE_FATAL_ERROR:
8932 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
8933 while (((status =
8934 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
8936 } else {
8937 do {
8938 if ((status =
8939 AscIsrQDone(asc_dvc)) == 1) {
8940 break;
8942 } while (status == 0x11);
8944 if ((status & 0x80) != 0)
8945 int_pending = ERR;
8948 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
8949 AscSetChipLramAddr(iop_base, saved_ram_addr);
8950 AscSetChipControl(iop_base, saved_ctrl_reg);
8951 asc_dvc->is_in_int = FALSE;
8952 return (int_pending);
8955 /* Microcode buffer is kept after initialization for error recovery. */
8956 static uchar _asc_mcode_buf[] = {
8957 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8958 0x00, 0x00, 0x00, 0x00,
8959 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00,
8960 0x00, 0x00, 0x00, 0x00,
8961 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8962 0x00, 0x00, 0x00, 0x00,
8963 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8964 0x00, 0x00, 0x00, 0x00,
8965 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00,
8966 0x00, 0xFF, 0x00, 0x00,
8967 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00,
8968 0x00, 0x00, 0x00, 0x00,
8969 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
8970 0x00, 0x00, 0x00, 0x00,
8971 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88,
8972 0x00, 0x00, 0x00, 0x00,
8973 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73,
8974 0x03, 0x23, 0x36, 0x40,
8975 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
8976 0xC2, 0x00, 0x92, 0x80,
8977 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60,
8978 0xB6, 0x00, 0x92, 0x80,
8979 0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00,
8980 0x92, 0x80, 0x80, 0x62,
8981 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
8982 0xCD, 0x04, 0x4D, 0x00,
8983 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01,
8984 0xE6, 0x84, 0xD2, 0xC1,
8985 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97,
8986 0xC6, 0x81, 0xC2, 0x88,
8987 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
8988 0x84, 0x97, 0x07, 0xA6,
8989 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE,
8990 0xC2, 0x88, 0xCE, 0x00,
8991 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01,
8992 0x80, 0x63, 0x07, 0xA6,
8993 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
8994 0x34, 0x01, 0x00, 0x33,
8995 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23,
8996 0x68, 0x98, 0x4D, 0x04,
8997 0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23,
8998 0xF8, 0x88, 0xFB, 0x23,
8999 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
9000 0x00, 0x33, 0x0A, 0x00,
9001 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00,
9002 0xC2, 0x88, 0xCD, 0x04,
9003 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81,
9004 0x06, 0xAB, 0x82, 0x01,
9005 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
9006 0x3C, 0x01, 0x00, 0x05,
9007 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01,
9008 0x15, 0x23, 0xA1, 0x01,
9009 0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00,
9010 0x06, 0x61, 0x00, 0xA0,
9011 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
9012 0xC2, 0x88, 0x06, 0x23,
9013 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01,
9014 0x57, 0x60, 0x00, 0xA0,
9015 0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73,
9016 0x4B, 0x00, 0x06, 0x61,
9017 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
9018 0x4F, 0x00, 0x84, 0x97,
9019 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97,
9020 0x48, 0x04, 0x84, 0x80,
9021 0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00,
9022 0x81, 0x73, 0x06, 0x29,
9023 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
9024 0x04, 0x98, 0xF0, 0x80,
9025 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6,
9026 0x34, 0x02, 0x03, 0xA6,
9027 0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96,
9028 0x46, 0x82, 0xFE, 0x95,
9029 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
9030 0x07, 0xA6, 0x5A, 0x02,
9031 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95,
9032 0x48, 0x82, 0x60, 0x96,
9033 0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84,
9034 0x04, 0x01, 0x0C, 0xDC,
9035 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
9036 0x6F, 0x00, 0xA5, 0x01,
9037 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01,
9038 0x02, 0xA6, 0xAA, 0x02,
9039 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04,
9040 0x01, 0xA6, 0xB4, 0x02,
9041 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
9042 0x80, 0x63, 0x00, 0x43,
9043 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23,
9044 0x04, 0x61, 0x84, 0x01,
9045 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F,
9046 0x00, 0x00, 0xEA, 0x82,
9047 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
9048 0x00, 0x33, 0x1F, 0x00,
9049 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98,
9050 0xB6, 0x2D, 0x01, 0xA6,
9051 0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6,
9052 0x10, 0x03, 0x03, 0xA6,
9053 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
9054 0x7C, 0x95, 0xEE, 0x82,
9055 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4,
9056 0x04, 0x01, 0x2D, 0xC8,
9057 0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01,
9058 0x05, 0x05, 0x86, 0x98,
9059 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
9060 0x3C, 0x04, 0x06, 0xA6,
9061 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88,
9062 0x7C, 0x95, 0x32, 0x83,
9063 0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05,
9064 0xEB, 0x04, 0x00, 0x33,
9065 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
9066 0xFF, 0xA2, 0x7A, 0x03,
9067 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01,
9068 0x00, 0xA2, 0x9A, 0x03,
9069 0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00,
9070 0x01, 0xA6, 0x96, 0x03,
9071 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
9072 0xA4, 0x03, 0x00, 0xA6,
9073 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03,
9074 0x07, 0xA6, 0xB2, 0x03,
9075 0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88,
9076 0xA8, 0x98, 0x80, 0x42,
9077 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
9078 0xC0, 0x83, 0x00, 0x33,
9079 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23,
9080 0xA0, 0x01, 0x12, 0x23,
9081 0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B,
9082 0x80, 0x67, 0x05, 0x23,
9083 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
9084 0x06, 0xA6, 0x0A, 0x04,
9085 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96,
9086 0xF4, 0x83, 0x20, 0x84,
9087 0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
9088 0x83, 0x03, 0x80, 0x63,
9089 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
9090 0x38, 0x04, 0x00, 0x33,
9091 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84,
9092 0x1D, 0x01, 0x06, 0xCC,
9093 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62,
9094 0xA2, 0x0D, 0x80, 0x63,
9095 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
9096 0x80, 0x63, 0xA3, 0x01,
9097 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0,
9098 0x76, 0x04, 0xE0, 0x00,
9099 0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00,
9100 0x00, 0x33, 0x1E, 0x00,
9101 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
9102 0x08, 0x23, 0x22, 0xA3,
9103 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3,
9104 0xC4, 0x04, 0x42, 0x23,
9105 0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23,
9106 0xF8, 0x88, 0x04, 0x98,
9107 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
9108 0x81, 0x62, 0xE8, 0x81,
9109 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98,
9110 0x00, 0x33, 0x00, 0x81,
9111 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23,
9112 0xF8, 0x88, 0x04, 0x23,
9113 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
9114 0xF4, 0x04, 0x00, 0x33,
9115 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01,
9116 0x04, 0x23, 0xA0, 0x01,
9117 0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00,
9118 0x00, 0xA3, 0x22, 0x05,
9119 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
9120 0x46, 0x97, 0xCD, 0x04,
9121 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23,
9122 0x82, 0x01, 0x34, 0x85,
9123 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05,
9124 0x1D, 0x01, 0x04, 0xD6,
9125 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
9126 0x49, 0x00, 0x81, 0x01,
9127 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01,
9128 0x49, 0x04, 0x80, 0x01,
9129 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04,
9130 0x01, 0x23, 0xEA, 0x00,
9131 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
9132 0x07, 0xA4, 0xF8, 0x05,
9133 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00,
9134 0xC2, 0x88, 0x04, 0xA0,
9135 0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61,
9136 0x00, 0xA2, 0xA4, 0x05,
9137 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
9138 0x62, 0x97, 0x04, 0x85,
9139 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05,
9140 0xF4, 0x85, 0x03, 0xA0,
9141 0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63,
9142 0xCC, 0x86, 0x07, 0xA0,
9143 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
9144 0x80, 0x67, 0x80, 0x63,
9145 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23,
9146 0xF8, 0x88, 0x07, 0x23,
9147 0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00,
9148 0x00, 0x63, 0x4A, 0x00,
9149 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
9150 0x07, 0x41, 0x83, 0x03,
9151 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88,
9152 0x1D, 0x01, 0x01, 0xD6,
9153 0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00,
9154 0x07, 0xA6, 0x7C, 0x05,
9155 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
9156 0x52, 0x00, 0x06, 0x61,
9157 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41,
9158 0x00, 0x63, 0x1D, 0x01,
9159 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23,
9160 0x07, 0x41, 0x00, 0x63,
9161 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
9162 0xDF, 0x00, 0x06, 0xA6,
9163 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33,
9164 0x00, 0x40, 0xC0, 0x20,
9165 0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63,
9166 0x06, 0xA6, 0x94, 0x06,
9167 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
9168 0x40, 0x0E, 0x80, 0x63,
9169 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E,
9170 0x80, 0x63, 0x00, 0x43,
9171 0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05,
9172 0x80, 0x67, 0x40, 0x0E,
9173 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
9174 0x07, 0xA6, 0xD6, 0x06,
9175 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00,
9176 0x0A, 0x2B, 0x07, 0xA6,
9177 0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2,
9178 0xF4, 0x06, 0xC0, 0x0E,
9179 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
9180 0x81, 0x62, 0x04, 0x01,
9181 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6,
9182 0x8C, 0x06, 0x00, 0x33,
9183 0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03,
9184 0x80, 0x63, 0x06, 0xA6,
9185 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
9186 0x00, 0x00, 0x80, 0x67,
9187 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05,
9188 0xBF, 0x23, 0x04, 0x61,
9189 0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00,
9190 0x00, 0x01, 0xF2, 0x00,
9191 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
9192 0x80, 0x05, 0x81, 0x05,
9193 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00,
9194 0x70, 0x00, 0x81, 0x01,
9195 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04,
9196 0x70, 0x00, 0x80, 0x01,
9197 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
9198 0xF1, 0x00, 0x70, 0x00,
9199 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01,
9200 0x71, 0x04, 0x70, 0x00,
9201 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05,
9202 0xA3, 0x01, 0xA2, 0x01,
9203 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
9204 0xC4, 0x07, 0x00, 0x33,
9205 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8,
9206 0x48, 0x00, 0xB0, 0x01,
9207 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43,
9208 0x00, 0xA2, 0xE4, 0x07,
9209 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
9210 0x05, 0x05, 0x00, 0x63,
9211 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43,
9212 0x76, 0x08, 0x80, 0x02,
9213 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
9214 0x00, 0x02, 0x00, 0xA0,
9215 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
9216 0x00, 0x63, 0xF3, 0x04,
9217 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40,
9218 0x00, 0xA2, 0x44, 0x08,
9219 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1,
9220 0x24, 0x08, 0x04, 0x98,
9221 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
9222 0x5A, 0x88, 0x02, 0x01,
9223 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00,
9224 0x00, 0xA3, 0x64, 0x08,
9225 0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63,
9226 0x06, 0xA6, 0x76, 0x08,
9227 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
9228 0x00, 0x63, 0x38, 0x2B,
9229 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98,
9230 0x05, 0x05, 0xB2, 0x09,
9231 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63,
9232 0x80, 0x32, 0x80, 0x36,
9233 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
9234 0x40, 0x36, 0x40, 0x3A,
9235 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08,
9236 0x5D, 0x00, 0xFE, 0xC3,
9237 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73,
9238 0xFF, 0xFD, 0x80, 0x73,
9239 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
9240 0xA1, 0x23, 0xA1, 0x01,
9241 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2,
9242 0x80, 0x00, 0x03, 0xC2,
9243 0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23,
9244 0xA0, 0x01, 0xE6, 0x84,
9247 static ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
9248 static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
9250 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
9251 static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
9252 INQUIRY,
9253 REQUEST_SENSE,
9254 READ_CAPACITY,
9255 READ_TOC,
9256 MODE_SELECT,
9257 MODE_SENSE,
9258 MODE_SELECT_10,
9259 MODE_SENSE_10,
9260 0xFF,
9261 0xFF,
9262 0xFF,
9263 0xFF,
9264 0xFF,
9265 0xFF,
9266 0xFF,
9267 0xFF
9270 static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
9272 PortAddr iop_base;
9273 ulong last_int_level;
9274 int sta;
9275 int n_q_required;
9276 int disable_syn_offset_one_fix;
9277 int i;
9278 ASC_PADDR addr;
9279 ASC_EXE_CALLBACK asc_exe_callback;
9280 ushort sg_entry_cnt = 0;
9281 ushort sg_entry_cnt_minus_one = 0;
9282 uchar target_ix;
9283 uchar tid_no;
9284 uchar sdtr_data;
9285 uchar extra_bytes;
9286 uchar scsi_cmd;
9287 uchar disable_cmd;
9288 ASC_SG_HEAD *sg_head;
9289 ASC_DCNT data_cnt;
9291 iop_base = asc_dvc->iop_base;
9292 sg_head = scsiq->sg_head;
9293 asc_exe_callback = asc_dvc->exe_callback;
9294 if (asc_dvc->err_code != 0)
9295 return (ERR);
9296 if (scsiq == (ASC_SCSI_Q *)0L) {
9297 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
9298 return (ERR);
9300 scsiq->q1.q_no = 0;
9301 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
9302 scsiq->q1.extra_bytes = 0;
9304 sta = 0;
9305 target_ix = scsiq->q2.target_ix;
9306 tid_no = ASC_TIX_TO_TID(target_ix);
9307 n_q_required = 1;
9308 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
9309 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
9310 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
9311 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9312 AscMsgOutSDTR(asc_dvc,
9313 asc_dvc->
9314 sdtr_period_tbl[(sdtr_data >> 4) &
9315 (uchar)(asc_dvc->
9316 max_sdtr_index -
9317 1)],
9318 (uchar)(sdtr_data & (uchar)
9319 ASC_SYN_MAX_OFFSET));
9320 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
9323 last_int_level = DvcEnterCritical();
9324 if (asc_dvc->in_critical_cnt != 0) {
9325 DvcLeaveCritical(last_int_level);
9326 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
9327 return (ERR);
9329 asc_dvc->in_critical_cnt++;
9330 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9331 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
9332 asc_dvc->in_critical_cnt--;
9333 DvcLeaveCritical(last_int_level);
9334 return (ERR);
9336 #if !CC_VERY_LONG_SG_LIST
9337 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9338 asc_dvc->in_critical_cnt--;
9339 DvcLeaveCritical(last_int_level);
9340 return (ERR);
9342 #endif /* !CC_VERY_LONG_SG_LIST */
9343 if (sg_entry_cnt == 1) {
9344 scsiq->q1.data_addr =
9345 (ADV_PADDR)sg_head->sg_list[0].addr;
9346 scsiq->q1.data_cnt =
9347 (ADV_DCNT)sg_head->sg_list[0].bytes;
9348 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
9350 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
9352 scsi_cmd = scsiq->cdbptr[0];
9353 disable_syn_offset_one_fix = FALSE;
9354 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
9355 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
9356 if (scsiq->q1.cntl & QC_SG_HEAD) {
9357 data_cnt = 0;
9358 for (i = 0; i < sg_entry_cnt; i++) {
9359 data_cnt +=
9360 (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
9361 bytes);
9363 } else {
9364 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
9366 if (data_cnt != 0UL) {
9367 if (data_cnt < 512UL) {
9368 disable_syn_offset_one_fix = TRUE;
9369 } else {
9370 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
9371 i++) {
9372 disable_cmd =
9373 _syn_offset_one_disable_cmd[i];
9374 if (disable_cmd == 0xFF) {
9375 break;
9377 if (scsi_cmd == disable_cmd) {
9378 disable_syn_offset_one_fix =
9379 TRUE;
9380 break;
9386 if (disable_syn_offset_one_fix) {
9387 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9388 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
9389 ASC_TAG_FLAG_DISABLE_DISCONNECT);
9390 } else {
9391 scsiq->q2.tag_code &= 0x27;
9393 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9394 if (asc_dvc->bug_fix_cntl) {
9395 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9396 if ((scsi_cmd == READ_6) ||
9397 (scsi_cmd == READ_10)) {
9398 addr =
9399 (ADV_PADDR)le32_to_cpu(sg_head->
9400 sg_list
9401 [sg_entry_cnt_minus_one].
9402 addr) +
9403 (ADV_DCNT)le32_to_cpu(sg_head->
9404 sg_list
9405 [sg_entry_cnt_minus_one].
9406 bytes);
9407 extra_bytes =
9408 (uchar)((ushort)addr & 0x0003);
9409 if ((extra_bytes != 0)
9411 ((scsiq->q2.
9412 tag_code &
9413 ASC_TAG_FLAG_EXTRA_BYTES)
9414 == 0)) {
9415 scsiq->q2.tag_code |=
9416 ASC_TAG_FLAG_EXTRA_BYTES;
9417 scsiq->q1.extra_bytes =
9418 extra_bytes;
9419 data_cnt =
9420 le32_to_cpu(sg_head->
9421 sg_list
9422 [sg_entry_cnt_minus_one].
9423 bytes);
9424 data_cnt -=
9425 (ASC_DCNT) extra_bytes;
9426 sg_head->
9427 sg_list
9428 [sg_entry_cnt_minus_one].
9429 bytes =
9430 cpu_to_le32(data_cnt);
9435 sg_head->entry_to_copy = sg_head->entry_cnt;
9436 #if CC_VERY_LONG_SG_LIST
9438 * Set the sg_entry_cnt to the maximum possible. The rest of
9439 * the SG elements will be copied when the RISC completes the
9440 * SG elements that fit and halts.
9442 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9443 sg_entry_cnt = ASC_MAX_SG_LIST;
9445 #endif /* CC_VERY_LONG_SG_LIST */
9446 n_q_required = AscSgListToQueue(sg_entry_cnt);
9447 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
9448 (uint) n_q_required)
9449 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9450 if ((sta =
9451 AscSendScsiQueue(asc_dvc, scsiq,
9452 n_q_required)) == 1) {
9453 asc_dvc->in_critical_cnt--;
9454 if (asc_exe_callback != 0) {
9455 (*asc_exe_callback) (asc_dvc, scsiq);
9457 DvcLeaveCritical(last_int_level);
9458 return (sta);
9461 } else {
9462 if (asc_dvc->bug_fix_cntl) {
9463 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9464 if ((scsi_cmd == READ_6) ||
9465 (scsi_cmd == READ_10)) {
9466 addr =
9467 le32_to_cpu(scsiq->q1.data_addr) +
9468 le32_to_cpu(scsiq->q1.data_cnt);
9469 extra_bytes =
9470 (uchar)((ushort)addr & 0x0003);
9471 if ((extra_bytes != 0)
9473 ((scsiq->q2.
9474 tag_code &
9475 ASC_TAG_FLAG_EXTRA_BYTES)
9476 == 0)) {
9477 data_cnt =
9478 le32_to_cpu(scsiq->q1.
9479 data_cnt);
9480 if (((ushort)data_cnt & 0x01FF)
9481 == 0) {
9482 scsiq->q2.tag_code |=
9483 ASC_TAG_FLAG_EXTRA_BYTES;
9484 data_cnt -= (ASC_DCNT)
9485 extra_bytes;
9486 scsiq->q1.data_cnt =
9487 cpu_to_le32
9488 (data_cnt);
9489 scsiq->q1.extra_bytes =
9490 extra_bytes;
9496 n_q_required = 1;
9497 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
9498 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9499 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
9500 n_q_required)) == 1) {
9501 asc_dvc->in_critical_cnt--;
9502 if (asc_exe_callback != 0) {
9503 (*asc_exe_callback) (asc_dvc, scsiq);
9505 DvcLeaveCritical(last_int_level);
9506 return (sta);
9510 asc_dvc->in_critical_cnt--;
9511 DvcLeaveCritical(last_int_level);
9512 return (sta);
9515 static int
9516 AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
9518 PortAddr iop_base;
9519 uchar free_q_head;
9520 uchar next_qp;
9521 uchar tid_no;
9522 uchar target_ix;
9523 int sta;
9525 iop_base = asc_dvc->iop_base;
9526 target_ix = scsiq->q2.target_ix;
9527 tid_no = ASC_TIX_TO_TID(target_ix);
9528 sta = 0;
9529 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
9530 if (n_q_required > 1) {
9531 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
9532 free_q_head, (uchar)
9533 (n_q_required)))
9534 != (uchar)ASC_QLINK_END) {
9535 asc_dvc->last_q_shortage = 0;
9536 scsiq->sg_head->queue_cnt = n_q_required - 1;
9537 scsiq->q1.q_no = free_q_head;
9538 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
9539 free_q_head)) == 1) {
9540 AscPutVarFreeQHead(iop_base, next_qp);
9541 asc_dvc->cur_total_qng += (uchar)(n_q_required);
9542 asc_dvc->cur_dvc_qng[tid_no]++;
9544 return (sta);
9546 } else if (n_q_required == 1) {
9547 if ((next_qp = AscAllocFreeQueue(iop_base,
9548 free_q_head)) !=
9549 ASC_QLINK_END) {
9550 scsiq->q1.q_no = free_q_head;
9551 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
9552 free_q_head)) == 1) {
9553 AscPutVarFreeQHead(iop_base, next_qp);
9554 asc_dvc->cur_total_qng++;
9555 asc_dvc->cur_dvc_qng[tid_no]++;
9557 return (sta);
9560 return (sta);
9563 static int AscSgListToQueue(int sg_list)
9565 int n_sg_list_qs;
9567 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
9568 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
9569 n_sg_list_qs++;
9570 return (n_sg_list_qs + 1);
9573 static uint
9574 AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
9576 uint cur_used_qs;
9577 uint cur_free_qs;
9578 ASC_SCSI_BIT_ID_TYPE target_id;
9579 uchar tid_no;
9581 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
9582 tid_no = ASC_TIX_TO_TID(target_ix);
9583 if ((asc_dvc->unit_not_ready & target_id) ||
9584 (asc_dvc->queue_full_or_busy & target_id)) {
9585 return (0);
9587 if (n_qs == 1) {
9588 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9589 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
9590 } else {
9591 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9592 (uint) ASC_MIN_FREE_Q;
9594 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
9595 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
9596 if (asc_dvc->cur_dvc_qng[tid_no] >=
9597 asc_dvc->max_dvc_qng[tid_no]) {
9598 return (0);
9600 return (cur_free_qs);
9602 if (n_qs > 1) {
9603 if ((n_qs > asc_dvc->last_q_shortage)
9604 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
9605 asc_dvc->last_q_shortage = n_qs;
9608 return (0);
9611 static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
9613 ushort q_addr;
9614 uchar tid_no;
9615 uchar sdtr_data;
9616 uchar syn_period_ix;
9617 uchar syn_offset;
9618 PortAddr iop_base;
9620 iop_base = asc_dvc->iop_base;
9621 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
9622 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
9623 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
9624 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9625 syn_period_ix =
9626 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
9627 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
9628 AscMsgOutSDTR(asc_dvc,
9629 asc_dvc->sdtr_period_tbl[syn_period_ix],
9630 syn_offset);
9631 scsiq->q1.cntl |= QC_MSG_OUT;
9633 q_addr = ASC_QNO_TO_QADDR(q_no);
9634 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
9635 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9637 scsiq->q1.status = QS_FREE;
9638 AscMemWordCopyPtrToLram(iop_base,
9639 q_addr + ASC_SCSIQ_CDB_BEG,
9640 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
9642 DvcPutScsiQ(iop_base,
9643 q_addr + ASC_SCSIQ_CPY_BEG,
9644 (uchar *)&scsiq->q1.cntl,
9645 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
9646 AscWriteLramWord(iop_base,
9647 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
9648 (ushort)(((ushort)scsiq->q1.
9649 q_no << 8) | (ushort)QS_READY));
9650 return (1);
9653 static int
9654 AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
9656 int sta;
9657 int i;
9658 ASC_SG_HEAD *sg_head;
9659 ASC_SG_LIST_Q scsi_sg_q;
9660 ASC_DCNT saved_data_addr;
9661 ASC_DCNT saved_data_cnt;
9662 PortAddr iop_base;
9663 ushort sg_list_dwords;
9664 ushort sg_index;
9665 ushort sg_entry_cnt;
9666 ushort q_addr;
9667 uchar next_qp;
9669 iop_base = asc_dvc->iop_base;
9670 sg_head = scsiq->sg_head;
9671 saved_data_addr = scsiq->q1.data_addr;
9672 saved_data_cnt = scsiq->q1.data_cnt;
9673 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
9674 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
9675 #if CC_VERY_LONG_SG_LIST
9677 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
9678 * then not all SG elements will fit in the allocated queues.
9679 * The rest of the SG elements will be copied when the RISC
9680 * completes the SG elements that fit and halts.
9682 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9684 * Set sg_entry_cnt to be the number of SG elements that
9685 * will fit in the allocated SG queues. It is minus 1, because
9686 * the first SG element is handled above. ASC_MAX_SG_LIST is
9687 * already inflated by 1 to account for this. For example it
9688 * may be 50 which is 1 + 7 queues * 7 SG elements.
9690 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
9693 * Keep track of remaining number of SG elements that will
9694 * need to be handled from a_isr.c.
9696 scsiq->remain_sg_entry_cnt =
9697 sg_head->entry_cnt - ASC_MAX_SG_LIST;
9698 } else {
9699 #endif /* CC_VERY_LONG_SG_LIST */
9701 * Set sg_entry_cnt to be the number of SG elements that
9702 * will fit in the allocated SG queues. It is minus 1, because
9703 * the first SG element is handled above.
9705 sg_entry_cnt = sg_head->entry_cnt - 1;
9706 #if CC_VERY_LONG_SG_LIST
9708 #endif /* CC_VERY_LONG_SG_LIST */
9709 if (sg_entry_cnt != 0) {
9710 scsiq->q1.cntl |= QC_SG_HEAD;
9711 q_addr = ASC_QNO_TO_QADDR(q_no);
9712 sg_index = 1;
9713 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
9714 scsi_sg_q.sg_head_qp = q_no;
9715 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
9716 for (i = 0; i < sg_head->queue_cnt; i++) {
9717 scsi_sg_q.seq_no = i + 1;
9718 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
9719 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
9720 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
9721 if (i == 0) {
9722 scsi_sg_q.sg_list_cnt =
9723 ASC_SG_LIST_PER_Q;
9724 scsi_sg_q.sg_cur_list_cnt =
9725 ASC_SG_LIST_PER_Q;
9726 } else {
9727 scsi_sg_q.sg_list_cnt =
9728 ASC_SG_LIST_PER_Q - 1;
9729 scsi_sg_q.sg_cur_list_cnt =
9730 ASC_SG_LIST_PER_Q - 1;
9732 } else {
9733 #if CC_VERY_LONG_SG_LIST
9735 * This is the last SG queue in the list of
9736 * allocated SG queues. If there are more
9737 * SG elements than will fit in the allocated
9738 * queues, then set the QCSG_SG_XFER_MORE flag.
9740 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9741 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
9742 } else {
9743 #endif /* CC_VERY_LONG_SG_LIST */
9744 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
9745 #if CC_VERY_LONG_SG_LIST
9747 #endif /* CC_VERY_LONG_SG_LIST */
9748 sg_list_dwords = sg_entry_cnt << 1;
9749 if (i == 0) {
9750 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
9751 scsi_sg_q.sg_cur_list_cnt =
9752 sg_entry_cnt;
9753 } else {
9754 scsi_sg_q.sg_list_cnt =
9755 sg_entry_cnt - 1;
9756 scsi_sg_q.sg_cur_list_cnt =
9757 sg_entry_cnt - 1;
9759 sg_entry_cnt = 0;
9761 next_qp = AscReadLramByte(iop_base,
9762 (ushort)(q_addr +
9763 ASC_SCSIQ_B_FWD));
9764 scsi_sg_q.q_no = next_qp;
9765 q_addr = ASC_QNO_TO_QADDR(next_qp);
9766 AscMemWordCopyPtrToLram(iop_base,
9767 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
9768 (uchar *)&scsi_sg_q,
9769 sizeof(ASC_SG_LIST_Q) >> 1);
9770 AscMemDWordCopyPtrToLram(iop_base,
9771 q_addr + ASC_SGQ_LIST_BEG,
9772 (uchar *)&sg_head->
9773 sg_list[sg_index],
9774 sg_list_dwords);
9775 sg_index += ASC_SG_LIST_PER_Q;
9776 scsiq->next_sg_index = sg_index;
9778 } else {
9779 scsiq->q1.cntl &= ~QC_SG_HEAD;
9781 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
9782 scsiq->q1.data_addr = saved_data_addr;
9783 scsiq->q1.data_cnt = saved_data_cnt;
9784 return (sta);
9787 static int
9788 AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
9790 int sta = FALSE;
9792 if (AscHostReqRiscHalt(iop_base)) {
9793 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9794 AscStartChip(iop_base);
9795 return (sta);
9797 return (sta);
9800 static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
9802 ASC_SCSI_BIT_ID_TYPE org_id;
9803 int i;
9804 int sta = TRUE;
9806 AscSetBank(iop_base, 1);
9807 org_id = AscReadChipDvcID(iop_base);
9808 for (i = 0; i <= ASC_MAX_TID; i++) {
9809 if (org_id == (0x01 << i))
9810 break;
9812 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
9813 AscWriteChipDvcID(iop_base, id);
9814 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
9815 AscSetBank(iop_base, 0);
9816 AscSetChipSyn(iop_base, sdtr_data);
9817 if (AscGetChipSyn(iop_base) != sdtr_data) {
9818 sta = FALSE;
9820 } else {
9821 sta = FALSE;
9823 AscSetBank(iop_base, 1);
9824 AscWriteChipDvcID(iop_base, org_id);
9825 AscSetBank(iop_base, 0);
9826 return (sta);
9829 static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
9831 uchar i;
9832 ushort s_addr;
9833 PortAddr iop_base;
9834 ushort warn_code;
9836 iop_base = asc_dvc->iop_base;
9837 warn_code = 0;
9838 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
9839 (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
9840 64) >> 1)
9842 i = ASC_MIN_ACTIVE_QNO;
9843 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
9844 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9845 (uchar)(i + 1));
9846 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9847 (uchar)(asc_dvc->max_total_qng));
9848 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9849 (uchar)i);
9850 i++;
9851 s_addr += ASC_QBLK_SIZE;
9852 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
9853 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9854 (uchar)(i + 1));
9855 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9856 (uchar)(i - 1));
9857 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9858 (uchar)i);
9860 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9861 (uchar)ASC_QLINK_END);
9862 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9863 (uchar)(asc_dvc->max_total_qng - 1));
9864 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9865 (uchar)asc_dvc->max_total_qng);
9866 i++;
9867 s_addr += ASC_QBLK_SIZE;
9868 for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
9869 i++, s_addr += ASC_QBLK_SIZE) {
9870 AscWriteLramByte(iop_base,
9871 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
9872 AscWriteLramByte(iop_base,
9873 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
9874 AscWriteLramByte(iop_base,
9875 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
9877 return (warn_code);
9880 static ushort AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
9882 PortAddr iop_base;
9883 int i;
9884 ushort lram_addr;
9886 iop_base = asc_dvc->iop_base;
9887 AscPutRiscVarFreeQHead(iop_base, 1);
9888 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
9889 AscPutVarFreeQHead(iop_base, 1);
9890 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
9891 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
9892 (uchar)((int)asc_dvc->max_total_qng + 1));
9893 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
9894 (uchar)((int)asc_dvc->max_total_qng + 2));
9895 AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
9896 asc_dvc->max_total_qng);
9897 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
9898 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9899 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
9900 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
9901 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
9902 AscPutQDoneInProgress(iop_base, 0);
9903 lram_addr = ASC_QADR_BEG;
9904 for (i = 0; i < 32; i++, lram_addr += 2) {
9905 AscWriteLramWord(iop_base, lram_addr, 0);
9907 return (0);
9910 static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
9912 if (asc_dvc->err_code == 0) {
9913 asc_dvc->err_code = err_code;
9914 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
9915 err_code);
9917 return (err_code);
9920 static uchar
9921 AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
9923 EXT_MSG sdtr_buf;
9924 uchar sdtr_period_index;
9925 PortAddr iop_base;
9927 iop_base = asc_dvc->iop_base;
9928 sdtr_buf.msg_type = EXTENDED_MESSAGE;
9929 sdtr_buf.msg_len = MS_SDTR_LEN;
9930 sdtr_buf.msg_req = EXTENDED_SDTR;
9931 sdtr_buf.xfer_period = sdtr_period;
9932 sdtr_offset &= ASC_SYN_MAX_OFFSET;
9933 sdtr_buf.req_ack_offset = sdtr_offset;
9934 if ((sdtr_period_index =
9935 AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
9936 asc_dvc->max_sdtr_index) {
9937 AscMemWordCopyPtrToLram(iop_base,
9938 ASCV_MSGOUT_BEG,
9939 (uchar *)&sdtr_buf,
9940 sizeof(EXT_MSG) >> 1);
9941 return ((sdtr_period_index << 4) | sdtr_offset);
9942 } else {
9944 sdtr_buf.req_ack_offset = 0;
9945 AscMemWordCopyPtrToLram(iop_base,
9946 ASCV_MSGOUT_BEG,
9947 (uchar *)&sdtr_buf,
9948 sizeof(EXT_MSG) >> 1);
9949 return (0);
9953 static uchar
9954 AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
9956 uchar byte;
9957 uchar sdtr_period_ix;
9959 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
9960 if ((sdtr_period_ix > asc_dvc->max_sdtr_index)
9962 return (0xFF);
9964 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
9965 return (byte);
9968 static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
9970 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9971 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
9972 return;
9975 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
9977 uchar *period_table;
9978 int max_index;
9979 int min_index;
9980 int i;
9982 period_table = asc_dvc->sdtr_period_tbl;
9983 max_index = (int)asc_dvc->max_sdtr_index;
9984 min_index = (int)asc_dvc->host_init_sdtr_index;
9985 if ((syn_time <= period_table[max_index])) {
9986 for (i = min_index; i < (max_index - 1); i++) {
9987 if (syn_time <= period_table[i]) {
9988 return ((uchar)i);
9991 return ((uchar)max_index);
9992 } else {
9993 return ((uchar)(max_index + 1));
9997 static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
9999 ushort q_addr;
10000 uchar next_qp;
10001 uchar q_status;
10003 q_addr = ASC_QNO_TO_QADDR(free_q_head);
10004 q_status = (uchar)AscReadLramByte(iop_base,
10005 (ushort)(q_addr +
10006 ASC_SCSIQ_B_STATUS));
10007 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
10008 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
10009 return (next_qp);
10011 return (ASC_QLINK_END);
10014 static uchar
10015 AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
10017 uchar i;
10019 for (i = 0; i < n_free_q; i++) {
10020 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
10021 == ASC_QLINK_END) {
10022 return (ASC_QLINK_END);
10025 return (free_q_head);
10028 static int AscHostReqRiscHalt(PortAddr iop_base)
10030 int count = 0;
10031 int sta = 0;
10032 uchar saved_stop_code;
10034 if (AscIsChipHalted(iop_base))
10035 return (1);
10036 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
10037 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
10038 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
10039 do {
10040 if (AscIsChipHalted(iop_base)) {
10041 sta = 1;
10042 break;
10044 DvcSleepMilliSecond(100);
10045 } while (count++ < 20);
10046 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
10047 return (sta);
10050 static int AscStopQueueExe(PortAddr iop_base)
10052 int count = 0;
10054 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
10055 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
10056 ASC_STOP_REQ_RISC_STOP);
10057 do {
10058 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
10059 ASC_STOP_ACK_RISC_STOP) {
10060 return (1);
10062 DvcSleepMilliSecond(100);
10063 } while (count++ < 20);
10065 return (0);
10068 static void DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
10070 udelay(micro_sec);
10073 static void DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
10075 udelay((nano_sec + 999) / 1000);
10078 static int AscStartChip(PortAddr iop_base)
10080 AscSetChipControl(iop_base, 0);
10081 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
10082 return (0);
10084 return (1);
10087 static int AscStopChip(PortAddr iop_base)
10089 uchar cc_val;
10091 cc_val =
10092 AscGetChipControl(iop_base) &
10093 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
10094 AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
10095 AscSetChipIH(iop_base, INS_HALT);
10096 AscSetChipIH(iop_base, INS_RFLAG_WTM);
10097 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
10098 return (0);
10100 return (1);
10103 static int AscIsChipHalted(PortAddr iop_base)
10105 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
10106 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
10107 return (1);
10110 return (0);
10113 static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
10115 AscSetBank(iop_base, 1);
10116 AscWriteChipIH(iop_base, ins_code);
10117 AscSetBank(iop_base, 0);
10118 return;
10121 static void AscAckInterrupt(PortAddr iop_base)
10123 uchar host_flag;
10124 uchar risc_flag;
10125 ushort loop;
10127 loop = 0;
10128 do {
10129 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
10130 if (loop++ > 0x7FFF) {
10131 break;
10133 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
10134 host_flag =
10135 AscReadLramByte(iop_base,
10136 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
10137 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10138 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
10139 AscSetChipStatus(iop_base, CIW_INT_ACK);
10140 loop = 0;
10141 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
10142 AscSetChipStatus(iop_base, CIW_INT_ACK);
10143 if (loop++ > 3) {
10144 break;
10147 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10148 return;
10151 static void AscDisableInterrupt(PortAddr iop_base)
10153 ushort cfg;
10155 cfg = AscGetChipCfgLsw(iop_base);
10156 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
10157 return;
10160 static void AscEnableInterrupt(PortAddr iop_base)
10162 ushort cfg;
10164 cfg = AscGetChipCfgLsw(iop_base);
10165 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
10166 return;
10169 static void AscSetBank(PortAddr iop_base, uchar bank)
10171 uchar val;
10173 val = AscGetChipControl(iop_base) &
10175 (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
10176 CC_CHIP_RESET));
10177 if (bank == 1) {
10178 val |= CC_BANK_ONE;
10179 } else if (bank == 2) {
10180 val |= CC_DIAG | CC_BANK_ONE;
10181 } else {
10182 val &= ~CC_BANK_ONE;
10184 AscSetChipControl(iop_base, val);
10185 return;
10188 static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
10190 PortAddr iop_base;
10191 int i = 10;
10193 iop_base = asc_dvc->iop_base;
10194 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
10195 && (i-- > 0)) {
10196 DvcSleepMilliSecond(100);
10198 AscStopChip(iop_base);
10199 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
10200 DvcDelayNanoSecond(asc_dvc, 60000);
10201 AscSetChipIH(iop_base, INS_RFLAG_WTM);
10202 AscSetChipIH(iop_base, INS_HALT);
10203 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
10204 AscSetChipControl(iop_base, CC_HALT);
10205 DvcSleepMilliSecond(200);
10206 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10207 AscSetChipStatus(iop_base, 0);
10208 return (AscIsChipHalted(iop_base));
10211 static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
10213 if (bus_type & ASC_IS_ISA)
10214 return (ASC_MAX_ISA_DMA_COUNT);
10215 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
10216 return (ASC_MAX_VL_DMA_COUNT);
10217 return (ASC_MAX_PCI_DMA_COUNT);
10220 #ifdef CONFIG_ISA
10221 static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
10223 ushort channel;
10225 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
10226 if (channel == 0x03)
10227 return (0);
10228 else if (channel == 0x00)
10229 return (7);
10230 return (channel + 4);
10233 static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
10235 ushort cfg_lsw;
10236 uchar value;
10238 if ((dma_channel >= 5) && (dma_channel <= 7)) {
10239 if (dma_channel == 7)
10240 value = 0x00;
10241 else
10242 value = dma_channel - 4;
10243 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
10244 cfg_lsw |= value;
10245 AscSetChipCfgLsw(iop_base, cfg_lsw);
10246 return (AscGetIsaDmaChannel(iop_base));
10248 return (0);
10251 static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
10253 speed_value &= 0x07;
10254 AscSetBank(iop_base, 1);
10255 AscWriteChipDmaSpeed(iop_base, speed_value);
10256 AscSetBank(iop_base, 0);
10257 return (AscGetIsaDmaSpeed(iop_base));
10260 static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
10262 uchar speed_value;
10264 AscSetBank(iop_base, 1);
10265 speed_value = AscReadChipDmaSpeed(iop_base);
10266 speed_value &= 0x07;
10267 AscSetBank(iop_base, 0);
10268 return (speed_value);
10270 #endif /* CONFIG_ISA */
10272 static ushort __devinit AscInitGetConfig(ASC_DVC_VAR *asc_dvc)
10274 unsigned short warn_code = 0;
10276 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
10277 if (asc_dvc->err_code != 0)
10278 return (UW_ERR);
10280 if (AscFindSignature(asc_dvc->iop_base)) {
10281 warn_code |= AscInitAscDvcVar(asc_dvc);
10282 warn_code |= AscInitFromEEP(asc_dvc);
10283 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
10284 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
10285 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
10287 } else {
10288 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10290 return (warn_code);
10293 static ushort __devinit AscInitSetConfig(ASC_DVC_VAR *asc_dvc)
10295 ushort warn_code = 0;
10297 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
10298 if (asc_dvc->err_code != 0)
10299 return (UW_ERR);
10300 if (AscFindSignature(asc_dvc->iop_base)) {
10301 warn_code |= AscInitFromAscDvcVar(asc_dvc);
10302 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
10303 } else {
10304 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10306 return (warn_code);
10309 static ushort __devinit AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc)
10311 PortAddr iop_base;
10312 ushort cfg_msw;
10313 ushort warn_code;
10315 iop_base = asc_dvc->iop_base;
10316 warn_code = 0;
10317 cfg_msw = AscGetChipCfgMsw(iop_base);
10318 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10319 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10320 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10321 AscSetChipCfgMsw(iop_base, cfg_msw);
10323 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
10324 asc_dvc->cfg->cmd_qng_enabled) {
10325 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
10326 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10328 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10329 warn_code |= ASC_WARN_AUTO_CONFIG;
10331 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
10332 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
10333 != asc_dvc->irq_no) {
10334 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
10337 #ifdef CONFIG_PCI
10338 if (asc_dvc->bus_type & ASC_IS_PCI) {
10339 struct pci_dev *pdev = to_pci_dev(asc_dvc->cfg->dev);
10340 cfg_msw &= 0xFFC0;
10341 AscSetChipCfgMsw(iop_base, cfg_msw);
10342 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
10343 } else {
10344 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
10345 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
10346 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
10347 asc_dvc->bug_fix_cntl |=
10348 ASC_BUG_FIX_ASYN_USE_SYN;
10351 } else
10352 #endif /* CONFIG_PCI */
10353 if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
10354 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
10355 == ASC_CHIP_VER_ASYN_BUG) {
10356 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
10359 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
10360 asc_dvc->cfg->chip_scsi_id) {
10361 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
10363 #ifdef CONFIG_ISA
10364 if (asc_dvc->bus_type & ASC_IS_ISA) {
10365 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
10366 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
10368 #endif /* CONFIG_ISA */
10369 return (warn_code);
10372 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
10374 ushort warn_code;
10375 PortAddr iop_base;
10377 iop_base = asc_dvc->iop_base;
10378 warn_code = 0;
10379 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
10380 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
10381 AscResetChipAndScsiBus(asc_dvc);
10382 DvcSleepMilliSecond((ASC_DCNT)
10383 ((ushort)asc_dvc->scsi_reset_wait * 1000));
10385 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
10386 if (asc_dvc->err_code != 0)
10387 return (UW_ERR);
10388 if (!AscFindSignature(asc_dvc->iop_base)) {
10389 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10390 return (warn_code);
10392 AscDisableInterrupt(iop_base);
10393 warn_code |= AscInitLram(asc_dvc);
10394 if (asc_dvc->err_code != 0)
10395 return (UW_ERR);
10396 ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
10397 (ulong)_asc_mcode_chksum);
10398 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
10399 _asc_mcode_size) != _asc_mcode_chksum) {
10400 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
10401 return (warn_code);
10403 warn_code |= AscInitMicroCodeVar(asc_dvc);
10404 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
10405 AscEnableInterrupt(iop_base);
10406 return (warn_code);
10409 static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
10411 int i;
10412 PortAddr iop_base;
10413 ushort warn_code;
10414 uchar chip_version;
10416 iop_base = asc_dvc->iop_base;
10417 warn_code = 0;
10418 asc_dvc->err_code = 0;
10419 if ((asc_dvc->bus_type &
10420 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
10421 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
10423 AscSetChipControl(iop_base, CC_HALT);
10424 AscSetChipStatus(iop_base, 0);
10425 asc_dvc->bug_fix_cntl = 0;
10426 asc_dvc->pci_fix_asyn_xfer = 0;
10427 asc_dvc->pci_fix_asyn_xfer_always = 0;
10428 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
10429 asc_dvc->sdtr_done = 0;
10430 asc_dvc->cur_total_qng = 0;
10431 asc_dvc->is_in_int = 0;
10432 asc_dvc->in_critical_cnt = 0;
10433 asc_dvc->last_q_shortage = 0;
10434 asc_dvc->use_tagged_qng = 0;
10435 asc_dvc->no_scam = 0;
10436 asc_dvc->unit_not_ready = 0;
10437 asc_dvc->queue_full_or_busy = 0;
10438 asc_dvc->redo_scam = 0;
10439 asc_dvc->res2 = 0;
10440 asc_dvc->host_init_sdtr_index = 0;
10441 asc_dvc->cfg->can_tagged_qng = 0;
10442 asc_dvc->cfg->cmd_qng_enabled = 0;
10443 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
10444 asc_dvc->init_sdtr = 0;
10445 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
10446 asc_dvc->scsi_reset_wait = 3;
10447 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
10448 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
10449 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
10450 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
10451 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
10452 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
10453 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
10454 ASC_LIB_VERSION_MINOR;
10455 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
10456 asc_dvc->cfg->chip_version = chip_version;
10457 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
10458 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
10459 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
10460 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
10461 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
10462 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
10463 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
10464 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
10465 asc_dvc->max_sdtr_index = 7;
10466 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
10467 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
10468 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
10469 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
10470 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
10471 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
10472 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
10473 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
10474 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
10475 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
10476 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
10477 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
10478 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
10479 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
10480 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
10481 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
10482 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
10483 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
10484 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
10485 asc_dvc->max_sdtr_index = 15;
10486 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
10487 AscSetExtraControl(iop_base,
10488 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10489 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
10490 AscSetExtraControl(iop_base,
10491 (SEC_ACTIVE_NEGATE |
10492 SEC_ENABLE_FILTER));
10495 if (asc_dvc->bus_type == ASC_IS_PCI) {
10496 AscSetExtraControl(iop_base,
10497 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10500 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
10501 if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
10502 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
10503 asc_dvc->bus_type = ASC_IS_ISAPNP;
10505 #ifdef CONFIG_ISA
10506 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
10507 asc_dvc->cfg->isa_dma_channel =
10508 (uchar)AscGetIsaDmaChannel(iop_base);
10510 #endif /* CONFIG_ISA */
10511 for (i = 0; i <= ASC_MAX_TID; i++) {
10512 asc_dvc->cur_dvc_qng[i] = 0;
10513 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
10514 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
10515 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
10516 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
10518 return (warn_code);
10521 static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
10523 ASCEEP_CONFIG eep_config_buf;
10524 ASCEEP_CONFIG *eep_config;
10525 PortAddr iop_base;
10526 ushort chksum;
10527 ushort warn_code;
10528 ushort cfg_msw, cfg_lsw;
10529 int i;
10530 int write_eep = 0;
10532 iop_base = asc_dvc->iop_base;
10533 warn_code = 0;
10534 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
10535 AscStopQueueExe(iop_base);
10536 if ((AscStopChip(iop_base) == FALSE) ||
10537 (AscGetChipScsiCtrl(iop_base) != 0)) {
10538 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
10539 AscResetChipAndScsiBus(asc_dvc);
10540 DvcSleepMilliSecond((ASC_DCNT)
10541 ((ushort)asc_dvc->scsi_reset_wait * 1000));
10543 if (AscIsChipHalted(iop_base) == FALSE) {
10544 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10545 return (warn_code);
10547 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10548 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10549 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10550 return (warn_code);
10552 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
10553 cfg_msw = AscGetChipCfgMsw(iop_base);
10554 cfg_lsw = AscGetChipCfgLsw(iop_base);
10555 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10556 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10557 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10558 AscSetChipCfgMsw(iop_base, cfg_msw);
10560 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
10561 ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
10562 if (chksum == 0) {
10563 chksum = 0xaa55;
10565 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10566 warn_code |= ASC_WARN_AUTO_CONFIG;
10567 if (asc_dvc->cfg->chip_version == 3) {
10568 if (eep_config->cfg_lsw != cfg_lsw) {
10569 warn_code |= ASC_WARN_EEPROM_RECOVER;
10570 eep_config->cfg_lsw =
10571 AscGetChipCfgLsw(iop_base);
10573 if (eep_config->cfg_msw != cfg_msw) {
10574 warn_code |= ASC_WARN_EEPROM_RECOVER;
10575 eep_config->cfg_msw =
10576 AscGetChipCfgMsw(iop_base);
10580 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
10581 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
10582 ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
10583 eep_config->chksum);
10584 if (chksum != eep_config->chksum) {
10585 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
10586 ASC_CHIP_VER_PCI_ULTRA_3050) {
10587 ASC_DBG(1,
10588 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
10589 eep_config->init_sdtr = 0xFF;
10590 eep_config->disc_enable = 0xFF;
10591 eep_config->start_motor = 0xFF;
10592 eep_config->use_cmd_qng = 0;
10593 eep_config->max_total_qng = 0xF0;
10594 eep_config->max_tag_qng = 0x20;
10595 eep_config->cntl = 0xBFFF;
10596 ASC_EEP_SET_CHIP_ID(eep_config, 7);
10597 eep_config->no_scam = 0;
10598 eep_config->adapter_info[0] = 0;
10599 eep_config->adapter_info[1] = 0;
10600 eep_config->adapter_info[2] = 0;
10601 eep_config->adapter_info[3] = 0;
10602 eep_config->adapter_info[4] = 0;
10603 /* Indicate EEPROM-less board. */
10604 eep_config->adapter_info[5] = 0xBB;
10605 } else {
10606 ASC_PRINT
10607 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
10608 write_eep = 1;
10609 warn_code |= ASC_WARN_EEPROM_CHKSUM;
10612 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
10613 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
10614 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
10615 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
10616 asc_dvc->start_motor = eep_config->start_motor;
10617 asc_dvc->dvc_cntl = eep_config->cntl;
10618 asc_dvc->no_scam = eep_config->no_scam;
10619 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
10620 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
10621 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
10622 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
10623 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
10624 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
10625 if (!AscTestExternalLram(asc_dvc)) {
10626 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
10627 ASC_IS_PCI_ULTRA)) {
10628 eep_config->max_total_qng =
10629 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
10630 eep_config->max_tag_qng =
10631 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
10632 } else {
10633 eep_config->cfg_msw |= 0x0800;
10634 cfg_msw |= 0x0800;
10635 AscSetChipCfgMsw(iop_base, cfg_msw);
10636 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
10637 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
10639 } else {
10641 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
10642 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
10644 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
10645 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
10647 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
10648 eep_config->max_tag_qng = eep_config->max_total_qng;
10650 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
10651 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
10653 asc_dvc->max_total_qng = eep_config->max_total_qng;
10654 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
10655 eep_config->use_cmd_qng) {
10656 eep_config->disc_enable = eep_config->use_cmd_qng;
10657 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10659 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
10660 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
10662 ASC_EEP_SET_CHIP_ID(eep_config,
10663 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
10664 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
10665 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
10666 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
10667 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
10670 for (i = 0; i <= ASC_MAX_TID; i++) {
10671 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
10672 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
10673 asc_dvc->cfg->sdtr_period_offset[i] =
10674 (uchar)(ASC_DEF_SDTR_OFFSET |
10675 (asc_dvc->host_init_sdtr_index << 4));
10677 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
10678 if (write_eep) {
10679 if ((i =
10680 AscSetEEPConfig(iop_base, eep_config,
10681 asc_dvc->bus_type)) != 0) {
10682 ASC_PRINT1
10683 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
10685 } else {
10686 ASC_PRINT
10687 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
10690 return (warn_code);
10693 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
10695 int i;
10696 ushort warn_code;
10697 PortAddr iop_base;
10698 ASC_PADDR phy_addr;
10699 ASC_DCNT phy_size;
10701 iop_base = asc_dvc->iop_base;
10702 warn_code = 0;
10703 for (i = 0; i <= ASC_MAX_TID; i++) {
10704 AscPutMCodeInitSDTRAtID(iop_base, i,
10705 asc_dvc->cfg->sdtr_period_offset[i]
10709 AscInitQLinkVar(asc_dvc);
10710 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
10711 asc_dvc->cfg->disc_enable);
10712 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
10713 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
10715 /* Align overrun buffer on an 8 byte boundary. */
10716 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
10717 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
10718 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
10719 (uchar *)&phy_addr, 1);
10720 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
10721 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
10722 (uchar *)&phy_size, 1);
10724 asc_dvc->cfg->mcode_date =
10725 AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
10726 asc_dvc->cfg->mcode_version =
10727 AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
10729 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10730 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10731 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10732 return (warn_code);
10734 if (AscStartChip(iop_base) != 1) {
10735 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10736 return (warn_code);
10739 return (warn_code);
10742 static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
10744 PortAddr iop_base;
10745 ushort q_addr;
10746 ushort saved_word;
10747 int sta;
10749 iop_base = asc_dvc->iop_base;
10750 sta = 0;
10751 q_addr = ASC_QNO_TO_QADDR(241);
10752 saved_word = AscReadLramWord(iop_base, q_addr);
10753 AscSetChipLramAddr(iop_base, q_addr);
10754 AscSetChipLramData(iop_base, 0x55AA);
10755 DvcSleepMilliSecond(10);
10756 AscSetChipLramAddr(iop_base, q_addr);
10757 if (AscGetChipLramData(iop_base) == 0x55AA) {
10758 sta = 1;
10759 AscWriteLramWord(iop_base, q_addr, saved_word);
10761 return (sta);
10764 static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
10766 uchar read_back;
10767 int retry;
10769 retry = 0;
10770 while (TRUE) {
10771 AscSetChipEEPCmd(iop_base, cmd_reg);
10772 DvcSleepMilliSecond(1);
10773 read_back = AscGetChipEEPCmd(iop_base);
10774 if (read_back == cmd_reg) {
10775 return (1);
10777 if (retry++ > ASC_EEP_MAX_RETRY) {
10778 return (0);
10783 static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
10785 ushort read_back;
10786 int retry;
10788 retry = 0;
10789 while (TRUE) {
10790 AscSetChipEEPData(iop_base, data_reg);
10791 DvcSleepMilliSecond(1);
10792 read_back = AscGetChipEEPData(iop_base);
10793 if (read_back == data_reg) {
10794 return (1);
10796 if (retry++ > ASC_EEP_MAX_RETRY) {
10797 return (0);
10802 static void __devinit AscWaitEEPRead(void)
10804 DvcSleepMilliSecond(1);
10805 return;
10808 static void __devinit AscWaitEEPWrite(void)
10810 DvcSleepMilliSecond(20);
10811 return;
10814 static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
10816 ushort read_wval;
10817 uchar cmd_reg;
10819 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
10820 AscWaitEEPRead();
10821 cmd_reg = addr | ASC_EEP_CMD_READ;
10822 AscWriteEEPCmdReg(iop_base, cmd_reg);
10823 AscWaitEEPRead();
10824 read_wval = AscGetChipEEPData(iop_base);
10825 AscWaitEEPRead();
10826 return (read_wval);
10829 static ushort __devinit
10830 AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
10832 ushort read_wval;
10834 read_wval = AscReadEEPWord(iop_base, addr);
10835 if (read_wval != word_val) {
10836 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
10837 AscWaitEEPRead();
10838 AscWriteEEPDataReg(iop_base, word_val);
10839 AscWaitEEPRead();
10840 AscWriteEEPCmdReg(iop_base,
10841 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
10842 AscWaitEEPWrite();
10843 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
10844 AscWaitEEPRead();
10845 return (AscReadEEPWord(iop_base, addr));
10847 return (read_wval);
10850 static ushort __devinit
10851 AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
10853 ushort wval;
10854 ushort sum;
10855 ushort *wbuf;
10856 int cfg_beg;
10857 int cfg_end;
10858 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
10859 int s_addr;
10861 wbuf = (ushort *)cfg_buf;
10862 sum = 0;
10863 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
10864 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10865 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
10866 sum += *wbuf;
10868 if (bus_type & ASC_IS_VL) {
10869 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10870 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10871 } else {
10872 cfg_beg = ASC_EEP_DVC_CFG_BEG;
10873 cfg_end = ASC_EEP_MAX_DVC_ADDR;
10875 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
10876 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
10877 if (s_addr <= uchar_end_in_config) {
10879 * Swap all char fields - must unswap bytes already swapped
10880 * by AscReadEEPWord().
10882 *wbuf = le16_to_cpu(wval);
10883 } else {
10884 /* Don't swap word field at the end - cntl field. */
10885 *wbuf = wval;
10887 sum += wval; /* Checksum treats all EEPROM data as words. */
10890 * Read the checksum word which will be compared against 'sum'
10891 * by the caller. Word field already swapped.
10893 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
10894 return (sum);
10897 static int __devinit
10898 AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
10900 int n_error;
10901 ushort *wbuf;
10902 ushort word;
10903 ushort sum;
10904 int s_addr;
10905 int cfg_beg;
10906 int cfg_end;
10907 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
10909 wbuf = (ushort *)cfg_buf;
10910 n_error = 0;
10911 sum = 0;
10912 /* Write two config words; AscWriteEEPWord() will swap bytes. */
10913 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10914 sum += *wbuf;
10915 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
10916 n_error++;
10919 if (bus_type & ASC_IS_VL) {
10920 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10921 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10922 } else {
10923 cfg_beg = ASC_EEP_DVC_CFG_BEG;
10924 cfg_end = ASC_EEP_MAX_DVC_ADDR;
10926 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
10927 if (s_addr <= uchar_end_in_config) {
10929 * This is a char field. Swap char fields before they are
10930 * swapped again by AscWriteEEPWord().
10932 word = cpu_to_le16(*wbuf);
10933 if (word !=
10934 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
10935 n_error++;
10937 } else {
10938 /* Don't swap word field at the end - cntl field. */
10939 if (*wbuf !=
10940 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
10941 n_error++;
10944 sum += *wbuf; /* Checksum calculated from word values. */
10946 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
10947 *wbuf = sum;
10948 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
10949 n_error++;
10952 /* Read EEPROM back again. */
10953 wbuf = (ushort *)cfg_buf;
10955 * Read two config words; Byte-swapping done by AscReadEEPWord().
10957 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10958 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
10959 n_error++;
10962 if (bus_type & ASC_IS_VL) {
10963 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10964 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10965 } else {
10966 cfg_beg = ASC_EEP_DVC_CFG_BEG;
10967 cfg_end = ASC_EEP_MAX_DVC_ADDR;
10969 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
10970 if (s_addr <= uchar_end_in_config) {
10972 * Swap all char fields. Must unswap bytes already swapped
10973 * by AscReadEEPWord().
10975 word =
10976 le16_to_cpu(AscReadEEPWord
10977 (iop_base, (uchar)s_addr));
10978 } else {
10979 /* Don't swap word field at the end - cntl field. */
10980 word = AscReadEEPWord(iop_base, (uchar)s_addr);
10982 if (*wbuf != word) {
10983 n_error++;
10986 /* Read checksum; Byte swapping not needed. */
10987 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
10988 n_error++;
10990 return (n_error);
10993 static int __devinit
10994 AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
10996 int retry;
10997 int n_error;
10999 retry = 0;
11000 while (TRUE) {
11001 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
11002 bus_type)) == 0) {
11003 break;
11005 if (++retry > ASC_EEP_MAX_RETRY) {
11006 break;
11009 return (n_error);
11012 static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
11014 char type = sdev->type;
11015 ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
11017 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
11018 if (!(asc_dvc->init_sdtr & tid_bits)) {
11019 if ((type == TYPE_ROM) &&
11020 (strncmp(sdev->vendor, "HP ", 3) == 0)) {
11021 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
11023 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
11024 if ((type == TYPE_PROCESSOR) ||
11025 (type == TYPE_SCANNER) || (type == TYPE_ROM) ||
11026 (type == TYPE_TAPE)) {
11027 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
11030 if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
11031 AscSetRunChipSynRegAtID(asc_dvc->iop_base,
11032 sdev->id,
11033 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
11039 static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
11041 uchar byte_data;
11042 ushort word_data;
11044 if (isodd_word(addr)) {
11045 AscSetChipLramAddr(iop_base, addr - 1);
11046 word_data = AscGetChipLramData(iop_base);
11047 byte_data = (uchar)((word_data >> 8) & 0xFF);
11048 } else {
11049 AscSetChipLramAddr(iop_base, addr);
11050 word_data = AscGetChipLramData(iop_base);
11051 byte_data = (uchar)(word_data & 0xFF);
11053 return (byte_data);
11056 static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
11058 ushort word_data;
11060 AscSetChipLramAddr(iop_base, addr);
11061 word_data = AscGetChipLramData(iop_base);
11062 return (word_data);
11065 #if CC_VERY_LONG_SG_LIST
11066 static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
11068 ushort val_low, val_high;
11069 ASC_DCNT dword_data;
11071 AscSetChipLramAddr(iop_base, addr);
11072 val_low = AscGetChipLramData(iop_base);
11073 val_high = AscGetChipLramData(iop_base);
11074 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
11075 return (dword_data);
11077 #endif /* CC_VERY_LONG_SG_LIST */
11079 static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
11081 AscSetChipLramAddr(iop_base, addr);
11082 AscSetChipLramData(iop_base, word_val);
11083 return;
11086 static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
11088 ushort word_data;
11090 if (isodd_word(addr)) {
11091 addr--;
11092 word_data = AscReadLramWord(iop_base, addr);
11093 word_data &= 0x00FF;
11094 word_data |= (((ushort)byte_val << 8) & 0xFF00);
11095 } else {
11096 word_data = AscReadLramWord(iop_base, addr);
11097 word_data &= 0xFF00;
11098 word_data |= ((ushort)byte_val & 0x00FF);
11100 AscWriteLramWord(iop_base, addr, word_data);
11101 return;
11105 * Copy 2 bytes to LRAM.
11107 * The source data is assumed to be in little-endian order in memory
11108 * and is maintained in little-endian order when written to LRAM.
11110 static void
11111 AscMemWordCopyPtrToLram(PortAddr iop_base,
11112 ushort s_addr, uchar *s_buffer, int words)
11114 int i;
11116 AscSetChipLramAddr(iop_base, s_addr);
11117 for (i = 0; i < 2 * words; i += 2) {
11119 * On a little-endian system the second argument below
11120 * produces a little-endian ushort which is written to
11121 * LRAM in little-endian order. On a big-endian system
11122 * the second argument produces a big-endian ushort which
11123 * is "transparently" byte-swapped by outpw() and written
11124 * in little-endian order to LRAM.
11126 outpw(iop_base + IOP_RAM_DATA,
11127 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
11129 return;
11133 * Copy 4 bytes to LRAM.
11135 * The source data is assumed to be in little-endian order in memory
11136 * and is maintained in little-endian order when writen to LRAM.
11138 static void
11139 AscMemDWordCopyPtrToLram(PortAddr iop_base,
11140 ushort s_addr, uchar *s_buffer, int dwords)
11142 int i;
11144 AscSetChipLramAddr(iop_base, s_addr);
11145 for (i = 0; i < 4 * dwords; i += 4) {
11146 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
11147 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
11149 return;
11153 * Copy 2 bytes from LRAM.
11155 * The source data is assumed to be in little-endian order in LRAM
11156 * and is maintained in little-endian order when written to memory.
11158 static void
11159 AscMemWordCopyPtrFromLram(PortAddr iop_base,
11160 ushort s_addr, uchar *d_buffer, int words)
11162 int i;
11163 ushort word;
11165 AscSetChipLramAddr(iop_base, s_addr);
11166 for (i = 0; i < 2 * words; i += 2) {
11167 word = inpw(iop_base + IOP_RAM_DATA);
11168 d_buffer[i] = word & 0xff;
11169 d_buffer[i + 1] = (word >> 8) & 0xff;
11171 return;
11174 static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
11176 ASC_DCNT sum;
11177 int i;
11179 sum = 0L;
11180 for (i = 0; i < words; i++, s_addr += 2) {
11181 sum += AscReadLramWord(iop_base, s_addr);
11183 return (sum);
11186 static void
11187 AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
11189 int i;
11191 AscSetChipLramAddr(iop_base, s_addr);
11192 for (i = 0; i < words; i++) {
11193 AscSetChipLramData(iop_base, set_wval);
11195 return;
11199 * --- Adv Library Functions
11202 /* a_mcode.h */
11204 /* Microcode buffer is kept after initialization for error recovery. */
11205 static unsigned char _adv_asc3550_buf[] = {
11206 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
11207 0x01, 0x00, 0x48, 0xe4,
11208 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff,
11209 0x28, 0x0e, 0x9e, 0xe7,
11210 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7,
11211 0x55, 0xf0, 0x01, 0xf6,
11212 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
11213 0x00, 0xec, 0x85, 0xf0,
11214 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0,
11215 0x86, 0xf0, 0xb4, 0x00,
11216 0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00,
11217 0xaa, 0x18, 0x02, 0x80,
11218 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
11219 0x00, 0x57, 0x01, 0xea,
11220 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80,
11221 0x03, 0xe6, 0xb6, 0x00,
11222 0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12,
11223 0x02, 0x4a, 0xb9, 0x54,
11224 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
11225 0x3e, 0x00, 0x80, 0x00,
11226 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
11227 0x74, 0x01, 0x76, 0x01,
11228 0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13,
11229 0x4c, 0x1c, 0xbb, 0x55,
11230 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
11231 0x03, 0xf7, 0x06, 0xf7,
11232 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08,
11233 0x30, 0x13, 0x64, 0x15,
11234 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c,
11235 0x04, 0xea, 0x5d, 0xf0,
11236 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
11237 0xcc, 0x00, 0x20, 0x01,
11238 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13,
11239 0x40, 0x13, 0x30, 0x1c,
11240 0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
11241 0x59, 0xf0, 0xa7, 0xf0,
11242 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
11243 0xa4, 0x00, 0xb5, 0x00,
11244 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a,
11245 0x14, 0x0e, 0x02, 0x10,
11246 0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13,
11247 0x10, 0x15, 0x14, 0x15,
11248 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
11249 0x91, 0x44, 0x0a, 0x45,
11250 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58,
11251 0x83, 0x59, 0x05, 0xe6,
11252 0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8,
11253 0x02, 0xfa, 0x03, 0xfa,
11254 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
11255 0x9e, 0x00, 0xa8, 0x00,
11256 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01,
11257 0x7a, 0x01, 0xc0, 0x01,
11258 0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08,
11259 0x69, 0x08, 0xba, 0x08,
11260 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
11261 0xf1, 0x10, 0x06, 0x12,
11262 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14,
11263 0x8a, 0x15, 0xc6, 0x17,
11264 0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
11265 0x0e, 0x47, 0x48, 0x47,
11266 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
11267 0x14, 0x56, 0x77, 0x57,
11268 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c,
11269 0xf0, 0x29, 0x02, 0xfe,
11270 0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf,
11271 0xfe, 0x80, 0x01, 0xff,
11272 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
11273 0x00, 0xfe, 0x57, 0x24,
11274 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09,
11275 0x00, 0x00, 0xff, 0x08,
11276 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
11277 0xff, 0xff, 0xff, 0x0f,
11278 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
11279 0xfe, 0x04, 0xf7, 0xcf,
11280 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67,
11281 0x0b, 0x3c, 0x2a, 0xfe,
11282 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0,
11283 0xfe, 0xf0, 0x01, 0xfe,
11284 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
11285 0x02, 0xfe, 0xd4, 0x0c,
11286 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
11287 0x1c, 0x05, 0xfe, 0xa6,
11288 0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48,
11289 0xf0, 0xfe, 0x86, 0x02,
11290 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
11291 0xfe, 0x46, 0xf0, 0xfe,
11292 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
11293 0x44, 0x02, 0xfe, 0x44,
11294 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b,
11295 0xa0, 0x17, 0x06, 0x18,
11296 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
11297 0x1e, 0x1c, 0xfe, 0xe9,
11298 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7,
11299 0x0a, 0x6b, 0x01, 0x9e,
11300 0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b,
11301 0x01, 0x82, 0xfe, 0xbd,
11302 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
11303 0x58, 0x1c, 0x17, 0x06,
11304 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21,
11305 0xfe, 0x94, 0x02, 0xfe,
11306 0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97,
11307 0x01, 0xfe, 0x54, 0x0f,
11308 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
11309 0x69, 0x10, 0x17, 0x06,
11310 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05,
11311 0xf6, 0xc7, 0x01, 0xfe,
11312 0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6,
11313 0x02, 0x29, 0x0a, 0x40,
11314 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
11315 0x58, 0x0a, 0x99, 0x01,
11316 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29,
11317 0x2a, 0x46, 0xfe, 0x02,
11318 0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc,
11319 0x01, 0xfe, 0x07, 0x4b,
11320 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
11321 0xfe, 0x56, 0x03, 0xfe,
11322 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10,
11323 0xfe, 0x9f, 0xf0, 0xfe,
11324 0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48,
11325 0x1c, 0xeb, 0x09, 0x04,
11326 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
11327 0x01, 0x0e, 0xac, 0x75,
11328 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2,
11329 0xfe, 0x82, 0xf0, 0xfe,
11330 0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25,
11331 0x32, 0x1f, 0xfe, 0xb4,
11332 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
11333 0x0a, 0xf0, 0xfe, 0x7a,
11334 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c,
11335 0x01, 0x33, 0x8f, 0xfe,
11336 0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8,
11337 0xf7, 0xfe, 0x48, 0x1c,
11338 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
11339 0x0a, 0xca, 0x01, 0x0e,
11340 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14,
11341 0x2c, 0x01, 0x33, 0x8f,
11342 0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65,
11343 0xfe, 0x3c, 0x04, 0x1f,
11344 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
11345 0x12, 0x2b, 0xff, 0x02,
11346 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f,
11347 0x22, 0x30, 0x2e, 0xd5,
11348 0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c,
11349 0xfe, 0x4c, 0x54, 0x64,
11350 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
11351 0xfe, 0x2a, 0x13, 0x2f,
11352 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
11353 0xd3, 0xfa, 0xef, 0x86,
11354 0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04,
11355 0x1d, 0xfe, 0x1c, 0x12,
11356 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
11357 0x70, 0x0c, 0x02, 0x22,
11358 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92,
11359 0x01, 0x33, 0x02, 0x29,
11360 0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87,
11361 0x80, 0xfe, 0x31, 0xe4,
11362 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
11363 0xfe, 0x70, 0x12, 0x49,
11364 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe,
11365 0x80, 0x05, 0xfe, 0x31,
11366 0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00,
11367 0x28, 0xfe, 0x42, 0x12,
11368 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
11369 0x11, 0xfe, 0xe3, 0x00,
11370 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
11371 0x64, 0x05, 0x83, 0x24,
11372 0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe,
11373 0x09, 0x48, 0x01, 0x08,
11374 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
11375 0x86, 0x24, 0x06, 0x12,
11376 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47,
11377 0x01, 0xa7, 0x14, 0x92,
11378 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c,
11379 0x02, 0x22, 0x05, 0xfe,
11380 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
11381 0x47, 0x01, 0xa7, 0x26,
11382 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f,
11383 0x01, 0xfe, 0xaa, 0x14,
11384 0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00,
11385 0x05, 0x50, 0xb4, 0x0c,
11386 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
11387 0x13, 0x01, 0xfe, 0x14,
11388 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c,
11389 0xff, 0x02, 0x00, 0x57,
11390 0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe,
11391 0x72, 0x06, 0x49, 0x04,
11392 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
11393 0x06, 0x11, 0x9a, 0x01,
11394 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06,
11395 0x01, 0xa7, 0xec, 0x72,
11396 0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32,
11397 0xfe, 0x0a, 0xf0, 0xfe,
11398 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
11399 0x8d, 0x81, 0x02, 0x22,
11400 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00,
11401 0x01, 0x08, 0x15, 0x00,
11402 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15,
11403 0x00, 0x02, 0xfe, 0x32,
11404 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
11405 0xfe, 0x1b, 0x00, 0x01,
11406 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
11407 0x08, 0x15, 0x06, 0x01,
11408 0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe,
11409 0x9a, 0x81, 0x4b, 0x1d,
11410 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
11411 0x45, 0xfe, 0x32, 0x12,
11412 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0,
11413 0xfe, 0x32, 0x07, 0x8d,
11414 0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a,
11415 0x06, 0x15, 0x19, 0x02,
11416 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
11417 0x90, 0x77, 0xfe, 0xca,
11418 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07,
11419 0x10, 0xfe, 0x0e, 0x12,
11420 0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe,
11421 0x83, 0xe7, 0xc4, 0xa1,
11422 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
11423 0x40, 0x12, 0x58, 0x01,
11424 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6,
11425 0x51, 0x83, 0xfb, 0xfe,
11426 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90,
11427 0xfe, 0x40, 0x50, 0xfe,
11428 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
11429 0xfe, 0x2a, 0x12, 0xfe,
11430 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f,
11431 0x85, 0x01, 0xa8, 0xfe,
11432 0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56,
11433 0x18, 0x57, 0xfb, 0xfe,
11434 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
11435 0x0c, 0x39, 0x18, 0x3a,
11436 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e,
11437 0x11, 0x65, 0xfe, 0x48,
11438 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73,
11439 0xdd, 0xb8, 0xfe, 0x80,
11440 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
11441 0xfe, 0x7a, 0x08, 0x8d,
11442 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9,
11443 0x10, 0x61, 0x04, 0x06,
11444 0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68,
11445 0x12, 0xfe, 0x2e, 0x1c,
11446 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
11447 0x52, 0x12, 0xfe, 0x2c,
11448 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe,
11449 0x08, 0xfe, 0x8a, 0x10,
11450 0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe,
11451 0x24, 0x0a, 0xab, 0xfe,
11452 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
11453 0x1c, 0x12, 0xb5, 0xfe,
11454 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb,
11455 0x1c, 0x06, 0x16, 0x9d,
11456 0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b,
11457 0x14, 0x92, 0x01, 0x33,
11458 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
11459 0xfe, 0x74, 0x18, 0x1c,
11460 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b,
11461 0x01, 0xe6, 0x1e, 0x27,
11462 0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a,
11463 0x09, 0x04, 0x6a, 0xfe,
11464 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
11465 0xfe, 0x83, 0x80, 0xfe,
11466 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63,
11467 0x27, 0xfe, 0x40, 0x59,
11468 0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18,
11469 0x7c, 0xbe, 0x54, 0xbf,
11470 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
11471 0x79, 0x56, 0x68, 0x57,
11472 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5,
11473 0xa2, 0x23, 0x0c, 0x7b,
11474 0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19,
11475 0x16, 0xd7, 0x79, 0x39,
11476 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
11477 0xfe, 0x10, 0x58, 0xfe,
11478 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04,
11479 0x19, 0x16, 0xd7, 0x09,
11480 0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f,
11481 0xfe, 0x10, 0x90, 0xfe,
11482 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
11483 0x11, 0x9b, 0x09, 0x04,
11484 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08,
11485 0xfe, 0x0c, 0x58, 0xfe,
11486 0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04,
11487 0x0b, 0xfe, 0x1a, 0x12,
11488 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
11489 0x14, 0x7a, 0x01, 0x33,
11490 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39,
11491 0xfe, 0xed, 0x19, 0xbf,
11492 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff,
11493 0x34, 0xfe, 0x74, 0x10,
11494 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
11495 0x84, 0x05, 0xcb, 0x1c,
11496 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1,
11497 0xf0, 0xfe, 0xc4, 0x0a,
11498 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe,
11499 0xce, 0xf0, 0xfe, 0xca,
11500 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
11501 0x22, 0x00, 0x02, 0x5a,
11502 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a,
11503 0xfe, 0xd0, 0xf0, 0xfe,
11504 0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f,
11505 0x4c, 0xfe, 0x10, 0x10,
11506 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
11507 0x2a, 0x13, 0xfe, 0x4e,
11508 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1,
11509 0x16, 0x32, 0x2a, 0x73,
11510 0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25,
11511 0x32, 0x8c, 0xfe, 0x48,
11512 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
11513 0xdb, 0x10, 0x11, 0xfe,
11514 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0,
11515 0x22, 0x30, 0x2e, 0xd8,
11516 0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1,
11517 0x45, 0x0f, 0xfe, 0x42,
11518 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
11519 0x09, 0x04, 0x0b, 0xfe,
11520 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28,
11521 0x00, 0x21, 0xfe, 0xa6,
11522 0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00,
11523 0xfe, 0xe2, 0x10, 0x01,
11524 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
11525 0x01, 0x6f, 0x02, 0x29,
11526 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10,
11527 0x01, 0x86, 0x3e, 0x0b,
11528 0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3,
11529 0x3e, 0x0b, 0x0f, 0xfe,
11530 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
11531 0xe8, 0x59, 0x11, 0x2d,
11532 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09,
11533 0x04, 0x0b, 0x84, 0x3e,
11534 0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12,
11535 0x09, 0x04, 0x1b, 0xfe,
11536 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
11537 0x1c, 0x1c, 0xfe, 0x9d,
11538 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f,
11539 0xfe, 0x15, 0x00, 0xfe,
11540 0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10,
11541 0x0f, 0xfe, 0x47, 0x00,
11542 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
11543 0xab, 0x70, 0x05, 0x6b,
11544 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe,
11545 0x1c, 0x42, 0x59, 0x01,
11546 0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31,
11547 0x00, 0x37, 0x97, 0x01,
11548 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
11549 0x1d, 0xfe, 0xce, 0x45,
11550 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75,
11551 0x57, 0x05, 0x51, 0xfe,
11552 0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48,
11553 0x46, 0x09, 0x04, 0x1d,
11554 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
11555 0x99, 0x01, 0x0e, 0xfe,
11556 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51,
11557 0xfe, 0xee, 0x14, 0xee,
11558 0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad,
11559 0x13, 0x02, 0x29, 0x1e,
11560 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
11561 0xce, 0x1e, 0x2d, 0x47,
11562 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06,
11563 0x12, 0x4d, 0x01, 0xfe,
11564 0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe,
11565 0xf0, 0x0d, 0xfe, 0x02,
11566 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
11567 0xf6, 0xfe, 0x34, 0x01,
11568 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13,
11569 0xaf, 0xfe, 0x02, 0xea,
11570 0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c,
11571 0x05, 0xfe, 0x38, 0x01,
11572 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
11573 0x0c, 0xfe, 0x62, 0x01,
11574 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06,
11575 0x03, 0x23, 0x03, 0x1e,
11576 0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe,
11577 0x71, 0x13, 0xfe, 0x24,
11578 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
11579 0xdc, 0xfe, 0x73, 0x57,
11580 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe,
11581 0x80, 0x5d, 0x03, 0xfe,
11582 0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6,
11583 0x75, 0x03, 0x09, 0x04,
11584 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
11585 0xfe, 0x1e, 0x80, 0xe1,
11586 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e,
11587 0x90, 0xa3, 0xfe, 0x3c,
11588 0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82,
11589 0x16, 0x2f, 0x07, 0x2d,
11590 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
11591 0xe8, 0x11, 0xfe, 0xe9,
11592 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe,
11593 0x1e, 0x1c, 0xfe, 0x14,
11594 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01,
11595 0x09, 0x04, 0x4f, 0xfe,
11596 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
11597 0x40, 0x12, 0x20, 0x63,
11598 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08,
11599 0x1c, 0x05, 0xfe, 0xac,
11600 0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05,
11601 0xfe, 0xb0, 0x00, 0xfe,
11602 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
11603 0x24, 0x69, 0x12, 0xc9,
11604 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe,
11605 0x90, 0x4d, 0xfe, 0x91,
11606 0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c,
11607 0xfe, 0x90, 0x4d, 0xfe,
11608 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
11609 0x46, 0x1e, 0x20, 0xed,
11610 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea,
11611 0x70, 0xfe, 0x14, 0x1c,
11612 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee,
11613 0xfe, 0x07, 0xe6, 0x1d,
11614 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
11615 0xfa, 0xef, 0xfe, 0x42,
11616 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0,
11617 0xfe, 0x36, 0x12, 0xf0,
11618 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
11619 0x3d, 0x75, 0x07, 0x10,
11620 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
11621 0x10, 0x07, 0x7e, 0x45,
11622 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74,
11623 0xfe, 0x01, 0xec, 0x97,
11624 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76,
11625 0x27, 0x01, 0xda, 0xfe,
11626 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
11627 0xfe, 0x48, 0x12, 0x07,
11628 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16,
11629 0xfe, 0x3e, 0x11, 0x07,
11630 0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8,
11631 0x11, 0x07, 0x19, 0xfe,
11632 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
11633 0x01, 0x08, 0x8c, 0x43,
11634 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11,
11635 0x7e, 0x02, 0x29, 0x2b,
11636 0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe,
11637 0xfc, 0x10, 0x09, 0x04,
11638 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
11639 0xc6, 0x10, 0x1e, 0x58,
11640 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c,
11641 0x54, 0x18, 0x55, 0x23,
11642 0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01,
11643 0xa5, 0xc0, 0x38, 0xc1,
11644 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
11645 0x05, 0xfa, 0x4e, 0xfe,
11646 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56,
11647 0x0c, 0x56, 0x18, 0x57,
11648 0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe,
11649 0x00, 0x56, 0xfe, 0xa1,
11650 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
11651 0x58, 0xfe, 0x1f, 0x40,
11652 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56,
11653 0x31, 0x57, 0xfe, 0x44,
11654 0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe,
11655 0x8a, 0x50, 0x05, 0x39,
11656 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
11657 0x12, 0xcd, 0x02, 0x5b,
11658 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44,
11659 0x2f, 0x07, 0x9b, 0x21,
11660 0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79,
11661 0x39, 0x68, 0x3a, 0xfe,
11662 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
11663 0x51, 0xfe, 0x8e, 0x51,
11664 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b,
11665 0x01, 0x08, 0x25, 0x32,
11666 0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b,
11667 0x3b, 0x02, 0x44, 0x01,
11668 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
11669 0x01, 0x08, 0x1f, 0xa2,
11670 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c,
11671 0x00, 0x28, 0x84, 0x49,
11672 0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06,
11673 0x78, 0x3d, 0xfe, 0xda,
11674 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
11675 0x05, 0xc6, 0x28, 0x84,
11676 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8,
11677 0x14, 0xfe, 0x03, 0x17,
11678 0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01,
11679 0xfe, 0xaa, 0x14, 0x02,
11680 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
11681 0x21, 0x44, 0x01, 0xfe,
11682 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87,
11683 0xfe, 0x4a, 0xf4, 0x0b,
11684 0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a,
11685 0x85, 0x02, 0x5b, 0x05,
11686 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
11687 0xd8, 0x14, 0x02, 0x5c,
11688 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1,
11689 0x01, 0x08, 0x23, 0x72,
11690 0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca,
11691 0x12, 0x5e, 0x2b, 0x01,
11692 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
11693 0x1c, 0xfe, 0xff, 0x7f,
11694 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00,
11695 0x57, 0x48, 0x8b, 0x1c,
11696 0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02,
11697 0x00, 0x57, 0x48, 0x8b,
11698 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
11699 0x03, 0x0a, 0x50, 0x01,
11700 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00,
11701 0x54, 0xfe, 0x00, 0xf4,
11702 0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe,
11703 0x03, 0x7c, 0x63, 0x27,
11704 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
11705 0xfe, 0x82, 0x4a, 0xfe,
11706 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe,
11707 0x42, 0x48, 0x5f, 0x60,
11708 0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08,
11709 0x1f, 0xfe, 0xa2, 0x14,
11710 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
11711 0xcc, 0x12, 0x49, 0x04,
11712 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe,
11713 0xe8, 0x13, 0x3b, 0x13,
11714 0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55,
11715 0xa1, 0xff, 0x02, 0x83,
11716 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
11717 0x13, 0x06, 0xfe, 0x56,
11718 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe,
11719 0x64, 0x00, 0x17, 0x93,
11720 0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe,
11721 0xc8, 0x00, 0x8e, 0xe4,
11722 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
11723 0x01, 0xba, 0xfe, 0x4e,
11724 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0,
11725 0xfe, 0x60, 0x14, 0xfe,
11726 0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01,
11727 0xfe, 0x22, 0x13, 0x1c,
11728 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
11729 0xfe, 0x9c, 0x14, 0xb7,
11730 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba,
11731 0xfe, 0x9c, 0x14, 0xb7,
11732 0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06,
11733 0xfe, 0xb4, 0x56, 0xfe,
11734 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
11735 0xe5, 0x15, 0x0b, 0x01,
11736 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89,
11737 0x49, 0x01, 0x08, 0x03,
11738 0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6,
11739 0x15, 0x06, 0x01, 0x08,
11740 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
11741 0x4a, 0x01, 0x08, 0x03,
11742 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc,
11743 0xfe, 0x49, 0xf4, 0x00,
11744 0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01,
11745 0x08, 0x2f, 0x07, 0xfe,
11746 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
11747 0x01, 0x43, 0x1e, 0xcd,
11748 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e,
11749 0xed, 0x88, 0x07, 0x10,
11750 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a,
11751 0x80, 0x01, 0x0e, 0x88,
11752 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
11753 0x88, 0x03, 0x0a, 0x42,
11754 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e,
11755 0xfe, 0x80, 0x80, 0xf2,
11756 0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51,
11757 0x01, 0x82, 0x03, 0x17,
11758 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
11759 0xfe, 0x24, 0x1c, 0xfe,
11760 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0,
11761 0x91, 0x1d, 0x66, 0xfe,
11762 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe,
11763 0xda, 0x10, 0x17, 0x10,
11764 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
11765 0x05, 0xfe, 0x66, 0x01,
11766 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06,
11767 0xfe, 0x3c, 0x50, 0x66,
11768 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe,
11769 0x40, 0x16, 0xfe, 0xb6,
11770 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
11771 0x10, 0x71, 0xfe, 0x83,
11772 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90,
11773 0xfe, 0x62, 0x16, 0xfe,
11774 0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19,
11775 0xfe, 0x98, 0xe7, 0x00,
11776 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
11777 0xfe, 0x30, 0xbc, 0xfe,
11778 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
11779 0xc5, 0x90, 0xfe, 0x9a,
11780 0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe,
11781 0x42, 0x10, 0xfe, 0x02,
11782 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
11783 0xfe, 0x1d, 0xf7, 0x4f,
11784 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f,
11785 0x47, 0xfe, 0x83, 0x58,
11786 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11,
11787 0xfe, 0xdd, 0x00, 0x63,
11788 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
11789 0x06, 0x37, 0x95, 0xa9,
11790 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e,
11791 0x18, 0x1c, 0x1a, 0x5d,
11792 0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe,
11793 0xe1, 0x10, 0x78, 0x2c,
11794 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
11795 0x13, 0x3c, 0x8a, 0x0a,
11796 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
11797 0xe3, 0xfe, 0x00, 0xcc,
11798 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01,
11799 0x0e, 0xf2, 0x01, 0x6f,
11800 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
11801 0xf6, 0xfe, 0xd6, 0xf0,
11802 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe,
11803 0x15, 0x00, 0x59, 0x76,
11804 0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35,
11805 0x11, 0x2d, 0x01, 0x6f,
11806 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
11807 0xc8, 0xfe, 0x48, 0x55,
11808 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a,
11809 0x99, 0x01, 0x0e, 0xf0,
11810 0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73,
11811 0x75, 0x03, 0x0a, 0x42,
11812 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
11813 0x0e, 0x73, 0x75, 0x03,
11814 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00,
11815 0xfe, 0x3a, 0x45, 0x5b,
11816 0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00,
11817 0xfe, 0x02, 0xe6, 0x1b,
11818 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
11819 0xfe, 0x94, 0x00, 0xfe,
11820 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02,
11821 0xe6, 0x2c, 0xfe, 0x4e,
11822 0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69,
11823 0x03, 0x07, 0x7a, 0xfe,
11824 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
11825 0x07, 0x1b, 0xfe, 0x5a,
11826 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d,
11827 0x24, 0x2c, 0xdc, 0x07,
11828 0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d,
11829 0x9f, 0xad, 0x03, 0x14,
11830 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
11831 0x03, 0x25, 0xfe, 0xca,
11832 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a,
11833 0x00, 0x00,
11836 static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
11837 static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
11839 /* Microcode buffer is kept after initialization for error recovery. */
11840 static unsigned char _adv_asc38C0800_buf[] = {
11841 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
11842 0x01, 0x00, 0x48, 0xe4,
11843 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff,
11844 0x1c, 0x0f, 0x00, 0xf6,
11845 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6,
11846 0x09, 0xe7, 0x55, 0xf0,
11847 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
11848 0x18, 0xf4, 0x08, 0x00,
11849 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6,
11850 0x86, 0xf0, 0xb1, 0xf0,
11851 0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c,
11852 0x3c, 0x00, 0xbb, 0x00,
11853 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
11854 0xba, 0x13, 0x18, 0x40,
11855 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01,
11856 0x6e, 0x01, 0x74, 0x01,
11857 0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00,
11858 0xc0, 0x00, 0x01, 0x01,
11859 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
11860 0x08, 0x12, 0x02, 0x4a,
11861 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4,
11862 0x5d, 0xf0, 0x02, 0xfa,
11863 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01,
11864 0x68, 0x01, 0x6a, 0x01,
11865 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
11866 0x06, 0x13, 0x4c, 0x1c,
11867 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00,
11868 0x0f, 0x00, 0x47, 0x00,
11869 0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c,
11870 0x4e, 0x1c, 0x10, 0x44,
11871 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
11872 0x05, 0x00, 0x34, 0x00,
11873 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b,
11874 0x42, 0x0c, 0x12, 0x0f,
11875 0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48,
11876 0x00, 0x4e, 0x42, 0x54,
11877 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
11878 0x59, 0xf0, 0xb8, 0xf0,
11879 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00,
11880 0x19, 0x00, 0x33, 0x00,
11881 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00,
11882 0xe7, 0x00, 0xe2, 0x03,
11883 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
11884 0x12, 0x13, 0x24, 0x14,
11885 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c,
11886 0x36, 0x1c, 0x08, 0x44,
11887 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54,
11888 0x3a, 0x55, 0x83, 0x55,
11889 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
11890 0x0c, 0xf0, 0x04, 0xf8,
11891 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00,
11892 0xa8, 0x00, 0xaa, 0x00,
11893 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01,
11894 0xc4, 0x01, 0xc6, 0x01,
11895 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
11896 0x68, 0x08, 0x69, 0x08,
11897 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10,
11898 0xed, 0x10, 0xf1, 0x10,
11899 0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13,
11900 0x1e, 0x13, 0x46, 0x14,
11901 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
11902 0xca, 0x18, 0xe6, 0x19,
11903 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c,
11904 0xf0, 0x2b, 0x02, 0xfe,
11905 0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6,
11906 0xfe, 0x84, 0x01, 0xff,
11907 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
11908 0x00, 0xfe, 0x57, 0x24,
11909 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09,
11910 0x00, 0x00, 0xff, 0x08,
11911 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
11912 0xff, 0xff, 0xff, 0x11,
11913 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
11914 0xfe, 0x04, 0xf7, 0xd6,
11915 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99,
11916 0x0a, 0x42, 0x2c, 0xfe,
11917 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0,
11918 0xfe, 0xf4, 0x01, 0xfe,
11919 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
11920 0x02, 0xfe, 0xc8, 0x0d,
11921 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
11922 0x1c, 0x03, 0xfe, 0xa6,
11923 0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48,
11924 0xf0, 0xfe, 0x8a, 0x02,
11925 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
11926 0xfe, 0x46, 0xf0, 0xfe,
11927 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
11928 0x48, 0x02, 0xfe, 0x44,
11929 0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a,
11930 0xaa, 0x18, 0x06, 0x14,
11931 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
11932 0x1e, 0x1c, 0xfe, 0xe9,
11933 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce,
11934 0x09, 0x70, 0x01, 0xa8,
11935 0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70,
11936 0x01, 0x87, 0xfe, 0xbd,
11937 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
11938 0x58, 0x1c, 0x18, 0x06,
11939 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23,
11940 0xfe, 0x98, 0x02, 0xfe,
11941 0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2,
11942 0x01, 0xfe, 0x48, 0x10,
11943 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
11944 0x69, 0x10, 0x18, 0x06,
11945 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05,
11946 0xf6, 0xce, 0x01, 0xfe,
11947 0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe,
11948 0x82, 0x16, 0x02, 0x2b,
11949 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
11950 0xfe, 0x41, 0x58, 0x09,
11951 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe,
11952 0x82, 0x16, 0x02, 0x2b,
11953 0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43,
11954 0xfe, 0x77, 0x57, 0xfe,
11955 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
11956 0xfe, 0x40, 0x1c, 0x1c,
11957 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48,
11958 0x03, 0xfe, 0x11, 0xf0,
11959 0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10,
11960 0xfe, 0x11, 0x00, 0x02,
11961 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
11962 0x21, 0x22, 0xa3, 0xb7,
11963 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16,
11964 0x12, 0xd1, 0x1c, 0xd9,
11965 0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12,
11966 0xfe, 0xe4, 0x00, 0x27,
11967 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
11968 0x06, 0xf0, 0xfe, 0xc8,
11969 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03,
11970 0x70, 0x28, 0x17, 0xfe,
11971 0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8,
11972 0xf9, 0x2c, 0x99, 0x19,
11973 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
11974 0x74, 0x01, 0xaf, 0x8c,
11975 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e,
11976 0x8d, 0x51, 0x64, 0x79,
11977 0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b,
11978 0xfe, 0x6a, 0x02, 0x02,
11979 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
11980 0xfe, 0x3c, 0x04, 0x3b,
11981 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02,
11982 0x00, 0x10, 0x01, 0x0b,
11983 0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde,
11984 0xfe, 0x4c, 0x44, 0xfe,
11985 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
11986 0xda, 0x4f, 0x79, 0x2a,
11987 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b,
11988 0xfe, 0x2a, 0x13, 0x32,
11989 0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c,
11990 0x54, 0x6b, 0xda, 0xfe,
11991 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
11992 0x08, 0x13, 0x32, 0x07,
11993 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d,
11994 0x08, 0x05, 0x06, 0x4d,
11995 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24,
11996 0x2d, 0x12, 0xfe, 0xe6,
11997 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
11998 0x02, 0x2b, 0xfe, 0x42,
11999 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
12000 0xfe, 0x87, 0x80, 0xfe,
12001 0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80,
12002 0x07, 0x19, 0xfe, 0x7c,
12003 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
12004 0x17, 0xfe, 0x90, 0x05,
12005 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe,
12006 0xa0, 0x00, 0x28, 0xfe,
12007 0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c,
12008 0x34, 0xfe, 0x89, 0x48,
12009 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
12010 0x12, 0xfe, 0xe3, 0x00,
12011 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
12012 0x70, 0x05, 0x88, 0x25,
12013 0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe,
12014 0x09, 0x48, 0xff, 0x02,
12015 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
12016 0x08, 0x53, 0x05, 0xcb,
12017 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08,
12018 0x05, 0x1b, 0xfe, 0x22,
12019 0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe,
12020 0x0d, 0x00, 0x01, 0x36,
12021 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
12022 0x03, 0x5c, 0x28, 0xfe,
12023 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53,
12024 0x05, 0x1f, 0xfe, 0x02,
12025 0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5,
12026 0x01, 0x4b, 0x12, 0xfe,
12027 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
12028 0x12, 0x03, 0x45, 0x28,
12029 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe,
12030 0x43, 0x48, 0xc4, 0xcc,
12031 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4,
12032 0x6e, 0x41, 0x01, 0xb2,
12033 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
12034 0xfe, 0xcc, 0x15, 0x1d,
12035 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03,
12036 0x45, 0xc1, 0x0c, 0x45,
12037 0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe,
12038 0xe2, 0x00, 0x27, 0xdb,
12039 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
12040 0xfe, 0x06, 0xf0, 0xfe,
12041 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12,
12042 0x16, 0x19, 0x01, 0x0b,
12043 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
12044 0xfe, 0x99, 0xa4, 0x01,
12045 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
12046 0x12, 0x08, 0x05, 0x1a,
12047 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
12048 0x0b, 0x16, 0x00, 0x01,
12049 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02,
12050 0xe2, 0x6c, 0x58, 0xbe,
12051 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
12052 0xfe, 0x09, 0x6f, 0xba,
12053 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27,
12054 0xfe, 0x54, 0x07, 0x1c,
12055 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c,
12056 0x07, 0x02, 0x24, 0x01,
12057 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
12058 0x2c, 0x90, 0xfe, 0xae,
12059 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a,
12060 0x37, 0x22, 0x20, 0x07,
12061 0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a,
12062 0xfe, 0x06, 0x10, 0xfe,
12063 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
12064 0x37, 0x01, 0xb3, 0xb8,
12065 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a,
12066 0x50, 0xfe, 0x44, 0x51,
12067 0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e,
12068 0x14, 0x5f, 0xfe, 0x0c,
12069 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
12070 0x14, 0x3e, 0xfe, 0x4a,
12071 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
12072 0x90, 0x0c, 0x60, 0x14,
12073 0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62,
12074 0xfe, 0x44, 0x90, 0xfe,
12075 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
12076 0x0c, 0x5e, 0x14, 0x5f,
12077 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e,
12078 0x14, 0x3c, 0x21, 0x0c,
12079 0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11,
12080 0x27, 0xdd, 0xfe, 0x9e,
12081 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
12082 0x9a, 0x08, 0xc6, 0xfe,
12083 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08,
12084 0x95, 0x86, 0x02, 0x24,
12085 0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05,
12086 0x06, 0xfe, 0x10, 0x12,
12087 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
12088 0x1c, 0x02, 0xfe, 0x18,
12089 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe,
12090 0x2c, 0x1c, 0xfe, 0xaa,
12091 0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe,
12092 0xde, 0x09, 0xfe, 0xb7,
12093 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
12094 0xfe, 0xf1, 0x18, 0xfe,
12095 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe,
12096 0x14, 0x59, 0xfe, 0x95,
12097 0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0,
12098 0xfe, 0xf0, 0x08, 0xb5,
12099 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
12100 0x0b, 0xb6, 0xfe, 0xbf,
12101 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c,
12102 0x12, 0xc2, 0xfe, 0xd2,
12103 0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e,
12104 0x06, 0x17, 0x85, 0xc5,
12105 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
12106 0x9d, 0x01, 0x36, 0x10,
12107 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe,
12108 0x98, 0x80, 0xfe, 0x19,
12109 0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18,
12110 0xfe, 0x44, 0x54, 0xbe,
12111 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
12112 0x02, 0x4a, 0x08, 0x05,
12113 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e,
12114 0x9c, 0x3c, 0xfe, 0x6c,
12115 0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f,
12116 0x3b, 0x40, 0x03, 0x49,
12117 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
12118 0x8f, 0xfe, 0xe3, 0x54,
12119 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe,
12120 0xda, 0x09, 0xfe, 0x8b,
12121 0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa,
12122 0x0a, 0x3a, 0x49, 0x3b,
12123 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
12124 0xad, 0xfe, 0x01, 0x59,
12125 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a,
12126 0x49, 0x8f, 0xfe, 0xe3,
12127 0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02,
12128 0x4a, 0x3a, 0x49, 0x3b,
12129 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
12130 0x02, 0x4a, 0x08, 0x05,
12131 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62,
12132 0xb7, 0xfe, 0x03, 0xa1,
12133 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
12134 0xfe, 0x86, 0x91, 0x6a,
12135 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
12136 0x61, 0x0c, 0x7f, 0x14,
12137 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62,
12138 0x9b, 0x2e, 0x9c, 0x3c,
12139 0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05,
12140 0xfa, 0x3c, 0x01, 0xef,
12141 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
12142 0xe4, 0x08, 0x05, 0x1f,
12143 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37,
12144 0x03, 0x5e, 0x29, 0x5f,
12145 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe,
12146 0xf4, 0x09, 0x08, 0x05,
12147 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
12148 0x81, 0x50, 0xfe, 0x10,
12149 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe,
12150 0x08, 0x09, 0x12, 0xa6,
12151 0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe,
12152 0x08, 0x09, 0xfe, 0x0c,
12153 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
12154 0x08, 0x05, 0x0a, 0xfe,
12155 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1,
12156 0xf0, 0xe2, 0x15, 0x7e,
12157 0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19,
12158 0x57, 0x3d, 0xfe, 0xed,
12159 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
12160 0x00, 0xff, 0x35, 0xfe,
12161 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18,
12162 0x1e, 0x19, 0x8a, 0x03,
12163 0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65,
12164 0xfe, 0xd1, 0xf0, 0xfe,
12165 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
12166 0x10, 0xfe, 0xce, 0xf0,
12167 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b,
12168 0x10, 0xfe, 0x22, 0x00,
12169 0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00,
12170 0x02, 0x65, 0xfe, 0xd0,
12171 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
12172 0x0b, 0x10, 0x58, 0xfe,
12173 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe,
12174 0x12, 0x00, 0x2c, 0x0f,
12175 0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14,
12176 0x0c, 0xbc, 0x17, 0x34,
12177 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
12178 0x0c, 0x1c, 0x34, 0x94,
12179 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01,
12180 0x4b, 0xfe, 0xdb, 0x10,
12181 0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe,
12182 0x89, 0xf0, 0x24, 0x33,
12183 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
12184 0x33, 0x31, 0xdf, 0xbc,
12185 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49,
12186 0x17, 0xfe, 0x2c, 0x0d,
12187 0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54,
12188 0x12, 0x55, 0xfe, 0x28,
12189 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
12190 0x44, 0xfe, 0x28, 0x00,
12191 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26,
12192 0x0f, 0x64, 0x12, 0x2f,
12193 0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44,
12194 0x0a, 0xfe, 0xb4, 0x10,
12195 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
12196 0xfe, 0x34, 0x46, 0xac,
12197 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a,
12198 0x37, 0x01, 0xf5, 0x01,
12199 0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02,
12200 0xfe, 0x2e, 0x03, 0x08,
12201 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
12202 0x1a, 0xfe, 0x58, 0x12,
12203 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
12204 0xfe, 0x50, 0x0d, 0xfe,
12205 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37,
12206 0xfe, 0xa9, 0x10, 0x10,
12207 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
12208 0xfe, 0x13, 0x00, 0xfe,
12209 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe,
12210 0x24, 0x00, 0x8c, 0xb5,
12211 0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a,
12212 0xfe, 0x9d, 0x41, 0xfe,
12213 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
12214 0xb4, 0x15, 0xfe, 0x31,
12215 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06,
12216 0xec, 0xd0, 0xfc, 0x44,
12217 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47,
12218 0x4b, 0x91, 0xfe, 0x75,
12219 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
12220 0x0e, 0xfe, 0x44, 0x48,
12221 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41,
12222 0xfe, 0x41, 0x58, 0x09,
12223 0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe,
12224 0x2e, 0x03, 0x09, 0x5d,
12225 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
12226 0xce, 0x47, 0xfe, 0xad,
12227 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13,
12228 0x59, 0x13, 0x9f, 0x13,
12229 0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe,
12230 0xe0, 0x0e, 0x0f, 0x06,
12231 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
12232 0x3a, 0x01, 0x56, 0xfe,
12233 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec,
12234 0x20, 0x4f, 0xfe, 0x05,
12235 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe,
12236 0x48, 0xf4, 0x0d, 0xfe,
12237 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
12238 0x15, 0x1a, 0x39, 0xa0,
12239 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff,
12240 0x0c, 0xfe, 0x60, 0x01,
12241 0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25,
12242 0x06, 0x13, 0x2f, 0x12,
12243 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
12244 0x22, 0x9f, 0xb7, 0x13,
12245 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39,
12246 0xa0, 0xb4, 0xfe, 0xd9,
12247 0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04,
12248 0xc3, 0xfe, 0x03, 0xdc,
12249 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
12250 0xfe, 0x00, 0xcc, 0x04,
12251 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13,
12252 0xfe, 0x1c, 0x80, 0x07,
12253 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae,
12254 0xfe, 0x0c, 0x90, 0xfe,
12255 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
12256 0x0a, 0xfe, 0x3c, 0x50,
12257 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4,
12258 0x16, 0x08, 0x05, 0x1b,
12259 0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58,
12260 0xfe, 0x2c, 0x13, 0x01,
12261 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
12262 0x0c, 0xfe, 0x64, 0x01,
12263 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03,
12264 0x80, 0x8d, 0xfe, 0x01,
12265 0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64,
12266 0x22, 0x20, 0xfb, 0x79,
12267 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
12268 0x03, 0xfe, 0xae, 0x00,
12270 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe,
12271 0xb2, 0x00, 0xfe, 0x09,
12272 0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c,
12273 0x45, 0x0f, 0x46, 0x52,
12274 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
12275 0x0f, 0x44, 0x11, 0x0f,
12276 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4,
12277 0x25, 0x11, 0x13, 0x20,
12278 0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14,
12279 0x56, 0xfe, 0xd6, 0xf0,
12280 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
12281 0x18, 0x1c, 0x04, 0x42,
12282 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe,
12283 0xf5, 0x13, 0x04, 0x01,
12284 0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
12285 0x13, 0x32, 0x07, 0x2f,
12286 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
12287 0x41, 0x48, 0xfe, 0x45,
12288 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78,
12289 0x07, 0x11, 0xac, 0x09,
12290 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07,
12291 0x82, 0x4e, 0xfe, 0x14,
12292 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
12293 0xfe, 0x01, 0xec, 0xa2,
12294 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79,
12295 0x2a, 0x01, 0xe3, 0xfe,
12296 0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a,
12297 0xfe, 0x48, 0x12, 0x07,
12298 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
12299 0xfe, 0x32, 0x12, 0x07,
12300 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07,
12301 0x1f, 0xfe, 0x12, 0x12,
12302 0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b,
12303 0x94, 0x4b, 0x04, 0x2d,
12304 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
12305 0x32, 0x07, 0xa6, 0xfe,
12306 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05,
12307 0x5a, 0xfe, 0x72, 0x12,
12308 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62,
12309 0xfe, 0x26, 0x13, 0x03,
12310 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
12311 0x0c, 0x7f, 0x0c, 0x80,
12312 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c,
12313 0x3c, 0xfe, 0x04, 0x55,
12314 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe,
12315 0x91, 0x10, 0x03, 0x3f,
12316 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
12317 0x88, 0x9b, 0x2e, 0x9c,
12318 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
12319 0x56, 0x0c, 0x5e, 0x14,
12320 0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40,
12321 0x03, 0x60, 0x29, 0x61,
12322 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
12323 0x50, 0xfe, 0xc6, 0x50,
12324 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d,
12325 0x29, 0x3e, 0xfe, 0x40,
12326 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72,
12327 0x2d, 0x01, 0x0b, 0x1d,
12328 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
12329 0x72, 0x01, 0xaf, 0x1e,
12330 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe,
12331 0x0a, 0x55, 0x35, 0xfe,
12332 0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51,
12333 0x02, 0x72, 0xfe, 0x19,
12334 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
12335 0x1d, 0xe8, 0x33, 0x31,
12336 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01,
12337 0x0b, 0x1c, 0x34, 0x1d,
12338 0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8,
12339 0x33, 0x31, 0xfe, 0xe8,
12340 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
12341 0x05, 0x1f, 0x35, 0xa9,
12342 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda,
12343 0x14, 0x01, 0xaf, 0x8c,
12344 0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a,
12345 0x03, 0x45, 0x28, 0x35,
12346 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
12347 0x03, 0x5c, 0xc1, 0x0c,
12348 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02,
12349 0x89, 0x01, 0x0b, 0x1c,
12350 0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1,
12351 0xfe, 0x42, 0x58, 0xf1,
12352 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
12353 0xf4, 0x06, 0xea, 0x32,
12354 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d,
12355 0x01, 0x0b, 0x26, 0x89,
12356 0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13,
12357 0x26, 0xfe, 0xd4, 0x13,
12358 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
12359 0x13, 0x1c, 0xfe, 0xd0,
12360 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10,
12361 0x0f, 0x71, 0xff, 0x02,
12362 0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe,
12363 0x00, 0x5c, 0x04, 0x0f,
12364 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
12365 0xfe, 0x00, 0x5c, 0x04,
12366 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff,
12367 0x02, 0x00, 0x57, 0x52,
12368 0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01,
12369 0x87, 0x04, 0xfe, 0x03,
12370 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
12371 0xfe, 0x00, 0x7d, 0xfe,
12372 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e,
12373 0x14, 0x5f, 0x57, 0x3f,
12374 0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83,
12375 0x5a, 0x8d, 0x04, 0x01,
12376 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
12377 0xfe, 0x96, 0x15, 0x33,
12378 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8,
12379 0x0a, 0xfe, 0xc1, 0x59,
12380 0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13,
12381 0x21, 0x69, 0x1a, 0xee,
12382 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
12383 0x30, 0xfe, 0x78, 0x10,
12384 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae,
12385 0x98, 0xfe, 0x30, 0x00,
12386 0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed,
12387 0x98, 0xfe, 0x64, 0x00,
12388 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
12389 0x10, 0x69, 0x06, 0xfe,
12390 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00,
12391 0x18, 0x59, 0x0f, 0x06,
12392 0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe,
12393 0x43, 0xf4, 0x9f, 0xfe,
12394 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
12395 0x9e, 0xfe, 0xf3, 0x10,
12396 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00,
12397 0x17, 0xfe, 0x4d, 0xe4,
12398 0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00,
12399 0x17, 0xfe, 0x4d, 0xe4,
12400 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
12401 0xf4, 0x00, 0xe9, 0x91,
12402 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a,
12403 0x04, 0x16, 0x06, 0x01,
12404 0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01,
12405 0x0b, 0x26, 0xf3, 0x76,
12406 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
12407 0x16, 0x19, 0x01, 0x0b,
12408 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01,
12409 0x0b, 0x26, 0xb1, 0x76,
12410 0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06,
12411 0xfe, 0x48, 0x13, 0xb8,
12412 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
12413 0xec, 0xfe, 0x27, 0x01,
12414 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32,
12415 0x07, 0xfe, 0xe3, 0x00,
12416 0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b,
12417 0x22, 0xd4, 0x07, 0x06,
12418 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
12419 0x07, 0x11, 0xae, 0x09,
12420 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01,
12421 0x0e, 0x8e, 0xfe, 0x80,
12422 0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04,
12423 0x09, 0x48, 0x01, 0x0e,
12424 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
12425 0x80, 0xfe, 0x80, 0x4c,
12426 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c,
12427 0x09, 0x5d, 0x01, 0x87,
12428 0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe,
12429 0x19, 0xde, 0xfe, 0x24,
12430 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
12431 0x17, 0xad, 0x9a, 0x1b,
12432 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde,
12433 0x16, 0xfe, 0xda, 0x10,
12434 0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe,
12435 0x18, 0x58, 0x03, 0xfe,
12436 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
12437 0xf4, 0x06, 0xfe, 0x3c,
12438 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f,
12439 0x97, 0xfe, 0x38, 0x17,
12440 0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c,
12441 0x10, 0x18, 0x11, 0x75,
12442 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
12443 0x2e, 0x97, 0xfe, 0x5a,
12444 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19,
12445 0xfe, 0x98, 0xe7, 0x00,
12446 0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75,
12447 0xfe, 0x30, 0xbc, 0xfe,
12448 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
12449 0xcb, 0x97, 0xfe, 0x92,
12450 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe,
12451 0x42, 0x10, 0xfe, 0x02,
12452 0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe,
12453 0x03, 0xa1, 0xfe, 0x1d,
12454 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
12455 0x9a, 0x5b, 0x41, 0xfe,
12456 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7,
12457 0x11, 0x12, 0xfe, 0xdd,
12458 0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8,
12459 0x17, 0x15, 0x06, 0x39,
12460 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
12461 0xfe, 0x7e, 0x18, 0x1e,
12462 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef,
12463 0x12, 0xfe, 0xe1, 0x10,
12464 0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42,
12465 0x13, 0x42, 0x92, 0x09,
12466 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
12467 0xf0, 0xfe, 0x00, 0xcc,
12468 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01,
12469 0x0e, 0xfe, 0x80, 0x4c,
12470 0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe,
12471 0x24, 0x12, 0xfe, 0x14,
12472 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
12473 0xe7, 0x0a, 0x10, 0xfe,
12474 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92,
12475 0x08, 0x54, 0x1b, 0x37,
12476 0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba,
12477 0x90, 0x3a, 0xce, 0x3b,
12478 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
12479 0x13, 0xa3, 0x04, 0x09,
12480 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49,
12481 0x44, 0x17, 0xfe, 0xe8,
12482 0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09,
12483 0x5d, 0x01, 0xa8, 0x09,
12484 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
12485 0x1c, 0x19, 0x03, 0xfe,
12486 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9,
12487 0x6b, 0xfe, 0x2e, 0x19,
12488 0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4,
12489 0xfe, 0x0b, 0x00, 0x6b,
12490 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
12491 0x08, 0x10, 0x03, 0xfe,
12492 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff,
12493 0x04, 0x68, 0x54, 0xe7,
12494 0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe,
12495 0x1a, 0xf4, 0xfe, 0x00,
12496 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
12497 0x04, 0x07, 0x7e, 0xfe,
12498 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
12499 0x07, 0x1a, 0xfe, 0x5a,
12500 0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66,
12501 0x25, 0x6d, 0xe5, 0x07,
12502 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
12503 0xa9, 0xb8, 0x04, 0x15,
12504 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe,
12505 0x40, 0x5c, 0x04, 0x1c,
12506 0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b,
12507 0xf7, 0xfe, 0x82, 0xf0,
12508 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
12511 static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
12512 static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
12514 /* Microcode buffer is kept after initialization for error recovery. */
12515 static unsigned char _adv_asc38C1600_buf[] = {
12516 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
12517 0x18, 0xe4, 0x01, 0x00,
12518 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00,
12519 0x07, 0x17, 0xc0, 0x5f,
12520 0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7,
12521 0x85, 0xf0, 0x86, 0xf0,
12522 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
12523 0x98, 0x57, 0x01, 0xe6,
12524 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d,
12525 0x38, 0x54, 0x32, 0xf0,
12526 0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4,
12527 0x00, 0xe6, 0xb1, 0xf0,
12528 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
12529 0x06, 0x13, 0x0c, 0x1c,
12530 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12,
12531 0xb9, 0x54, 0x00, 0x80,
12532 0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56,
12533 0x03, 0xe6, 0x01, 0xea,
12534 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
12535 0x04, 0x13, 0xbb, 0x55,
12536 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00,
12537 0xbb, 0x00, 0xc0, 0x00,
12538 0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12,
12539 0x4c, 0x1c, 0x4e, 0x1c,
12540 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
12541 0x24, 0x01, 0x3c, 0x01,
12542 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01,
12543 0x78, 0x01, 0x7c, 0x01,
12544 0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c,
12545 0x6e, 0x1e, 0x02, 0x48,
12546 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
12547 0x03, 0xfc, 0x06, 0x00,
12548 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a,
12549 0x30, 0x1c, 0x38, 0x1c,
12550 0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea,
12551 0x5d, 0xf0, 0xa7, 0xf0,
12552 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
12553 0x33, 0x00, 0x34, 0x00,
12554 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01,
12555 0x79, 0x01, 0x3c, 0x09,
12556 0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13,
12557 0x40, 0x16, 0x50, 0x16,
12558 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
12559 0x05, 0xf0, 0x09, 0xf0,
12560 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00,
12561 0x9c, 0x00, 0xa4, 0x00,
12562 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08,
12563 0xe9, 0x09, 0x5c, 0x0c,
12564 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
12565 0x42, 0x1d, 0x08, 0x44,
12566 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54,
12567 0x83, 0x55, 0x83, 0x59,
12568 0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0,
12569 0x4b, 0xf4, 0x04, 0xf8,
12570 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
12571 0xa8, 0x00, 0xaa, 0x00,
12572 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01,
12573 0x7a, 0x01, 0x82, 0x01,
12574 0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07,
12575 0x68, 0x08, 0x10, 0x0d,
12576 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
12577 0xf3, 0x10, 0x06, 0x12,
12578 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c,
12579 0xf0, 0x35, 0x05, 0xfe,
12580 0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8,
12581 0xfe, 0x88, 0x01, 0xff,
12582 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
12583 0x00, 0xfe, 0x57, 0x24,
12584 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09,
12585 0x00, 0x00, 0xff, 0x08,
12586 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
12587 0xff, 0xff, 0xff, 0x13,
12588 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
12589 0xfe, 0x04, 0xf7, 0xe8,
12590 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d,
12591 0x0d, 0x51, 0x37, 0xfe,
12592 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0,
12593 0xfe, 0xf8, 0x01, 0xfe,
12594 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
12595 0x05, 0xfe, 0x08, 0x0f,
12596 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe,
12597 0x28, 0x1c, 0x03, 0xfe,
12598 0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe,
12599 0x48, 0xf0, 0xfe, 0x90,
12600 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
12601 0x02, 0xfe, 0x46, 0xf0,
12602 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0,
12603 0xfe, 0x4e, 0x02, 0xfe,
12604 0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c,
12605 0x0d, 0xa2, 0x1c, 0x07,
12606 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
12607 0x1c, 0xf5, 0xfe, 0x1e,
12608 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc,
12609 0xde, 0x0a, 0x81, 0x01,
12610 0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a,
12611 0x81, 0x01, 0x5c, 0xfe,
12612 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
12613 0xfe, 0x58, 0x1c, 0x1c,
12614 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02,
12615 0x2b, 0xfe, 0x9e, 0x02,
12616 0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30,
12617 0x00, 0x47, 0xb8, 0x01,
12618 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
12619 0x1a, 0x31, 0xfe, 0x69,
12620 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe,
12621 0x1e, 0x1e, 0x20, 0x2c,
12622 0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a,
12623 0x44, 0x15, 0x56, 0x51,
12624 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
12625 0x01, 0x18, 0x09, 0x00,
12626 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01,
12627 0x18, 0xfe, 0xc8, 0x54,
12628 0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60,
12629 0xfe, 0x02, 0xe8, 0x30,
12630 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
12631 0xfe, 0xe4, 0x01, 0xfe,
12632 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe,
12633 0x26, 0xf0, 0xfe, 0x66,
12634 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe,
12635 0xef, 0x10, 0xfe, 0x9f,
12636 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
12637 0x70, 0x37, 0xfe, 0x48,
12638 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26,
12639 0x21, 0xb9, 0xc7, 0x20,
12640 0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15,
12641 0xe1, 0x2a, 0xeb, 0xfe,
12642 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
12643 0x15, 0xfe, 0xe4, 0x00,
12644 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41,
12645 0xfe, 0x06, 0xf0, 0xfe,
12646 0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29,
12647 0x03, 0x81, 0x1e, 0x1b,
12648 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
12649 0xea, 0xfe, 0x46, 0x1c,
12650 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
12651 0xfe, 0x48, 0x1c, 0x75,
12652 0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a,
12653 0xe1, 0x01, 0x18, 0x77,
12654 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
12655 0x8f, 0xfe, 0x70, 0x02,
12656 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04,
12657 0x16, 0xfe, 0x4a, 0x04,
12658 0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff,
12659 0x02, 0x00, 0x10, 0x01,
12660 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
12661 0xee, 0xfe, 0x4c, 0x44,
12662 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54,
12663 0x7b, 0xec, 0x60, 0x8d,
12664 0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01,
12665 0x0c, 0x06, 0x28, 0xfe,
12666 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
12667 0x13, 0x34, 0xfe, 0x4c,
12668 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54,
12669 0x13, 0x01, 0x0c, 0x06,
12670 0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06,
12671 0x28, 0xf9, 0x1f, 0x7f,
12672 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
12673 0xfe, 0xa4, 0x0e, 0x05,
12674 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe,
12675 0x9c, 0x93, 0x3a, 0x0b,
12676 0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b,
12677 0x7d, 0x1d, 0xfe, 0x46,
12678 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
12679 0xfe, 0x87, 0x83, 0xfe,
12680 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98,
12681 0x13, 0x0f, 0xfe, 0x20,
12682 0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84,
12683 0x12, 0x01, 0x38, 0x06,
12684 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
12685 0x05, 0xd0, 0x54, 0x01,
12686 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe,
12687 0x50, 0x12, 0x5e, 0xff,
12688 0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02,
12689 0x00, 0x10, 0x2f, 0xfe,
12690 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
12691 0x38, 0xfe, 0x4a, 0xf0,
12692 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe,
12693 0x21, 0x00, 0xf1, 0x2e,
12694 0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00,
12695 0x10, 0x2f, 0xfe, 0xd0,
12696 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
12697 0x1c, 0x00, 0x4d, 0x01,
12698 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06,
12699 0x28, 0xfe, 0x24, 0x12,
12700 0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe,
12701 0x0d, 0x00, 0x01, 0x42,
12702 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
12703 0x03, 0xb6, 0x1e, 0xfe,
12704 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17,
12705 0xfe, 0x72, 0x06, 0x0a,
12706 0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56,
12707 0x19, 0x16, 0xfe, 0x68,
12708 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
12709 0x03, 0x9a, 0x1e, 0xfe,
12710 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12,
12711 0x48, 0xfe, 0x92, 0x06,
12712 0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13,
12713 0x58, 0xff, 0x02, 0x00,
12714 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
12715 0xfe, 0xea, 0x06, 0x01,
12716 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16,
12717 0xfe, 0xe0, 0x06, 0x15,
12718 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07,
12719 0x01, 0x84, 0xfe, 0xae,
12720 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
12721 0x1e, 0xfe, 0x1a, 0x12,
12722 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
12723 0x43, 0x48, 0x62, 0x80,
12724 0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24,
12725 0x36, 0xfe, 0x02, 0xf6,
12726 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
12727 0xd0, 0x0d, 0x17, 0xfe,
12728 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20,
12729 0x9e, 0x15, 0x82, 0x01,
12730 0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58,
12731 0x57, 0x10, 0xe6, 0x05,
12732 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
12733 0xfe, 0x9c, 0x32, 0x5f,
12734 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c,
12735 0xfe, 0x0a, 0xf0, 0xfe,
12736 0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08,
12737 0xaf, 0xa0, 0x05, 0x29,
12738 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
12739 0x00, 0x01, 0x08, 0x14,
12740 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08,
12741 0x14, 0x00, 0x05, 0xfe,
12742 0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06,
12743 0x12, 0xfe, 0x30, 0x13,
12744 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
12745 0x01, 0x08, 0x14, 0x00,
12746 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a,
12747 0x78, 0x4f, 0x0f, 0xfe,
12748 0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d,
12749 0x28, 0x48, 0xfe, 0x6c,
12750 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
12751 0x12, 0x53, 0x63, 0x4e,
12752 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe,
12753 0x6c, 0x08, 0xaf, 0xa0,
12754 0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24,
12755 0x05, 0xed, 0xfe, 0x9c,
12756 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
12757 0x1e, 0xfe, 0x99, 0x58,
12758 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a,
12759 0x22, 0x6b, 0x01, 0x0c,
12760 0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e,
12761 0x1e, 0x47, 0x2c, 0x7a,
12762 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
12763 0x01, 0x0c, 0x61, 0x65,
12764 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a,
12765 0x16, 0xfe, 0x08, 0x50,
12766 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10,
12767 0x01, 0xfe, 0xce, 0x1e,
12768 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
12769 0x01, 0xfe, 0xfe, 0x1e,
12770 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a,
12771 0x10, 0x01, 0x0c, 0x06,
12772 0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e,
12773 0x10, 0x6a, 0x22, 0x6b,
12774 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
12775 0xfe, 0x9f, 0x83, 0x33,
12776 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93,
12777 0x3a, 0x0b, 0xfe, 0xc6,
12778 0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d,
12779 0x01, 0xfe, 0xce, 0x1e,
12780 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
12781 0x04, 0xfe, 0xc0, 0x93,
12782 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e,
12783 0x10, 0x4b, 0x22, 0x4c,
12784 0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe,
12785 0x4e, 0x11, 0x2f, 0xfe,
12786 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
12787 0x3c, 0x37, 0x88, 0xf5,
12788 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a,
12789 0xd3, 0xfe, 0x42, 0x0a,
12790 0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0,
12791 0x05, 0x29, 0x01, 0x41,
12792 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
12793 0xfe, 0x14, 0x12, 0x01,
12794 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe,
12795 0x2e, 0x1c, 0x05, 0xfe,
12796 0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41,
12797 0xfe, 0x2c, 0x1c, 0xfe,
12798 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
12799 0x92, 0x10, 0xc4, 0xf6,
12800 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe,
12801 0xe7, 0x10, 0xfe, 0x2b,
12802 0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12,
12803 0xac, 0xfe, 0xd2, 0xf0,
12804 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
12805 0x1b, 0xbf, 0xd4, 0x5b,
12806 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75,
12807 0x5e, 0x32, 0x1f, 0x7f,
12808 0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98,
12809 0x05, 0x70, 0xfe, 0x74,
12810 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
12811 0x0f, 0x4d, 0x01, 0xfe,
12812 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06,
12813 0x0d, 0x2b, 0xfe, 0xe2,
12814 0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24,
12815 0xfe, 0x88, 0x13, 0x21,
12816 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
12817 0x83, 0x83, 0xfe, 0xc9,
12818 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04,
12819 0x91, 0x04, 0xfe, 0x84,
12820 0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93,
12821 0xfe, 0xcb, 0x57, 0x0b,
12822 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
12823 0x6a, 0x3b, 0x6b, 0x10,
12824 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30,
12825 0x20, 0x6e, 0xdb, 0x64,
12826 0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55,
12827 0xfe, 0x04, 0xfa, 0x64,
12828 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
12829 0x10, 0x98, 0x91, 0x6c,
12830 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91,
12831 0x4b, 0x7e, 0x4c, 0x01,
12832 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10,
12833 0x58, 0xfe, 0x91, 0x58,
12834 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
12835 0x1b, 0x40, 0x01, 0x0c,
12836 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f,
12837 0xfe, 0x10, 0x90, 0x04,
12838 0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93,
12839 0x79, 0x0b, 0x0e, 0xfe,
12840 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
12841 0x01, 0x0c, 0x06, 0x0d,
12842 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe,
12843 0x0c, 0x58, 0xfe, 0x8d,
12844 0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99,
12845 0x83, 0x33, 0x0b, 0x0e,
12846 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
12847 0x19, 0xfe, 0x19, 0x41,
12848 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42,
12849 0x19, 0xfe, 0x44, 0x00,
12850 0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda,
12851 0x4c, 0xfe, 0x0c, 0x51,
12852 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
12853 0x76, 0x10, 0xac, 0xfe,
12854 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03,
12855 0xe3, 0x23, 0x07, 0xfe,
12856 0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe,
12857 0xcc, 0x0c, 0x1f, 0x92,
12858 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
12859 0x0c, 0xfe, 0x3e, 0x10,
12860 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70,
12861 0xfe, 0xcb, 0xf0, 0xfe,
12862 0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe,
12863 0xf4, 0x0c, 0x19, 0x94,
12864 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
12865 0xfe, 0xcc, 0xf0, 0xef,
12866 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe,
12867 0x4e, 0x11, 0x2f, 0xfe,
12868 0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b,
12869 0x3c, 0x37, 0x88, 0xf5,
12870 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
12871 0x2f, 0xfe, 0x3e, 0x0d,
12872 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f,
12873 0xd2, 0x9f, 0xd3, 0x9f,
12874 0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4,
12875 0xc5, 0x75, 0xd7, 0x99,
12876 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
12877 0x9c, 0x2f, 0xfe, 0x8c,
12878 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe,
12879 0x42, 0x00, 0x05, 0x70,
12880 0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06,
12881 0x0d, 0xfe, 0x44, 0x13,
12882 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
12883 0xfe, 0xda, 0x0e, 0x0a,
12884 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa,
12885 0x10, 0x01, 0xfe, 0xf4,
12886 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40,
12887 0x15, 0x56, 0x01, 0x85,
12888 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
12889 0xcc, 0x10, 0x01, 0xa7,
12890 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04,
12891 0xfe, 0x99, 0x83, 0xfe,
12892 0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe,
12893 0x43, 0x00, 0xfe, 0xa2,
12894 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
12895 0x00, 0x1d, 0x40, 0x15,
12896 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05,
12897 0xfe, 0x3a, 0x03, 0x01,
12898 0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01,
12899 0x76, 0x06, 0x12, 0xfe,
12900 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
12901 0xfe, 0x9d, 0xf0, 0xfe,
12902 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01,
12903 0x0c, 0x61, 0x12, 0x44,
12904 0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f,
12905 0xfe, 0x2e, 0x10, 0x19,
12906 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
12907 0xfe, 0x41, 0x00, 0xa2,
12908 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b,
12909 0xea, 0x4f, 0xfe, 0x04,
12910 0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05,
12911 0x35, 0xfe, 0x12, 0x1c,
12912 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
12913 0xfe, 0xd4, 0x11, 0x05,
12914 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe,
12915 0xce, 0x45, 0x31, 0x51,
12916 0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03,
12917 0x67, 0xfe, 0x98, 0x56,
12918 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
12919 0x0c, 0x06, 0x28, 0xfe,
12920 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba,
12921 0xfe, 0xfa, 0x14, 0xfe,
12922 0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67,
12923 0xfe, 0xe0, 0x14, 0xfe,
12924 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
12925 0xfe, 0xad, 0x13, 0x05,
12926 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20,
12927 0xe7, 0xfe, 0x08, 0x1c,
12928 0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe,
12929 0x48, 0x55, 0xa5, 0x3b,
12930 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
12931 0xf0, 0x1a, 0x03, 0xfe,
12932 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02,
12933 0xec, 0xe7, 0x53, 0x00,
12934 0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
12935 0x01, 0xfe, 0x62, 0x1b,
12936 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
12937 0xea, 0xe7, 0x53, 0x92,
12938 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03,
12939 0xfe, 0x38, 0x01, 0x23,
12940 0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62,
12941 0x01, 0x01, 0xfe, 0x1e,
12942 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
12943 0x26, 0x02, 0x21, 0x96,
12944 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5,
12945 0xc3, 0xfe, 0xe1, 0x10,
12946 0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf,
12947 0xfe, 0x03, 0xdc, 0xfe,
12948 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
12949 0x00, 0xcc, 0x02, 0xfe,
12950 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13,
12951 0x0f, 0xfe, 0x1c, 0x80,
12952 0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13,
12953 0x0f, 0xfe, 0x1e, 0x80,
12954 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
12955 0x1d, 0x80, 0x04, 0xfe,
12956 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee,
12957 0x1e, 0xac, 0xfe, 0x14,
12958 0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e,
12959 0x1f, 0xfe, 0x30, 0xf4,
12960 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
12961 0x56, 0xfb, 0x01, 0xfe,
12962 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01,
12963 0xfe, 0x00, 0x1d, 0x15,
12964 0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe,
12965 0x22, 0x1b, 0xfe, 0x1e,
12966 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
12967 0x96, 0x90, 0x04, 0xfe,
12968 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66,
12969 0x01, 0x01, 0x0c, 0x06,
12970 0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b,
12971 0x0e, 0x77, 0xfe, 0x01,
12972 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
12973 0x21, 0x2c, 0xfe, 0x00,
12974 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe,
12975 0x06, 0x58, 0x03, 0xfe,
12976 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58,
12977 0x03, 0xfe, 0xb2, 0x00,
12978 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
12979 0x66, 0x10, 0x55, 0x10,
12980 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91,
12981 0x54, 0x2b, 0xfe, 0x88,
12982 0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe,
12983 0x91, 0x54, 0x2b, 0xfe,
12984 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
12985 0x00, 0x40, 0x8d, 0x2c,
12986 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe,
12987 0x12, 0x1c, 0x75, 0xfe,
12988 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c,
12989 0x14, 0xfe, 0x0e, 0x47,
12990 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
12991 0xa7, 0x90, 0x34, 0x60,
12992 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80,
12993 0x09, 0x56, 0xfe, 0x34,
12994 0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48,
12995 0xfe, 0x45, 0x48, 0x01,
12996 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
12997 0x09, 0x1a, 0xa5, 0x0a,
12998 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4,
12999 0xfe, 0x14, 0x56, 0xfe,
13000 0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01,
13001 0xec, 0xb8, 0xfe, 0x9e,
13002 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
13003 0xf4, 0xfe, 0xdd, 0x10,
13004 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48,
13005 0x12, 0x09, 0x0d, 0xfe,
13006 0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4,
13007 0x13, 0x09, 0xfe, 0x23,
13008 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
13009 0x24, 0xfe, 0x12, 0x12,
13010 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08,
13011 0xae, 0x41, 0x02, 0x32,
13012 0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05,
13013 0x35, 0x32, 0x01, 0x43,
13014 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
13015 0x13, 0x01, 0x0c, 0x06,
13016 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe,
13017 0xe5, 0x55, 0xb0, 0xfe,
13018 0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e,
13019 0xfe, 0xb6, 0x0e, 0x10,
13020 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
13021 0x88, 0x20, 0x6e, 0x01,
13022 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5,
13023 0x55, 0xfe, 0x04, 0xfa,
13024 0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d,
13025 0xfe, 0x40, 0x56, 0xfe,
13026 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
13027 0x44, 0x55, 0xfe, 0xe5,
13028 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10,
13029 0x68, 0x22, 0x69, 0x01,
13030 0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b,
13031 0x6b, 0xfe, 0x2c, 0x50,
13032 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
13033 0x50, 0x03, 0x68, 0x3b,
13034 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe,
13035 0x40, 0x50, 0xfe, 0xc2,
13036 0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08,
13037 0x16, 0x3d, 0x27, 0x25,
13038 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
13039 0xa6, 0x23, 0x3f, 0x1b,
13040 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c,
13041 0xfe, 0x0a, 0x55, 0x31,
13042 0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e,
13043 0x51, 0x05, 0x72, 0x01,
13044 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
13045 0x2a, 0x3c, 0x16, 0xc0,
13046 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b,
13047 0xfe, 0x66, 0x15, 0x05,
13048 0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d,
13049 0x2b, 0x3d, 0x01, 0x08,
13050 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
13051 0xb6, 0x1e, 0x83, 0x01,
13052 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46,
13053 0x07, 0x90, 0x3f, 0x01,
13054 0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13,
13055 0x01, 0x43, 0x09, 0x82,
13056 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
13057 0x05, 0x72, 0xfe, 0xc0,
13058 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e,
13059 0x32, 0x01, 0x08, 0x17,
13060 0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16,
13061 0x3d, 0x27, 0x25, 0xbd,
13062 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
13063 0xe8, 0x14, 0x01, 0xa6,
13064 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe,
13065 0x0e, 0x12, 0x01, 0x43,
13066 0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32,
13067 0x01, 0x08, 0x17, 0x73,
13068 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
13069 0x27, 0x25, 0xbd, 0x09,
13070 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe,
13071 0xb6, 0x14, 0x86, 0xa8,
13072 0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09,
13073 0x82, 0x4e, 0x05, 0x72,
13074 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
13075 0xfe, 0xc0, 0x19, 0x05,
13076 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f,
13077 0xcc, 0x01, 0x08, 0x26,
13078 0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe,
13079 0xcc, 0x15, 0x5e, 0x32,
13080 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
13081 0xad, 0x23, 0xfe, 0xff,
13082 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02,
13083 0x00, 0x57, 0x52, 0xad,
13084 0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff,
13085 0x02, 0x00, 0x57, 0x52,
13086 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
13087 0x02, 0x13, 0x58, 0xff,
13088 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01,
13089 0x5c, 0x0a, 0x55, 0x01,
13090 0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a,
13091 0xff, 0x03, 0x00, 0x54,
13092 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
13093 0x7c, 0x3a, 0x0b, 0x0e,
13094 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19,
13095 0xfe, 0x1a, 0xf7, 0x00,
13096 0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c,
13097 0xda, 0x6d, 0x02, 0xfe,
13098 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
13099 0x02, 0x01, 0xc6, 0xfe,
13100 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27,
13101 0x25, 0xbe, 0x01, 0x08,
13102 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59,
13103 0x03, 0x9a, 0x1e, 0xfe,
13104 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
13105 0x48, 0xfe, 0x08, 0x17,
13106 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26,
13107 0x17, 0x4d, 0x13, 0x07,
13108 0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1,
13109 0xff, 0x02, 0x83, 0x55,
13110 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
13111 0x17, 0x1c, 0x63, 0x13,
13112 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64,
13113 0x00, 0xb0, 0xfe, 0x80,
13114 0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10,
13115 0x53, 0x07, 0xfe, 0x60,
13116 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
13117 0x00, 0x1c, 0x95, 0x13,
13118 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3,
13119 0xfe, 0x43, 0xf4, 0x96,
13120 0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43,
13121 0xf4, 0x94, 0xf6, 0x8b,
13122 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
13123 0xda, 0x17, 0x62, 0x49,
13124 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80,
13125 0x71, 0x50, 0x26, 0xfe,
13126 0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3,
13127 0x58, 0x02, 0x50, 0x13,
13128 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
13129 0x25, 0xbe, 0xfe, 0x03,
13130 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9,
13131 0x0a, 0x01, 0x08, 0x16,
13132 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01,
13133 0x01, 0x08, 0x16, 0xa9,
13134 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
13135 0x08, 0x16, 0xa9, 0x27,
13136 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83,
13137 0x01, 0x38, 0x06, 0x24,
13138 0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1,
13139 0x78, 0x03, 0x9a, 0x1e,
13140 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
13141 0xfe, 0x40, 0x5a, 0x23,
13142 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c,
13143 0x80, 0x48, 0xfe, 0xaa,
13144 0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01,
13145 0xfe, 0xac, 0x1d, 0xfe,
13146 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
13147 0x43, 0x48, 0x2d, 0x93,
13148 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4,
13149 0x36, 0xfe, 0x34, 0xf4,
13150 0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe,
13151 0x28, 0x10, 0xfe, 0xc0,
13152 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
13153 0x18, 0x45, 0xfe, 0x1c,
13154 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c,
13155 0x19, 0xfe, 0x04, 0xf4,
13156 0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d,
13157 0x21, 0xfe, 0x7f, 0x01,
13158 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
13159 0x7e, 0x01, 0xfe, 0xc8,
13160 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa,
13161 0x21, 0xfe, 0x81, 0x01,
13162 0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50,
13163 0x13, 0x0d, 0x02, 0x14,
13164 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
13165 0xfe, 0x82, 0x19, 0x14,
13166 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01,
13167 0x08, 0x02, 0x14, 0x07,
13168 0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07,
13169 0x01, 0x08, 0x17, 0xc1,
13170 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
13171 0x08, 0x02, 0x50, 0x02,
13172 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74,
13173 0x14, 0x12, 0x01, 0x08,
13174 0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01,
13175 0x08, 0x17, 0x74, 0xfe,
13176 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
13177 0x74, 0x5f, 0xcc, 0x01,
13178 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4,
13179 0xfe, 0x49, 0xf4, 0x00,
13180 0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff,
13181 0x02, 0x00, 0x10, 0x2f,
13182 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
13183 0x16, 0xfe, 0x64, 0x1a,
13184 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c,
13185 0x61, 0x07, 0x44, 0x02,
13186 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12,
13187 0x13, 0x0a, 0x9d, 0x01,
13188 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
13189 0xfe, 0x80, 0xe7, 0x1a,
13190 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02,
13191 0x0a, 0x5a, 0x01, 0x18,
13192 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe,
13193 0x7e, 0x1e, 0xfe, 0x80,
13194 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
13195 0xfe, 0x80, 0x4c, 0x0a,
13196 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf,
13197 0xfe, 0x19, 0xde, 0xfe,
13198 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe,
13199 0x2a, 0x1c, 0xfa, 0xb3,
13200 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
13201 0xf4, 0x1a, 0xfe, 0xfa,
13202 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24,
13203 0xfe, 0x18, 0x58, 0x03,
13204 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f,
13205 0xfe, 0x30, 0xf4, 0x07,
13206 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
13207 0xf7, 0x24, 0xb1, 0xfe,
13208 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b,
13209 0xfe, 0xba, 0x10, 0x1c,
13210 0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
13211 0x1d, 0xf7, 0x54, 0xb1,
13212 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
13213 0xaf, 0x19, 0xfe, 0x98,
13214 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c,
13215 0x1a, 0x87, 0x8b, 0x0f,
13216 0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58,
13217 0xfe, 0x32, 0x90, 0x04,
13218 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
13219 0x7c, 0x12, 0xfe, 0x0f,
13220 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14,
13221 0x31, 0x02, 0xc9, 0x2b,
13222 0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe,
13223 0x6a, 0xfe, 0x19, 0xfe,
13224 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
13225 0x1b, 0xfe, 0x36, 0x14,
13226 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19,
13227 0xfe, 0x80, 0xe7, 0x1a,
13228 0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a,
13229 0x30, 0xfe, 0x12, 0x45,
13230 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
13231 0x39, 0xf0, 0x75, 0x26,
13232 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03,
13233 0xe3, 0x23, 0x07, 0xfe,
13234 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09,
13235 0x56, 0xfe, 0x3c, 0x13,
13236 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
13237 0x01, 0x18, 0xcb, 0xfe,
13238 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16,
13239 0xfe, 0x00, 0xcc, 0xcb,
13240 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18,
13241 0xfe, 0x80, 0x4c, 0x01,
13242 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
13243 0x12, 0xfe, 0x14, 0x56,
13244 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7,
13245 0x0d, 0x19, 0xfe, 0x15,
13246 0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06,
13247 0x83, 0xfe, 0x18, 0x80,
13248 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
13249 0x90, 0xfe, 0xba, 0x90,
13250 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02,
13251 0x21, 0xb9, 0x88, 0x20,
13252 0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01,
13253 0x18, 0xfe, 0x49, 0x44,
13254 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
13255 0x1a, 0xa4, 0x0a, 0x67,
13256 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4,
13257 0x1d, 0x7b, 0xfe, 0x52,
13258 0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe,
13259 0x4e, 0xe4, 0xdd, 0x7b,
13260 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
13261 0xfe, 0x4e, 0xe4, 0xfe,
13262 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24,
13263 0xfe, 0x08, 0x10, 0x03,
13264 0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04,
13265 0x68, 0x54, 0xfe, 0xf1,
13266 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
13267 0xfe, 0x1a, 0xf4, 0xfe,
13268 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02,
13269 0x09, 0x92, 0xfe, 0x5a,
13270 0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe,
13271 0x5a, 0xf0, 0xfe, 0xc8,
13272 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
13273 0x1a, 0x10, 0x09, 0x0d,
13274 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02,
13275 0x1f, 0x93, 0x01, 0x42,
13276 0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e,
13277 0xfe, 0x14, 0xf0, 0x08,
13278 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
13279 0xfe, 0x82, 0xf0, 0xfe,
13280 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e,
13281 0x02, 0x0f, 0xfe, 0x18,
13282 0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02,
13283 0x80, 0x04, 0xfe, 0x82,
13284 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
13285 0x83, 0x33, 0x0b, 0x0e,
13286 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e,
13287 0x02, 0x0f, 0xfe, 0x04,
13288 0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80,
13289 0x80, 0x04, 0xfe, 0x80,
13290 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
13291 0xfe, 0x99, 0x83, 0xfe,
13292 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86,
13293 0x83, 0xfe, 0xce, 0x47,
13294 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a,
13295 0x0b, 0x0e, 0x02, 0x0f,
13296 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13297 0xfe, 0x08, 0x90, 0x04,
13298 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04,
13299 0xfe, 0x8a, 0x93, 0x79,
13300 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a,
13301 0x0b, 0x0e, 0x02, 0x0f,
13302 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13303 0xfe, 0x3c, 0x90, 0x04,
13304 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80,
13305 0x04, 0xfe, 0x83, 0x83,
13306 0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
13309 static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
13310 static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
13312 /* a_init.c */
13314 * EEPROM Configuration.
13316 * All drivers should use this structure to set the default EEPROM
13317 * configuration. The BIOS now uses this structure when it is built.
13318 * Additional structure information can be found in a_condor.h where
13319 * the structure is defined.
13321 * The *_Field_IsChar structs are needed to correct for endianness.
13322 * These values are read from the board 16 bits at a time directly
13323 * into the structs. Because some fields are char, the values will be
13324 * in the wrong order. The *_Field_IsChar tells when to flip the
13325 * bytes. Data read and written to PCI memory is automatically swapped
13326 * on big-endian platforms so char fields read as words are actually being
13327 * unswapped on big-endian platforms.
13329 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
13330 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
13331 0x0000, /* cfg_msw */
13332 0xFFFF, /* disc_enable */
13333 0xFFFF, /* wdtr_able */
13334 0xFFFF, /* sdtr_able */
13335 0xFFFF, /* start_motor */
13336 0xFFFF, /* tagqng_able */
13337 0xFFFF, /* bios_scan */
13338 0, /* scam_tolerant */
13339 7, /* adapter_scsi_id */
13340 0, /* bios_boot_delay */
13341 3, /* scsi_reset_delay */
13342 0, /* bios_id_lun */
13343 0, /* termination */
13344 0, /* reserved1 */
13345 0xFFE7, /* bios_ctrl */
13346 0xFFFF, /* ultra_able */
13347 0, /* reserved2 */
13348 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
13349 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13350 0, /* dvc_cntl */
13351 0, /* bug_fix */
13352 0, /* serial_number_word1 */
13353 0, /* serial_number_word2 */
13354 0, /* serial_number_word3 */
13355 0, /* check_sum */
13356 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13357 , /* oem_name[16] */
13358 0, /* dvc_err_code */
13359 0, /* adv_err_code */
13360 0, /* adv_err_addr */
13361 0, /* saved_dvc_err_code */
13362 0, /* saved_adv_err_code */
13363 0, /* saved_adv_err_addr */
13364 0 /* num_of_err */
13367 static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
13368 0, /* cfg_lsw */
13369 0, /* cfg_msw */
13370 0, /* -disc_enable */
13371 0, /* wdtr_able */
13372 0, /* sdtr_able */
13373 0, /* start_motor */
13374 0, /* tagqng_able */
13375 0, /* bios_scan */
13376 0, /* scam_tolerant */
13377 1, /* adapter_scsi_id */
13378 1, /* bios_boot_delay */
13379 1, /* scsi_reset_delay */
13380 1, /* bios_id_lun */
13381 1, /* termination */
13382 1, /* reserved1 */
13383 0, /* bios_ctrl */
13384 0, /* ultra_able */
13385 0, /* reserved2 */
13386 1, /* max_host_qng */
13387 1, /* max_dvc_qng */
13388 0, /* dvc_cntl */
13389 0, /* bug_fix */
13390 0, /* serial_number_word1 */
13391 0, /* serial_number_word2 */
13392 0, /* serial_number_word3 */
13393 0, /* check_sum */
13394 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13395 , /* oem_name[16] */
13396 0, /* dvc_err_code */
13397 0, /* adv_err_code */
13398 0, /* adv_err_addr */
13399 0, /* saved_dvc_err_code */
13400 0, /* saved_adv_err_code */
13401 0, /* saved_adv_err_addr */
13402 0 /* num_of_err */
13405 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
13406 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13407 0x0000, /* 01 cfg_msw */
13408 0xFFFF, /* 02 disc_enable */
13409 0xFFFF, /* 03 wdtr_able */
13410 0x4444, /* 04 sdtr_speed1 */
13411 0xFFFF, /* 05 start_motor */
13412 0xFFFF, /* 06 tagqng_able */
13413 0xFFFF, /* 07 bios_scan */
13414 0, /* 08 scam_tolerant */
13415 7, /* 09 adapter_scsi_id */
13416 0, /* bios_boot_delay */
13417 3, /* 10 scsi_reset_delay */
13418 0, /* bios_id_lun */
13419 0, /* 11 termination_se */
13420 0, /* termination_lvd */
13421 0xFFE7, /* 12 bios_ctrl */
13422 0x4444, /* 13 sdtr_speed2 */
13423 0x4444, /* 14 sdtr_speed3 */
13424 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
13425 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13426 0, /* 16 dvc_cntl */
13427 0x4444, /* 17 sdtr_speed4 */
13428 0, /* 18 serial_number_word1 */
13429 0, /* 19 serial_number_word2 */
13430 0, /* 20 serial_number_word3 */
13431 0, /* 21 check_sum */
13432 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13433 , /* 22-29 oem_name[16] */
13434 0, /* 30 dvc_err_code */
13435 0, /* 31 adv_err_code */
13436 0, /* 32 adv_err_addr */
13437 0, /* 33 saved_dvc_err_code */
13438 0, /* 34 saved_adv_err_code */
13439 0, /* 35 saved_adv_err_addr */
13440 0, /* 36 reserved */
13441 0, /* 37 reserved */
13442 0, /* 38 reserved */
13443 0, /* 39 reserved */
13444 0, /* 40 reserved */
13445 0, /* 41 reserved */
13446 0, /* 42 reserved */
13447 0, /* 43 reserved */
13448 0, /* 44 reserved */
13449 0, /* 45 reserved */
13450 0, /* 46 reserved */
13451 0, /* 47 reserved */
13452 0, /* 48 reserved */
13453 0, /* 49 reserved */
13454 0, /* 50 reserved */
13455 0, /* 51 reserved */
13456 0, /* 52 reserved */
13457 0, /* 53 reserved */
13458 0, /* 54 reserved */
13459 0, /* 55 reserved */
13460 0, /* 56 cisptr_lsw */
13461 0, /* 57 cisprt_msw */
13462 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
13463 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
13464 0, /* 60 reserved */
13465 0, /* 61 reserved */
13466 0, /* 62 reserved */
13467 0 /* 63 reserved */
13470 static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
13471 0, /* 00 cfg_lsw */
13472 0, /* 01 cfg_msw */
13473 0, /* 02 disc_enable */
13474 0, /* 03 wdtr_able */
13475 0, /* 04 sdtr_speed1 */
13476 0, /* 05 start_motor */
13477 0, /* 06 tagqng_able */
13478 0, /* 07 bios_scan */
13479 0, /* 08 scam_tolerant */
13480 1, /* 09 adapter_scsi_id */
13481 1, /* bios_boot_delay */
13482 1, /* 10 scsi_reset_delay */
13483 1, /* bios_id_lun */
13484 1, /* 11 termination_se */
13485 1, /* termination_lvd */
13486 0, /* 12 bios_ctrl */
13487 0, /* 13 sdtr_speed2 */
13488 0, /* 14 sdtr_speed3 */
13489 1, /* 15 max_host_qng */
13490 1, /* max_dvc_qng */
13491 0, /* 16 dvc_cntl */
13492 0, /* 17 sdtr_speed4 */
13493 0, /* 18 serial_number_word1 */
13494 0, /* 19 serial_number_word2 */
13495 0, /* 20 serial_number_word3 */
13496 0, /* 21 check_sum */
13497 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13498 , /* 22-29 oem_name[16] */
13499 0, /* 30 dvc_err_code */
13500 0, /* 31 adv_err_code */
13501 0, /* 32 adv_err_addr */
13502 0, /* 33 saved_dvc_err_code */
13503 0, /* 34 saved_adv_err_code */
13504 0, /* 35 saved_adv_err_addr */
13505 0, /* 36 reserved */
13506 0, /* 37 reserved */
13507 0, /* 38 reserved */
13508 0, /* 39 reserved */
13509 0, /* 40 reserved */
13510 0, /* 41 reserved */
13511 0, /* 42 reserved */
13512 0, /* 43 reserved */
13513 0, /* 44 reserved */
13514 0, /* 45 reserved */
13515 0, /* 46 reserved */
13516 0, /* 47 reserved */
13517 0, /* 48 reserved */
13518 0, /* 49 reserved */
13519 0, /* 50 reserved */
13520 0, /* 51 reserved */
13521 0, /* 52 reserved */
13522 0, /* 53 reserved */
13523 0, /* 54 reserved */
13524 0, /* 55 reserved */
13525 0, /* 56 cisptr_lsw */
13526 0, /* 57 cisprt_msw */
13527 0, /* 58 subsysvid */
13528 0, /* 59 subsysid */
13529 0, /* 60 reserved */
13530 0, /* 61 reserved */
13531 0, /* 62 reserved */
13532 0 /* 63 reserved */
13535 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
13536 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13537 0x0000, /* 01 cfg_msw */
13538 0xFFFF, /* 02 disc_enable */
13539 0xFFFF, /* 03 wdtr_able */
13540 0x5555, /* 04 sdtr_speed1 */
13541 0xFFFF, /* 05 start_motor */
13542 0xFFFF, /* 06 tagqng_able */
13543 0xFFFF, /* 07 bios_scan */
13544 0, /* 08 scam_tolerant */
13545 7, /* 09 adapter_scsi_id */
13546 0, /* bios_boot_delay */
13547 3, /* 10 scsi_reset_delay */
13548 0, /* bios_id_lun */
13549 0, /* 11 termination_se */
13550 0, /* termination_lvd */
13551 0xFFE7, /* 12 bios_ctrl */
13552 0x5555, /* 13 sdtr_speed2 */
13553 0x5555, /* 14 sdtr_speed3 */
13554 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
13555 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13556 0, /* 16 dvc_cntl */
13557 0x5555, /* 17 sdtr_speed4 */
13558 0, /* 18 serial_number_word1 */
13559 0, /* 19 serial_number_word2 */
13560 0, /* 20 serial_number_word3 */
13561 0, /* 21 check_sum */
13562 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13563 , /* 22-29 oem_name[16] */
13564 0, /* 30 dvc_err_code */
13565 0, /* 31 adv_err_code */
13566 0, /* 32 adv_err_addr */
13567 0, /* 33 saved_dvc_err_code */
13568 0, /* 34 saved_adv_err_code */
13569 0, /* 35 saved_adv_err_addr */
13570 0, /* 36 reserved */
13571 0, /* 37 reserved */
13572 0, /* 38 reserved */
13573 0, /* 39 reserved */
13574 0, /* 40 reserved */
13575 0, /* 41 reserved */
13576 0, /* 42 reserved */
13577 0, /* 43 reserved */
13578 0, /* 44 reserved */
13579 0, /* 45 reserved */
13580 0, /* 46 reserved */
13581 0, /* 47 reserved */
13582 0, /* 48 reserved */
13583 0, /* 49 reserved */
13584 0, /* 50 reserved */
13585 0, /* 51 reserved */
13586 0, /* 52 reserved */
13587 0, /* 53 reserved */
13588 0, /* 54 reserved */
13589 0, /* 55 reserved */
13590 0, /* 56 cisptr_lsw */
13591 0, /* 57 cisprt_msw */
13592 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
13593 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
13594 0, /* 60 reserved */
13595 0, /* 61 reserved */
13596 0, /* 62 reserved */
13597 0 /* 63 reserved */
13600 static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
13601 0, /* 00 cfg_lsw */
13602 0, /* 01 cfg_msw */
13603 0, /* 02 disc_enable */
13604 0, /* 03 wdtr_able */
13605 0, /* 04 sdtr_speed1 */
13606 0, /* 05 start_motor */
13607 0, /* 06 tagqng_able */
13608 0, /* 07 bios_scan */
13609 0, /* 08 scam_tolerant */
13610 1, /* 09 adapter_scsi_id */
13611 1, /* bios_boot_delay */
13612 1, /* 10 scsi_reset_delay */
13613 1, /* bios_id_lun */
13614 1, /* 11 termination_se */
13615 1, /* termination_lvd */
13616 0, /* 12 bios_ctrl */
13617 0, /* 13 sdtr_speed2 */
13618 0, /* 14 sdtr_speed3 */
13619 1, /* 15 max_host_qng */
13620 1, /* max_dvc_qng */
13621 0, /* 16 dvc_cntl */
13622 0, /* 17 sdtr_speed4 */
13623 0, /* 18 serial_number_word1 */
13624 0, /* 19 serial_number_word2 */
13625 0, /* 20 serial_number_word3 */
13626 0, /* 21 check_sum */
13627 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13628 , /* 22-29 oem_name[16] */
13629 0, /* 30 dvc_err_code */
13630 0, /* 31 adv_err_code */
13631 0, /* 32 adv_err_addr */
13632 0, /* 33 saved_dvc_err_code */
13633 0, /* 34 saved_adv_err_code */
13634 0, /* 35 saved_adv_err_addr */
13635 0, /* 36 reserved */
13636 0, /* 37 reserved */
13637 0, /* 38 reserved */
13638 0, /* 39 reserved */
13639 0, /* 40 reserved */
13640 0, /* 41 reserved */
13641 0, /* 42 reserved */
13642 0, /* 43 reserved */
13643 0, /* 44 reserved */
13644 0, /* 45 reserved */
13645 0, /* 46 reserved */
13646 0, /* 47 reserved */
13647 0, /* 48 reserved */
13648 0, /* 49 reserved */
13649 0, /* 50 reserved */
13650 0, /* 51 reserved */
13651 0, /* 52 reserved */
13652 0, /* 53 reserved */
13653 0, /* 54 reserved */
13654 0, /* 55 reserved */
13655 0, /* 56 cisptr_lsw */
13656 0, /* 57 cisprt_msw */
13657 0, /* 58 subsysvid */
13658 0, /* 59 subsysid */
13659 0, /* 60 reserved */
13660 0, /* 61 reserved */
13661 0, /* 62 reserved */
13662 0 /* 63 reserved */
13666 * Initialize the ADV_DVC_VAR structure.
13668 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13670 * For a non-fatal error return a warning code. If there are no warnings
13671 * then 0 is returned.
13673 static int __devinit AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
13675 unsigned short warn_code = 0;
13676 AdvPortAddr iop_base = asc_dvc->iop_base;
13677 struct pci_dev *pdev = to_pci_dev(asc_dvc->cfg->dev);
13678 u16 cmd;
13679 int status;
13681 asc_dvc->err_code = 0;
13684 * Save the state of the PCI Configuration Command Register
13685 * "Parity Error Response Control" Bit. If the bit is clear (0),
13686 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
13687 * DMA parity errors.
13689 asc_dvc->cfg->control_flag = 0;
13690 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
13691 if ((cmd & PCI_COMMAND_PARITY) == 0)
13692 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
13694 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
13695 ADV_LIB_VERSION_MINOR;
13696 asc_dvc->cfg->chip_version =
13697 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
13699 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
13700 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
13701 (ushort)ADV_CHIP_ID_BYTE);
13703 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
13704 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
13705 (ushort)ADV_CHIP_ID_WORD);
13708 * Reset the chip to start and allow register writes.
13710 if (AdvFindSignature(iop_base) == 0) {
13711 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
13712 return ADV_ERROR;
13713 } else {
13715 * The caller must set 'chip_type' to a valid setting.
13717 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
13718 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
13719 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
13720 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
13721 return ADV_ERROR;
13725 * Reset Chip.
13727 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13728 ADV_CTRL_REG_CMD_RESET);
13729 DvcSleepMilliSecond(100);
13730 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13731 ADV_CTRL_REG_CMD_WR_IO_REG);
13733 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13734 status = AdvInitFrom38C1600EEP(asc_dvc);
13735 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13736 status = AdvInitFrom38C0800EEP(asc_dvc);
13737 } else {
13738 status = AdvInitFrom3550EEP(asc_dvc);
13740 warn_code |= status;
13743 return warn_code;
13747 * Initialize the ASC-3550.
13749 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13751 * For a non-fatal error return a warning code. If there are no warnings
13752 * then 0 is returned.
13754 * Needed after initialization for error recovery.
13756 static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
13758 AdvPortAddr iop_base;
13759 ushort warn_code;
13760 ADV_DCNT sum;
13761 int begin_addr;
13762 int end_addr;
13763 ushort code_sum;
13764 int word;
13765 int j;
13766 int adv_asc3550_expanded_size;
13767 ADV_CARR_T *carrp;
13768 ADV_DCNT contig_len;
13769 ADV_SDCNT buf_size;
13770 ADV_PADDR carr_paddr;
13771 int i;
13772 ushort scsi_cfg1;
13773 uchar tid;
13774 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
13775 ushort wdtr_able = 0, sdtr_able, tagqng_able;
13776 uchar max_cmd[ADV_MAX_TID + 1];
13778 /* If there is already an error, don't continue. */
13779 if (asc_dvc->err_code != 0) {
13780 return ADV_ERROR;
13784 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
13786 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
13787 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
13788 return ADV_ERROR;
13791 warn_code = 0;
13792 iop_base = asc_dvc->iop_base;
13795 * Save the RISC memory BIOS region before writing the microcode.
13796 * The BIOS may already be loaded and using its RISC LRAM region
13797 * so its region must be saved and restored.
13799 * Note: This code makes the assumption, which is currently true,
13800 * that a chip reset does not clear RISC LRAM.
13802 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
13803 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
13804 bios_mem[i]);
13808 * Save current per TID negotiated values.
13810 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
13811 ushort bios_version, major, minor;
13813 bios_version =
13814 bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
13815 major = (bios_version >> 12) & 0xF;
13816 minor = (bios_version >> 8) & 0xF;
13817 if (major < 3 || (major == 3 && minor == 1)) {
13818 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
13819 AdvReadWordLram(iop_base, 0x120, wdtr_able);
13820 } else {
13821 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
13824 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
13825 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
13826 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13827 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
13828 max_cmd[tid]);
13832 * Load the Microcode
13834 * Write the microcode image to RISC memory starting at address 0.
13836 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
13837 /* Assume the following compressed format of the microcode buffer:
13839 * 254 word (508 byte) table indexed by byte code followed
13840 * by the following byte codes:
13842 * 1-Byte Code:
13843 * 00: Emit word 0 in table.
13844 * 01: Emit word 1 in table.
13846 * FD: Emit word 253 in table.
13848 * Multi-Byte Code:
13849 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
13850 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
13852 word = 0;
13853 for (i = 253 * 2; i < _adv_asc3550_size; i++) {
13854 if (_adv_asc3550_buf[i] == 0xff) {
13855 for (j = 0; j < _adv_asc3550_buf[i + 1]; j++) {
13856 AdvWriteWordAutoIncLram(iop_base, (((ushort)
13857 _adv_asc3550_buf
13858 [i +
13859 3] << 8) |
13860 _adv_asc3550_buf
13861 [i + 2]));
13862 word++;
13864 i += 3;
13865 } else if (_adv_asc3550_buf[i] == 0xfe) {
13866 AdvWriteWordAutoIncLram(iop_base, (((ushort)
13867 _adv_asc3550_buf[i +
13869 << 8) |
13870 _adv_asc3550_buf[i +
13871 1]));
13872 i += 2;
13873 word++;
13874 } else {
13875 AdvWriteWordAutoIncLram(iop_base, (((ushort)
13876 _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) | _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
13877 word++;
13882 * Set 'word' for later use to clear the rest of memory and save
13883 * the expanded mcode size.
13885 word *= 2;
13886 adv_asc3550_expanded_size = word;
13889 * Clear the rest of ASC-3550 Internal RAM (8KB).
13891 for (; word < ADV_3550_MEMSIZE; word += 2) {
13892 AdvWriteWordAutoIncLram(iop_base, 0);
13896 * Verify the microcode checksum.
13898 sum = 0;
13899 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
13901 for (word = 0; word < adv_asc3550_expanded_size; word += 2) {
13902 sum += AdvReadWordAutoIncLram(iop_base);
13905 if (sum != _adv_asc3550_chksum) {
13906 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
13907 return ADV_ERROR;
13911 * Restore the RISC memory BIOS region.
13913 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
13914 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
13915 bios_mem[i]);
13919 * Calculate and write the microcode code checksum to the microcode
13920 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
13922 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
13923 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
13924 code_sum = 0;
13925 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
13926 for (word = begin_addr; word < end_addr; word += 2) {
13927 code_sum += AdvReadWordAutoIncLram(iop_base);
13929 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
13932 * Read and save microcode version and date.
13934 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
13935 asc_dvc->cfg->mcode_date);
13936 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
13937 asc_dvc->cfg->mcode_version);
13940 * Set the chip type to indicate the ASC3550.
13942 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
13945 * If the PCI Configuration Command Register "Parity Error Response
13946 * Control" Bit was clear (0), then set the microcode variable
13947 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
13948 * to ignore DMA parity errors.
13950 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
13951 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
13952 word |= CONTROL_FLAG_IGNORE_PERR;
13953 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
13957 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
13958 * threshold of 128 bytes. This register is only accessible to the host.
13960 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
13961 START_CTL_EMFU | READ_CMD_MRM);
13964 * Microcode operating variables for WDTR, SDTR, and command tag
13965 * queuing will be set in slave_configure() based on what a
13966 * device reports it is capable of in Inquiry byte 7.
13968 * If SCSI Bus Resets have been disabled, then directly set
13969 * SDTR and WDTR from the EEPROM configuration. This will allow
13970 * the BIOS and warm boot to work without a SCSI bus hang on
13971 * the Inquiry caused by host and target mismatched DTR values.
13972 * Without the SCSI Bus Reset, before an Inquiry a device can't
13973 * be assumed to be in Asynchronous, Narrow mode.
13975 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
13976 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
13977 asc_dvc->wdtr_able);
13978 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
13979 asc_dvc->sdtr_able);
13983 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
13984 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
13985 * bitmask. These values determine the maximum SDTR speed negotiated
13986 * with a device.
13988 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
13989 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
13990 * without determining here whether the device supports SDTR.
13992 * 4-bit speed SDTR speed name
13993 * =========== ===============
13994 * 0000b (0x0) SDTR disabled
13995 * 0001b (0x1) 5 Mhz
13996 * 0010b (0x2) 10 Mhz
13997 * 0011b (0x3) 20 Mhz (Ultra)
13998 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
13999 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
14000 * 0110b (0x6) Undefined
14002 * 1111b (0xF) Undefined
14004 word = 0;
14005 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14006 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
14007 /* Set Ultra speed for TID 'tid'. */
14008 word |= (0x3 << (4 * (tid % 4)));
14009 } else {
14010 /* Set Fast speed for TID 'tid'. */
14011 word |= (0x2 << (4 * (tid % 4)));
14013 if (tid == 3) { /* Check if done with sdtr_speed1. */
14014 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
14015 word = 0;
14016 } else if (tid == 7) { /* Check if done with sdtr_speed2. */
14017 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
14018 word = 0;
14019 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
14020 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
14021 word = 0;
14022 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
14023 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
14024 /* End of loop. */
14029 * Set microcode operating variable for the disconnect per TID bitmask.
14031 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
14032 asc_dvc->cfg->disc_enable);
14035 * Set SCSI_CFG0 Microcode Default Value.
14037 * The microcode will set the SCSI_CFG0 register using this value
14038 * after it is started below.
14040 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14041 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14042 asc_dvc->chip_scsi_id);
14045 * Determine SCSI_CFG1 Microcode Default Value.
14047 * The microcode will set the SCSI_CFG1 register using this value
14048 * after it is started below.
14051 /* Read current SCSI_CFG1 Register value. */
14052 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14055 * If all three connectors are in use, return an error.
14057 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
14058 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
14059 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
14060 return ADV_ERROR;
14064 * If the internal narrow cable is reversed all of the SCSI_CTRL
14065 * register signals will be set. Check for and return an error if
14066 * this condition is found.
14068 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
14069 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14070 return ADV_ERROR;
14074 * If this is a differential board and a single-ended device
14075 * is attached to one of the connectors, return an error.
14077 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
14078 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
14079 return ADV_ERROR;
14083 * If automatic termination control is enabled, then set the
14084 * termination value based on a table listed in a_condor.h.
14086 * If manual termination was specified with an EEPROM setting
14087 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
14088 * is ready to be 'ored' into SCSI_CFG1.
14090 if (asc_dvc->cfg->termination == 0) {
14092 * The software always controls termination by setting TERM_CTL_SEL.
14093 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
14095 asc_dvc->cfg->termination |= TERM_CTL_SEL;
14097 switch (scsi_cfg1 & CABLE_DETECT) {
14098 /* TERM_CTL_H: on, TERM_CTL_L: on */
14099 case 0x3:
14100 case 0x7:
14101 case 0xB:
14102 case 0xD:
14103 case 0xE:
14104 case 0xF:
14105 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
14106 break;
14108 /* TERM_CTL_H: on, TERM_CTL_L: off */
14109 case 0x1:
14110 case 0x5:
14111 case 0x9:
14112 case 0xA:
14113 case 0xC:
14114 asc_dvc->cfg->termination |= TERM_CTL_H;
14115 break;
14117 /* TERM_CTL_H: off, TERM_CTL_L: off */
14118 case 0x2:
14119 case 0x6:
14120 break;
14125 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
14127 scsi_cfg1 &= ~TERM_CTL;
14130 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
14131 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
14132 * referenced, because the hardware internally inverts
14133 * the Termination High and Low bits if TERM_POL is set.
14135 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
14138 * Set SCSI_CFG1 Microcode Default Value
14140 * Set filter value and possibly modified termination control
14141 * bits in the Microcode SCSI_CFG1 Register Value.
14143 * The microcode will set the SCSI_CFG1 register using this value
14144 * after it is started below.
14146 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
14147 FLTR_DISABLE | scsi_cfg1);
14150 * Set MEM_CFG Microcode Default Value
14152 * The microcode will set the MEM_CFG register using this value
14153 * after it is started below.
14155 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
14156 * are defined.
14158 * ASC-3550 has 8KB internal memory.
14160 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
14161 BIOS_EN | RAM_SZ_8KB);
14164 * Set SEL_MASK Microcode Default Value
14166 * The microcode will set the SEL_MASK register using this value
14167 * after it is started below.
14169 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
14170 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
14173 * Build carrier freelist.
14175 * Driver must have already allocated memory and set 'carrier_buf'.
14177 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
14179 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
14180 asc_dvc->carr_freelist = NULL;
14181 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
14182 buf_size = ADV_CARRIER_BUFSIZE;
14183 } else {
14184 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
14187 do {
14189 * Get physical address of the carrier 'carrp'.
14191 contig_len = sizeof(ADV_CARR_T);
14192 carr_paddr =
14193 cpu_to_le32(DvcGetPhyAddr
14194 (asc_dvc, NULL, (uchar *)carrp,
14195 (ADV_SDCNT *)&contig_len,
14196 ADV_IS_CARRIER_FLAG));
14198 buf_size -= sizeof(ADV_CARR_T);
14201 * If the current carrier is not physically contiguous, then
14202 * maybe there was a page crossing. Try the next carrier aligned
14203 * start address.
14205 if (contig_len < sizeof(ADV_CARR_T)) {
14206 carrp++;
14207 continue;
14210 carrp->carr_pa = carr_paddr;
14211 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
14214 * Insert the carrier at the beginning of the freelist.
14216 carrp->next_vpa =
14217 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
14218 asc_dvc->carr_freelist = carrp;
14220 carrp++;
14222 while (buf_size > 0);
14225 * Set-up the Host->RISC Initiator Command Queue (ICQ).
14228 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
14229 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14230 return ADV_ERROR;
14232 asc_dvc->carr_freelist = (ADV_CARR_T *)
14233 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
14236 * The first command issued will be placed in the stopper carrier.
14238 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14241 * Set RISC ICQ physical address start value.
14243 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
14246 * Set-up the RISC->Host Initiator Response Queue (IRQ).
14248 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
14249 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14250 return ADV_ERROR;
14252 asc_dvc->carr_freelist = (ADV_CARR_T *)
14253 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
14256 * The first command completed by the RISC will be placed in
14257 * the stopper.
14259 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
14260 * completed the RISC will set the ASC_RQ_STOPPER bit.
14262 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14265 * Set RISC IRQ physical address start value.
14267 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
14268 asc_dvc->carr_pending_cnt = 0;
14270 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
14271 (ADV_INTR_ENABLE_HOST_INTR |
14272 ADV_INTR_ENABLE_GLOBAL_INTR));
14274 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
14275 AdvWriteWordRegister(iop_base, IOPW_PC, word);
14277 /* finally, finally, gentlemen, start your engine */
14278 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
14281 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
14282 * Resets should be performed. The RISC has to be running
14283 * to issue a SCSI Bus Reset.
14285 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
14287 * If the BIOS Signature is present in memory, restore the
14288 * BIOS Handshake Configuration Table and do not perform
14289 * a SCSI Bus Reset.
14291 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
14292 0x55AA) {
14294 * Restore per TID negotiated values.
14296 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14297 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14298 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
14299 tagqng_able);
14300 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14301 AdvWriteByteLram(iop_base,
14302 ASC_MC_NUMBER_OF_MAX_CMD + tid,
14303 max_cmd[tid]);
14305 } else {
14306 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
14307 warn_code = ASC_WARN_BUSRESET_ERROR;
14312 return warn_code;
14316 * Initialize the ASC-38C0800.
14318 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14320 * For a non-fatal error return a warning code. If there are no warnings
14321 * then 0 is returned.
14323 * Needed after initialization for error recovery.
14325 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
14327 AdvPortAddr iop_base;
14328 ushort warn_code;
14329 ADV_DCNT sum;
14330 int begin_addr;
14331 int end_addr;
14332 ushort code_sum;
14333 int word;
14334 int j;
14335 int adv_asc38C0800_expanded_size;
14336 ADV_CARR_T *carrp;
14337 ADV_DCNT contig_len;
14338 ADV_SDCNT buf_size;
14339 ADV_PADDR carr_paddr;
14340 int i;
14341 ushort scsi_cfg1;
14342 uchar byte;
14343 uchar tid;
14344 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
14345 ushort wdtr_able, sdtr_able, tagqng_able;
14346 uchar max_cmd[ADV_MAX_TID + 1];
14348 /* If there is already an error, don't continue. */
14349 if (asc_dvc->err_code != 0) {
14350 return ADV_ERROR;
14354 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
14356 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
14357 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
14358 return ADV_ERROR;
14361 warn_code = 0;
14362 iop_base = asc_dvc->iop_base;
14365 * Save the RISC memory BIOS region before writing the microcode.
14366 * The BIOS may already be loaded and using its RISC LRAM region
14367 * so its region must be saved and restored.
14369 * Note: This code makes the assumption, which is currently true,
14370 * that a chip reset does not clear RISC LRAM.
14372 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14373 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14374 bios_mem[i]);
14378 * Save current per TID negotiated values.
14380 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14381 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14382 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14383 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14384 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14385 max_cmd[tid]);
14389 * RAM BIST (RAM Built-In Self Test)
14391 * Address : I/O base + offset 0x38h register (byte).
14392 * Function: Bit 7-6(RW) : RAM mode
14393 * Normal Mode : 0x00
14394 * Pre-test Mode : 0x40
14395 * RAM Test Mode : 0x80
14396 * Bit 5 : unused
14397 * Bit 4(RO) : Done bit
14398 * Bit 3-0(RO) : Status
14399 * Host Error : 0x08
14400 * Int_RAM Error : 0x04
14401 * RISC Error : 0x02
14402 * SCSI Error : 0x01
14403 * No Error : 0x00
14405 * Note: RAM BIST code should be put right here, before loading the
14406 * microcode and after saving the RISC memory BIOS region.
14410 * LRAM Pre-test
14412 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
14413 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
14414 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
14415 * to NORMAL_MODE, return an error too.
14417 for (i = 0; i < 2; i++) {
14418 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
14419 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14420 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14421 if ((byte & RAM_TEST_DONE) == 0
14422 || (byte & 0x0F) != PRE_TEST_VALUE) {
14423 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14424 return ADV_ERROR;
14427 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14428 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14429 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
14430 != NORMAL_VALUE) {
14431 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14432 return ADV_ERROR;
14437 * LRAM Test - It takes about 1.5 ms to run through the test.
14439 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
14440 * If Done bit not set or Status not 0, save register byte, set the
14441 * err_code, and return an error.
14443 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
14444 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
14446 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14447 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
14448 /* Get here if Done bit not set or Status not 0. */
14449 asc_dvc->bist_err_code = byte; /* for BIOS display message */
14450 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
14451 return ADV_ERROR;
14454 /* We need to reset back to normal mode after LRAM test passes. */
14455 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14458 * Load the Microcode
14460 * Write the microcode image to RISC memory starting at address 0.
14463 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14465 /* Assume the following compressed format of the microcode buffer:
14467 * 254 word (508 byte) table indexed by byte code followed
14468 * by the following byte codes:
14470 * 1-Byte Code:
14471 * 00: Emit word 0 in table.
14472 * 01: Emit word 1 in table.
14474 * FD: Emit word 253 in table.
14476 * Multi-Byte Code:
14477 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14478 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14480 word = 0;
14481 for (i = 253 * 2; i < _adv_asc38C0800_size; i++) {
14482 if (_adv_asc38C0800_buf[i] == 0xff) {
14483 for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++) {
14484 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14485 _adv_asc38C0800_buf
14486 [i +
14487 3] << 8) |
14488 _adv_asc38C0800_buf
14489 [i + 2]));
14490 word++;
14492 i += 3;
14493 } else if (_adv_asc38C0800_buf[i] == 0xfe) {
14494 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14495 _adv_asc38C0800_buf
14496 [i +
14497 2] << 8) |
14498 _adv_asc38C0800_buf[i
14500 1]));
14501 i += 2;
14502 word++;
14503 } else {
14504 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14505 _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) | _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
14506 word++;
14511 * Set 'word' for later use to clear the rest of memory and save
14512 * the expanded mcode size.
14514 word *= 2;
14515 adv_asc38C0800_expanded_size = word;
14518 * Clear the rest of ASC-38C0800 Internal RAM (16KB).
14520 for (; word < ADV_38C0800_MEMSIZE; word += 2) {
14521 AdvWriteWordAutoIncLram(iop_base, 0);
14525 * Verify the microcode checksum.
14527 sum = 0;
14528 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14530 for (word = 0; word < adv_asc38C0800_expanded_size; word += 2) {
14531 sum += AdvReadWordAutoIncLram(iop_base);
14533 ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
14535 ASC_DBG2(1,
14536 "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
14537 (ulong)sum, (ulong)_adv_asc38C0800_chksum);
14539 if (sum != _adv_asc38C0800_chksum) {
14540 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14541 return ADV_ERROR;
14545 * Restore the RISC memory BIOS region.
14547 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14548 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14549 bios_mem[i]);
14553 * Calculate and write the microcode code checksum to the microcode
14554 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14556 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14557 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14558 code_sum = 0;
14559 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14560 for (word = begin_addr; word < end_addr; word += 2) {
14561 code_sum += AdvReadWordAutoIncLram(iop_base);
14563 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14566 * Read microcode version and date.
14568 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
14569 asc_dvc->cfg->mcode_date);
14570 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
14571 asc_dvc->cfg->mcode_version);
14574 * Set the chip type to indicate the ASC38C0800.
14576 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
14579 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
14580 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
14581 * cable detection and then we are able to read C_DET[3:0].
14583 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
14584 * Microcode Default Value' section below.
14586 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14587 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
14588 scsi_cfg1 | DIS_TERM_DRV);
14591 * If the PCI Configuration Command Register "Parity Error Response
14592 * Control" Bit was clear (0), then set the microcode variable
14593 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14594 * to ignore DMA parity errors.
14596 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
14597 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14598 word |= CONTROL_FLAG_IGNORE_PERR;
14599 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14603 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
14604 * bits for the default FIFO threshold.
14606 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
14608 * For DMA Errata #4 set the BC_THRESH_ENB bit.
14610 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14611 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
14612 READ_CMD_MRM);
14615 * Microcode operating variables for WDTR, SDTR, and command tag
14616 * queuing will be set in slave_configure() based on what a
14617 * device reports it is capable of in Inquiry byte 7.
14619 * If SCSI Bus Resets have been disabled, then directly set
14620 * SDTR and WDTR from the EEPROM configuration. This will allow
14621 * the BIOS and warm boot to work without a SCSI bus hang on
14622 * the Inquiry caused by host and target mismatched DTR values.
14623 * Without the SCSI Bus Reset, before an Inquiry a device can't
14624 * be assumed to be in Asynchronous, Narrow mode.
14626 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
14627 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
14628 asc_dvc->wdtr_able);
14629 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
14630 asc_dvc->sdtr_able);
14634 * Set microcode operating variables for DISC and SDTR_SPEED1,
14635 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
14636 * configuration values.
14638 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14639 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14640 * without determining here whether the device supports SDTR.
14642 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
14643 asc_dvc->cfg->disc_enable);
14644 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
14645 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
14646 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
14647 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
14650 * Set SCSI_CFG0 Microcode Default Value.
14652 * The microcode will set the SCSI_CFG0 register using this value
14653 * after it is started below.
14655 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14656 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14657 asc_dvc->chip_scsi_id);
14660 * Determine SCSI_CFG1 Microcode Default Value.
14662 * The microcode will set the SCSI_CFG1 register using this value
14663 * after it is started below.
14666 /* Read current SCSI_CFG1 Register value. */
14667 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14670 * If the internal narrow cable is reversed all of the SCSI_CTRL
14671 * register signals will be set. Check for and return an error if
14672 * this condition is found.
14674 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
14675 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14676 return ADV_ERROR;
14680 * All kind of combinations of devices attached to one of four connectors
14681 * are acceptable except HVD device attached. For example, LVD device can
14682 * be attached to SE connector while SE device attached to LVD connector.
14683 * If LVD device attached to SE connector, it only runs up to Ultra speed.
14685 * If an HVD device is attached to one of LVD connectors, return an error.
14686 * However, there is no way to detect HVD device attached to SE connectors.
14688 if (scsi_cfg1 & HVD) {
14689 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
14690 return ADV_ERROR;
14694 * If either SE or LVD automatic termination control is enabled, then
14695 * set the termination value based on a table listed in a_condor.h.
14697 * If manual termination was specified with an EEPROM setting then
14698 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
14699 * be 'ored' into SCSI_CFG1.
14701 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
14702 /* SE automatic termination control is enabled. */
14703 switch (scsi_cfg1 & C_DET_SE) {
14704 /* TERM_SE_HI: on, TERM_SE_LO: on */
14705 case 0x1:
14706 case 0x2:
14707 case 0x3:
14708 asc_dvc->cfg->termination |= TERM_SE;
14709 break;
14711 /* TERM_SE_HI: on, TERM_SE_LO: off */
14712 case 0x0:
14713 asc_dvc->cfg->termination |= TERM_SE_HI;
14714 break;
14718 if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
14719 /* LVD automatic termination control is enabled. */
14720 switch (scsi_cfg1 & C_DET_LVD) {
14721 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
14722 case 0x4:
14723 case 0x8:
14724 case 0xC:
14725 asc_dvc->cfg->termination |= TERM_LVD;
14726 break;
14728 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
14729 case 0x0:
14730 break;
14735 * Clear any set TERM_SE and TERM_LVD bits.
14737 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
14740 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
14742 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
14745 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
14746 * and set possibly modified termination control bits in the Microcode
14747 * SCSI_CFG1 Register Value.
14749 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
14752 * Set SCSI_CFG1 Microcode Default Value
14754 * Set possibly modified termination control and reset DIS_TERM_DRV
14755 * bits in the Microcode SCSI_CFG1 Register Value.
14757 * The microcode will set the SCSI_CFG1 register using this value
14758 * after it is started below.
14760 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
14763 * Set MEM_CFG Microcode Default Value
14765 * The microcode will set the MEM_CFG register using this value
14766 * after it is started below.
14768 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
14769 * are defined.
14771 * ASC-38C0800 has 16KB internal memory.
14773 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
14774 BIOS_EN | RAM_SZ_16KB);
14777 * Set SEL_MASK Microcode Default Value
14779 * The microcode will set the SEL_MASK register using this value
14780 * after it is started below.
14782 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
14783 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
14786 * Build the carrier freelist.
14788 * Driver must have already allocated memory and set 'carrier_buf'.
14790 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
14792 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
14793 asc_dvc->carr_freelist = NULL;
14794 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
14795 buf_size = ADV_CARRIER_BUFSIZE;
14796 } else {
14797 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
14800 do {
14802 * Get physical address for the carrier 'carrp'.
14804 contig_len = sizeof(ADV_CARR_T);
14805 carr_paddr =
14806 cpu_to_le32(DvcGetPhyAddr
14807 (asc_dvc, NULL, (uchar *)carrp,
14808 (ADV_SDCNT *)&contig_len,
14809 ADV_IS_CARRIER_FLAG));
14811 buf_size -= sizeof(ADV_CARR_T);
14814 * If the current carrier is not physically contiguous, then
14815 * maybe there was a page crossing. Try the next carrier aligned
14816 * start address.
14818 if (contig_len < sizeof(ADV_CARR_T)) {
14819 carrp++;
14820 continue;
14823 carrp->carr_pa = carr_paddr;
14824 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
14827 * Insert the carrier at the beginning of the freelist.
14829 carrp->next_vpa =
14830 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
14831 asc_dvc->carr_freelist = carrp;
14833 carrp++;
14835 while (buf_size > 0);
14838 * Set-up the Host->RISC Initiator Command Queue (ICQ).
14841 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
14842 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14843 return ADV_ERROR;
14845 asc_dvc->carr_freelist = (ADV_CARR_T *)
14846 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
14849 * The first command issued will be placed in the stopper carrier.
14851 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14854 * Set RISC ICQ physical address start value.
14855 * carr_pa is LE, must be native before write
14857 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
14860 * Set-up the RISC->Host Initiator Response Queue (IRQ).
14862 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
14863 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14864 return ADV_ERROR;
14866 asc_dvc->carr_freelist = (ADV_CARR_T *)
14867 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
14870 * The first command completed by the RISC will be placed in
14871 * the stopper.
14873 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
14874 * completed the RISC will set the ASC_RQ_STOPPER bit.
14876 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14879 * Set RISC IRQ physical address start value.
14881 * carr_pa is LE, must be native before write *
14883 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
14884 asc_dvc->carr_pending_cnt = 0;
14886 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
14887 (ADV_INTR_ENABLE_HOST_INTR |
14888 ADV_INTR_ENABLE_GLOBAL_INTR));
14890 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
14891 AdvWriteWordRegister(iop_base, IOPW_PC, word);
14893 /* finally, finally, gentlemen, start your engine */
14894 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
14897 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
14898 * Resets should be performed. The RISC has to be running
14899 * to issue a SCSI Bus Reset.
14901 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
14903 * If the BIOS Signature is present in memory, restore the
14904 * BIOS Handshake Configuration Table and do not perform
14905 * a SCSI Bus Reset.
14907 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
14908 0x55AA) {
14910 * Restore per TID negotiated values.
14912 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14913 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14914 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
14915 tagqng_able);
14916 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14917 AdvWriteByteLram(iop_base,
14918 ASC_MC_NUMBER_OF_MAX_CMD + tid,
14919 max_cmd[tid]);
14921 } else {
14922 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
14923 warn_code = ASC_WARN_BUSRESET_ERROR;
14928 return warn_code;
14932 * Initialize the ASC-38C1600.
14934 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
14936 * For a non-fatal error return a warning code. If there are no warnings
14937 * then 0 is returned.
14939 * Needed after initialization for error recovery.
14941 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
14943 AdvPortAddr iop_base;
14944 ushort warn_code;
14945 ADV_DCNT sum;
14946 int begin_addr;
14947 int end_addr;
14948 ushort code_sum;
14949 long word;
14950 int j;
14951 int adv_asc38C1600_expanded_size;
14952 ADV_CARR_T *carrp;
14953 ADV_DCNT contig_len;
14954 ADV_SDCNT buf_size;
14955 ADV_PADDR carr_paddr;
14956 int i;
14957 ushort scsi_cfg1;
14958 uchar byte;
14959 uchar tid;
14960 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
14961 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
14962 uchar max_cmd[ASC_MAX_TID + 1];
14964 /* If there is already an error, don't continue. */
14965 if (asc_dvc->err_code != 0) {
14966 return ADV_ERROR;
14970 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
14972 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
14973 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
14974 return ADV_ERROR;
14977 warn_code = 0;
14978 iop_base = asc_dvc->iop_base;
14981 * Save the RISC memory BIOS region before writing the microcode.
14982 * The BIOS may already be loaded and using its RISC LRAM region
14983 * so its region must be saved and restored.
14985 * Note: This code makes the assumption, which is currently true,
14986 * that a chip reset does not clear RISC LRAM.
14988 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14989 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14990 bios_mem[i]);
14994 * Save current per TID negotiated values.
14996 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14997 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14998 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
14999 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15000 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15001 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15002 max_cmd[tid]);
15006 * RAM BIST (Built-In Self Test)
15008 * Address : I/O base + offset 0x38h register (byte).
15009 * Function: Bit 7-6(RW) : RAM mode
15010 * Normal Mode : 0x00
15011 * Pre-test Mode : 0x40
15012 * RAM Test Mode : 0x80
15013 * Bit 5 : unused
15014 * Bit 4(RO) : Done bit
15015 * Bit 3-0(RO) : Status
15016 * Host Error : 0x08
15017 * Int_RAM Error : 0x04
15018 * RISC Error : 0x02
15019 * SCSI Error : 0x01
15020 * No Error : 0x00
15022 * Note: RAM BIST code should be put right here, before loading the
15023 * microcode and after saving the RISC memory BIOS region.
15027 * LRAM Pre-test
15029 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15030 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15031 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15032 * to NORMAL_MODE, return an error too.
15034 for (i = 0; i < 2; i++) {
15035 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15036 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15037 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15038 if ((byte & RAM_TEST_DONE) == 0
15039 || (byte & 0x0F) != PRE_TEST_VALUE) {
15040 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15041 return ADV_ERROR;
15044 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15045 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15046 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15047 != NORMAL_VALUE) {
15048 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15049 return ADV_ERROR;
15054 * LRAM Test - It takes about 1.5 ms to run through the test.
15056 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15057 * If Done bit not set or Status not 0, save register byte, set the
15058 * err_code, and return an error.
15060 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15061 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
15063 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15064 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
15065 /* Get here if Done bit not set or Status not 0. */
15066 asc_dvc->bist_err_code = byte; /* for BIOS display message */
15067 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15068 return ADV_ERROR;
15071 /* We need to reset back to normal mode after LRAM test passes. */
15072 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15075 * Load the Microcode
15077 * Write the microcode image to RISC memory starting at address 0.
15080 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15083 * Assume the following compressed format of the microcode buffer:
15085 * 254 word (508 byte) table indexed by byte code followed
15086 * by the following byte codes:
15088 * 1-Byte Code:
15089 * 00: Emit word 0 in table.
15090 * 01: Emit word 1 in table.
15092 * FD: Emit word 253 in table.
15094 * Multi-Byte Code:
15095 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15096 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15098 word = 0;
15099 for (i = 253 * 2; i < _adv_asc38C1600_size; i++) {
15100 if (_adv_asc38C1600_buf[i] == 0xff) {
15101 for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++) {
15102 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15103 _adv_asc38C1600_buf
15104 [i +
15105 3] << 8) |
15106 _adv_asc38C1600_buf
15107 [i + 2]));
15108 word++;
15110 i += 3;
15111 } else if (_adv_asc38C1600_buf[i] == 0xfe) {
15112 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15113 _adv_asc38C1600_buf
15114 [i +
15115 2] << 8) |
15116 _adv_asc38C1600_buf[i
15118 1]));
15119 i += 2;
15120 word++;
15121 } else {
15122 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15123 _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) | _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
15124 word++;
15129 * Set 'word' for later use to clear the rest of memory and save
15130 * the expanded mcode size.
15132 word *= 2;
15133 adv_asc38C1600_expanded_size = word;
15136 * Clear the rest of ASC-38C1600 Internal RAM (32KB).
15138 for (; word < ADV_38C1600_MEMSIZE; word += 2) {
15139 AdvWriteWordAutoIncLram(iop_base, 0);
15143 * Verify the microcode checksum.
15145 sum = 0;
15146 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15148 for (word = 0; word < adv_asc38C1600_expanded_size; word += 2) {
15149 sum += AdvReadWordAutoIncLram(iop_base);
15152 if (sum != _adv_asc38C1600_chksum) {
15153 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15154 return ADV_ERROR;
15158 * Restore the RISC memory BIOS region.
15160 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15161 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15162 bios_mem[i]);
15166 * Calculate and write the microcode code checksum to the microcode
15167 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15169 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15170 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15171 code_sum = 0;
15172 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15173 for (word = begin_addr; word < end_addr; word += 2) {
15174 code_sum += AdvReadWordAutoIncLram(iop_base);
15176 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15179 * Read microcode version and date.
15181 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
15182 asc_dvc->cfg->mcode_date);
15183 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
15184 asc_dvc->cfg->mcode_version);
15187 * Set the chip type to indicate the ASC38C1600.
15189 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
15192 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15193 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15194 * cable detection and then we are able to read C_DET[3:0].
15196 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15197 * Microcode Default Value' section below.
15199 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15200 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
15201 scsi_cfg1 | DIS_TERM_DRV);
15204 * If the PCI Configuration Command Register "Parity Error Response
15205 * Control" Bit was clear (0), then set the microcode variable
15206 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15207 * to ignore DMA parity errors.
15209 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
15210 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15211 word |= CONTROL_FLAG_IGNORE_PERR;
15212 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15216 * If the BIOS control flag AIPP (Asynchronous Information
15217 * Phase Protection) disable bit is not set, then set the firmware
15218 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
15219 * AIPP checking and encoding.
15221 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
15222 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15223 word |= CONTROL_FLAG_ENABLE_AIPP;
15224 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15228 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
15229 * and START_CTL_TH [3:2].
15231 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15232 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
15235 * Microcode operating variables for WDTR, SDTR, and command tag
15236 * queuing will be set in slave_configure() based on what a
15237 * device reports it is capable of in Inquiry byte 7.
15239 * If SCSI Bus Resets have been disabled, then directly set
15240 * SDTR and WDTR from the EEPROM configuration. This will allow
15241 * the BIOS and warm boot to work without a SCSI bus hang on
15242 * the Inquiry caused by host and target mismatched DTR values.
15243 * Without the SCSI Bus Reset, before an Inquiry a device can't
15244 * be assumed to be in Asynchronous, Narrow mode.
15246 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
15247 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
15248 asc_dvc->wdtr_able);
15249 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
15250 asc_dvc->sdtr_able);
15254 * Set microcode operating variables for DISC and SDTR_SPEED1,
15255 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15256 * configuration values.
15258 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15259 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15260 * without determining here whether the device supports SDTR.
15262 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
15263 asc_dvc->cfg->disc_enable);
15264 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15265 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15266 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15267 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15270 * Set SCSI_CFG0 Microcode Default Value.
15272 * The microcode will set the SCSI_CFG0 register using this value
15273 * after it is started below.
15275 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15276 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15277 asc_dvc->chip_scsi_id);
15280 * Calculate SCSI_CFG1 Microcode Default Value.
15282 * The microcode will set the SCSI_CFG1 register using this value
15283 * after it is started below.
15285 * Each ASC-38C1600 function has only two cable detect bits.
15286 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
15288 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15291 * If the cable is reversed all of the SCSI_CTRL register signals
15292 * will be set. Check for and return an error if this condition is
15293 * found.
15295 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
15296 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15297 return ADV_ERROR;
15301 * Each ASC-38C1600 function has two connectors. Only an HVD device
15302 * can not be connected to either connector. An LVD device or SE device
15303 * may be connected to either connecor. If an SE device is connected,
15304 * then at most Ultra speed (20 Mhz) can be used on both connectors.
15306 * If an HVD device is attached, return an error.
15308 if (scsi_cfg1 & HVD) {
15309 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15310 return ADV_ERROR;
15314 * Each function in the ASC-38C1600 uses only the SE cable detect and
15315 * termination because there are two connectors for each function. Each
15316 * function may use either LVD or SE mode. Corresponding the SE automatic
15317 * termination control EEPROM bits are used for each function. Each
15318 * function has its own EEPROM. If SE automatic control is enabled for
15319 * the function, then set the termination value based on a table listed
15320 * in a_condor.h.
15322 * If manual termination is specified in the EEPROM for the function,
15323 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
15324 * ready to be 'ored' into SCSI_CFG1.
15326 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
15327 /* SE automatic termination control is enabled. */
15328 switch (scsi_cfg1 & C_DET_SE) {
15329 /* TERM_SE_HI: on, TERM_SE_LO: on */
15330 case 0x1:
15331 case 0x2:
15332 case 0x3:
15333 asc_dvc->cfg->termination |= TERM_SE;
15334 break;
15336 case 0x0:
15337 if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0) {
15338 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
15339 } else {
15340 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
15341 asc_dvc->cfg->termination |= TERM_SE_HI;
15343 break;
15348 * Clear any set TERM_SE bits.
15350 scsi_cfg1 &= ~TERM_SE;
15353 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
15355 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
15358 * Clear Big Endian and Terminator Polarity bits and set possibly
15359 * modified termination control bits in the Microcode SCSI_CFG1
15360 * Register Value.
15362 * Big Endian bit is not used even on big endian machines.
15364 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
15367 * Set SCSI_CFG1 Microcode Default Value
15369 * Set possibly modified termination control bits in the Microcode
15370 * SCSI_CFG1 Register Value.
15372 * The microcode will set the SCSI_CFG1 register using this value
15373 * after it is started below.
15375 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15378 * Set MEM_CFG Microcode Default Value
15380 * The microcode will set the MEM_CFG register using this value
15381 * after it is started below.
15383 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15384 * are defined.
15386 * ASC-38C1600 has 32KB internal memory.
15388 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
15389 * out a special 16K Adv Library and Microcode version. After the issue
15390 * resolved, we should turn back to the 32K support. Both a_condor.h and
15391 * mcode.sas files also need to be updated.
15393 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15394 * BIOS_EN | RAM_SZ_32KB);
15396 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15397 BIOS_EN | RAM_SZ_16KB);
15400 * Set SEL_MASK Microcode Default Value
15402 * The microcode will set the SEL_MASK register using this value
15403 * after it is started below.
15405 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15406 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15409 * Build the carrier freelist.
15411 * Driver must have already allocated memory and set 'carrier_buf'.
15414 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15416 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15417 asc_dvc->carr_freelist = NULL;
15418 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
15419 buf_size = ADV_CARRIER_BUFSIZE;
15420 } else {
15421 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15424 do {
15426 * Get physical address for the carrier 'carrp'.
15428 contig_len = sizeof(ADV_CARR_T);
15429 carr_paddr =
15430 cpu_to_le32(DvcGetPhyAddr
15431 (asc_dvc, NULL, (uchar *)carrp,
15432 (ADV_SDCNT *)&contig_len,
15433 ADV_IS_CARRIER_FLAG));
15435 buf_size -= sizeof(ADV_CARR_T);
15438 * If the current carrier is not physically contiguous, then
15439 * maybe there was a page crossing. Try the next carrier aligned
15440 * start address.
15442 if (contig_len < sizeof(ADV_CARR_T)) {
15443 carrp++;
15444 continue;
15447 carrp->carr_pa = carr_paddr;
15448 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15451 * Insert the carrier at the beginning of the freelist.
15453 carrp->next_vpa =
15454 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15455 asc_dvc->carr_freelist = carrp;
15457 carrp++;
15459 while (buf_size > 0);
15462 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15464 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
15465 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15466 return ADV_ERROR;
15468 asc_dvc->carr_freelist = (ADV_CARR_T *)
15469 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15472 * The first command issued will be placed in the stopper carrier.
15474 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15477 * Set RISC ICQ physical address start value. Initialize the
15478 * COMMA register to the same value otherwise the RISC will
15479 * prematurely detect a command is available.
15481 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15482 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
15483 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
15486 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15488 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
15489 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15490 return ADV_ERROR;
15492 asc_dvc->carr_freelist = (ADV_CARR_T *)
15493 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15496 * The first command completed by the RISC will be placed in
15497 * the stopper.
15499 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15500 * completed the RISC will set the ASC_RQ_STOPPER bit.
15502 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15505 * Set RISC IRQ physical address start value.
15507 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15508 asc_dvc->carr_pending_cnt = 0;
15510 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15511 (ADV_INTR_ENABLE_HOST_INTR |
15512 ADV_INTR_ENABLE_GLOBAL_INTR));
15513 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15514 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15516 /* finally, finally, gentlemen, start your engine */
15517 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15520 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15521 * Resets should be performed. The RISC has to be running
15522 * to issue a SCSI Bus Reset.
15524 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
15526 * If the BIOS Signature is present in memory, restore the
15527 * per TID microcode operating variables.
15529 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
15530 0x55AA) {
15532 * Restore per TID negotiated values.
15534 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15535 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15536 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15537 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
15538 tagqng_able);
15539 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15540 AdvWriteByteLram(iop_base,
15541 ASC_MC_NUMBER_OF_MAX_CMD + tid,
15542 max_cmd[tid]);
15544 } else {
15545 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
15546 warn_code = ASC_WARN_BUSRESET_ERROR;
15551 return warn_code;
15555 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
15556 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
15557 * all of this is done.
15559 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15561 * For a non-fatal error return a warning code. If there are no warnings
15562 * then 0 is returned.
15564 * Note: Chip is stopped on entry.
15566 static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
15568 AdvPortAddr iop_base;
15569 ushort warn_code;
15570 ADVEEP_3550_CONFIG eep_config;
15571 int i;
15573 iop_base = asc_dvc->iop_base;
15575 warn_code = 0;
15578 * Read the board's EEPROM configuration.
15580 * Set default values if a bad checksum is found.
15582 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
15583 warn_code |= ASC_WARN_EEPROM_CHKSUM;
15586 * Set EEPROM default values.
15588 for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++) {
15589 *((uchar *)&eep_config + i) =
15590 *((uchar *)&Default_3550_EEPROM_Config + i);
15594 * Assume the 6 byte board serial number that was read
15595 * from EEPROM is correct even if the EEPROM checksum
15596 * failed.
15598 eep_config.serial_number_word3 =
15599 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
15601 eep_config.serial_number_word2 =
15602 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
15604 eep_config.serial_number_word1 =
15605 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
15607 AdvSet3550EEPConfig(iop_base, &eep_config);
15610 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
15611 * EEPROM configuration that was read.
15613 * This is the mapping of EEPROM fields to Adv Library fields.
15615 asc_dvc->wdtr_able = eep_config.wdtr_able;
15616 asc_dvc->sdtr_able = eep_config.sdtr_able;
15617 asc_dvc->ultra_able = eep_config.ultra_able;
15618 asc_dvc->tagqng_able = eep_config.tagqng_able;
15619 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
15620 asc_dvc->max_host_qng = eep_config.max_host_qng;
15621 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15622 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
15623 asc_dvc->start_motor = eep_config.start_motor;
15624 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
15625 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
15626 asc_dvc->no_scam = eep_config.scam_tolerant;
15627 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
15628 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
15629 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
15632 * Set the host maximum queuing (max. 253, min. 16) and the per device
15633 * maximum queuing (max. 63, min. 4).
15635 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
15636 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15637 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
15638 /* If the value is zero, assume it is uninitialized. */
15639 if (eep_config.max_host_qng == 0) {
15640 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15641 } else {
15642 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
15646 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
15647 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15648 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
15649 /* If the value is zero, assume it is uninitialized. */
15650 if (eep_config.max_dvc_qng == 0) {
15651 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15652 } else {
15653 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
15658 * If 'max_dvc_qng' is greater than 'max_host_qng', then
15659 * set 'max_dvc_qng' to 'max_host_qng'.
15661 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
15662 eep_config.max_dvc_qng = eep_config.max_host_qng;
15666 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
15667 * values based on possibly adjusted EEPROM values.
15669 asc_dvc->max_host_qng = eep_config.max_host_qng;
15670 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15673 * If the EEPROM 'termination' field is set to automatic (0), then set
15674 * the ADV_DVC_CFG 'termination' field to automatic also.
15676 * If the termination is specified with a non-zero 'termination'
15677 * value check that a legal value is set and set the ADV_DVC_CFG
15678 * 'termination' field appropriately.
15680 if (eep_config.termination == 0) {
15681 asc_dvc->cfg->termination = 0; /* auto termination */
15682 } else {
15683 /* Enable manual control with low off / high off. */
15684 if (eep_config.termination == 1) {
15685 asc_dvc->cfg->termination = TERM_CTL_SEL;
15687 /* Enable manual control with low off / high on. */
15688 } else if (eep_config.termination == 2) {
15689 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
15691 /* Enable manual control with low on / high on. */
15692 } else if (eep_config.termination == 3) {
15693 asc_dvc->cfg->termination =
15694 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
15695 } else {
15697 * The EEPROM 'termination' field contains a bad value. Use
15698 * automatic termination instead.
15700 asc_dvc->cfg->termination = 0;
15701 warn_code |= ASC_WARN_EEPROM_TERMINATION;
15705 return warn_code;
15709 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
15710 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
15711 * all of this is done.
15713 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15715 * For a non-fatal error return a warning code. If there are no warnings
15716 * then 0 is returned.
15718 * Note: Chip is stopped on entry.
15720 static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
15722 AdvPortAddr iop_base;
15723 ushort warn_code;
15724 ADVEEP_38C0800_CONFIG eep_config;
15725 int i;
15726 uchar tid, termination;
15727 ushort sdtr_speed = 0;
15729 iop_base = asc_dvc->iop_base;
15731 warn_code = 0;
15734 * Read the board's EEPROM configuration.
15736 * Set default values if a bad checksum is found.
15738 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
15739 eep_config.check_sum) {
15740 warn_code |= ASC_WARN_EEPROM_CHKSUM;
15743 * Set EEPROM default values.
15745 for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++) {
15746 *((uchar *)&eep_config + i) =
15747 *((uchar *)&Default_38C0800_EEPROM_Config + i);
15751 * Assume the 6 byte board serial number that was read
15752 * from EEPROM is correct even if the EEPROM checksum
15753 * failed.
15755 eep_config.serial_number_word3 =
15756 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
15758 eep_config.serial_number_word2 =
15759 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
15761 eep_config.serial_number_word1 =
15762 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
15764 AdvSet38C0800EEPConfig(iop_base, &eep_config);
15767 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
15768 * EEPROM configuration that was read.
15770 * This is the mapping of EEPROM fields to Adv Library fields.
15772 asc_dvc->wdtr_able = eep_config.wdtr_able;
15773 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
15774 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
15775 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
15776 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
15777 asc_dvc->tagqng_able = eep_config.tagqng_able;
15778 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
15779 asc_dvc->max_host_qng = eep_config.max_host_qng;
15780 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15781 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
15782 asc_dvc->start_motor = eep_config.start_motor;
15783 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
15784 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
15785 asc_dvc->no_scam = eep_config.scam_tolerant;
15786 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
15787 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
15788 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
15791 * For every Target ID if any of its 'sdtr_speed[1234]' bits
15792 * are set, then set an 'sdtr_able' bit for it.
15794 asc_dvc->sdtr_able = 0;
15795 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
15796 if (tid == 0) {
15797 sdtr_speed = asc_dvc->sdtr_speed1;
15798 } else if (tid == 4) {
15799 sdtr_speed = asc_dvc->sdtr_speed2;
15800 } else if (tid == 8) {
15801 sdtr_speed = asc_dvc->sdtr_speed3;
15802 } else if (tid == 12) {
15803 sdtr_speed = asc_dvc->sdtr_speed4;
15805 if (sdtr_speed & ADV_MAX_TID) {
15806 asc_dvc->sdtr_able |= (1 << tid);
15808 sdtr_speed >>= 4;
15812 * Set the host maximum queuing (max. 253, min. 16) and the per device
15813 * maximum queuing (max. 63, min. 4).
15815 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
15816 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15817 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
15818 /* If the value is zero, assume it is uninitialized. */
15819 if (eep_config.max_host_qng == 0) {
15820 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15821 } else {
15822 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
15826 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
15827 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15828 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
15829 /* If the value is zero, assume it is uninitialized. */
15830 if (eep_config.max_dvc_qng == 0) {
15831 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15832 } else {
15833 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
15838 * If 'max_dvc_qng' is greater than 'max_host_qng', then
15839 * set 'max_dvc_qng' to 'max_host_qng'.
15841 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
15842 eep_config.max_dvc_qng = eep_config.max_host_qng;
15846 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
15847 * values based on possibly adjusted EEPROM values.
15849 asc_dvc->max_host_qng = eep_config.max_host_qng;
15850 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15853 * If the EEPROM 'termination' field is set to automatic (0), then set
15854 * the ADV_DVC_CFG 'termination' field to automatic also.
15856 * If the termination is specified with a non-zero 'termination'
15857 * value check that a legal value is set and set the ADV_DVC_CFG
15858 * 'termination' field appropriately.
15860 if (eep_config.termination_se == 0) {
15861 termination = 0; /* auto termination for SE */
15862 } else {
15863 /* Enable manual control with low off / high off. */
15864 if (eep_config.termination_se == 1) {
15865 termination = 0;
15867 /* Enable manual control with low off / high on. */
15868 } else if (eep_config.termination_se == 2) {
15869 termination = TERM_SE_HI;
15871 /* Enable manual control with low on / high on. */
15872 } else if (eep_config.termination_se == 3) {
15873 termination = TERM_SE;
15874 } else {
15876 * The EEPROM 'termination_se' field contains a bad value.
15877 * Use automatic termination instead.
15879 termination = 0;
15880 warn_code |= ASC_WARN_EEPROM_TERMINATION;
15884 if (eep_config.termination_lvd == 0) {
15885 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
15886 } else {
15887 /* Enable manual control with low off / high off. */
15888 if (eep_config.termination_lvd == 1) {
15889 asc_dvc->cfg->termination = termination;
15891 /* Enable manual control with low off / high on. */
15892 } else if (eep_config.termination_lvd == 2) {
15893 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
15895 /* Enable manual control with low on / high on. */
15896 } else if (eep_config.termination_lvd == 3) {
15897 asc_dvc->cfg->termination = termination | TERM_LVD;
15898 } else {
15900 * The EEPROM 'termination_lvd' field contains a bad value.
15901 * Use automatic termination instead.
15903 asc_dvc->cfg->termination = termination;
15904 warn_code |= ASC_WARN_EEPROM_TERMINATION;
15908 return warn_code;
15912 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
15913 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
15914 * all of this is done.
15916 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
15918 * For a non-fatal error return a warning code. If there are no warnings
15919 * then 0 is returned.
15921 * Note: Chip is stopped on entry.
15923 static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
15925 AdvPortAddr iop_base;
15926 ushort warn_code;
15927 ADVEEP_38C1600_CONFIG eep_config;
15928 int i;
15929 uchar tid, termination;
15930 ushort sdtr_speed = 0;
15932 iop_base = asc_dvc->iop_base;
15934 warn_code = 0;
15937 * Read the board's EEPROM configuration.
15939 * Set default values if a bad checksum is found.
15941 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
15942 eep_config.check_sum) {
15943 warn_code |= ASC_WARN_EEPROM_CHKSUM;
15946 * Set EEPROM default values.
15948 for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++) {
15949 if (i == 1
15950 && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) !=
15951 0) {
15953 * Set Function 1 EEPROM Word 0 MSB
15955 * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11)
15956 * EEPROM bits.
15958 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and
15959 * old Mac system booting problem. The Expansion ROM must
15960 * be disabled in Function 1 for these systems.
15963 *((uchar *)&eep_config + i) =
15965 ((uchar *)&Default_38C1600_EEPROM_Config
15967 i)) &
15969 (((ADV_EEPROM_BIOS_ENABLE |
15970 ADV_EEPROM_INTAB) >> 8) & 0xFF)));
15973 * Set the INTAB (bit 11) if the GPIO 0 input indicates
15974 * the Function 1 interrupt line is wired to INTA.
15976 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
15977 * 1 - Function 1 interrupt line wired to INT A.
15978 * 0 - Function 1 interrupt line wired to INT B.
15980 * Note: Adapter boards always have Function 0 wired to INTA.
15981 * Put all 5 GPIO bits in input mode and then read
15982 * their input values.
15984 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL,
15986 if (AdvReadByteRegister
15987 (iop_base, IOPB_GPIO_DATA) & 0x01) {
15988 /* Function 1 interrupt wired to INTA; Set EEPROM bit. */
15989 *((uchar *)&eep_config + i) |=
15990 ((ADV_EEPROM_INTAB >> 8) & 0xFF);
15992 } else {
15993 *((uchar *)&eep_config + i) =
15994 *((uchar *)&Default_38C1600_EEPROM_Config
15995 + i);
16000 * Assume the 6 byte board serial number that was read
16001 * from EEPROM is correct even if the EEPROM checksum
16002 * failed.
16004 eep_config.serial_number_word3 =
16005 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16007 eep_config.serial_number_word2 =
16008 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16010 eep_config.serial_number_word1 =
16011 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16013 AdvSet38C1600EEPConfig(iop_base, &eep_config);
16017 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16018 * EEPROM configuration that was read.
16020 * This is the mapping of EEPROM fields to Adv Library fields.
16022 asc_dvc->wdtr_able = eep_config.wdtr_able;
16023 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16024 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16025 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16026 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16027 asc_dvc->ppr_able = 0;
16028 asc_dvc->tagqng_able = eep_config.tagqng_able;
16029 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16030 asc_dvc->max_host_qng = eep_config.max_host_qng;
16031 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16032 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
16033 asc_dvc->start_motor = eep_config.start_motor;
16034 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16035 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16036 asc_dvc->no_scam = eep_config.scam_tolerant;
16039 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16040 * are set, then set an 'sdtr_able' bit for it.
16042 asc_dvc->sdtr_able = 0;
16043 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
16044 if (tid == 0) {
16045 sdtr_speed = asc_dvc->sdtr_speed1;
16046 } else if (tid == 4) {
16047 sdtr_speed = asc_dvc->sdtr_speed2;
16048 } else if (tid == 8) {
16049 sdtr_speed = asc_dvc->sdtr_speed3;
16050 } else if (tid == 12) {
16051 sdtr_speed = asc_dvc->sdtr_speed4;
16053 if (sdtr_speed & ASC_MAX_TID) {
16054 asc_dvc->sdtr_able |= (1 << tid);
16056 sdtr_speed >>= 4;
16060 * Set the host maximum queuing (max. 253, min. 16) and the per device
16061 * maximum queuing (max. 63, min. 4).
16063 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
16064 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16065 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
16066 /* If the value is zero, assume it is uninitialized. */
16067 if (eep_config.max_host_qng == 0) {
16068 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16069 } else {
16070 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16074 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
16075 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16076 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
16077 /* If the value is zero, assume it is uninitialized. */
16078 if (eep_config.max_dvc_qng == 0) {
16079 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16080 } else {
16081 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16086 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16087 * set 'max_dvc_qng' to 'max_host_qng'.
16089 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
16090 eep_config.max_dvc_qng = eep_config.max_host_qng;
16094 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
16095 * values based on possibly adjusted EEPROM values.
16097 asc_dvc->max_host_qng = eep_config.max_host_qng;
16098 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16101 * If the EEPROM 'termination' field is set to automatic (0), then set
16102 * the ASC_DVC_CFG 'termination' field to automatic also.
16104 * If the termination is specified with a non-zero 'termination'
16105 * value check that a legal value is set and set the ASC_DVC_CFG
16106 * 'termination' field appropriately.
16108 if (eep_config.termination_se == 0) {
16109 termination = 0; /* auto termination for SE */
16110 } else {
16111 /* Enable manual control with low off / high off. */
16112 if (eep_config.termination_se == 1) {
16113 termination = 0;
16115 /* Enable manual control with low off / high on. */
16116 } else if (eep_config.termination_se == 2) {
16117 termination = TERM_SE_HI;
16119 /* Enable manual control with low on / high on. */
16120 } else if (eep_config.termination_se == 3) {
16121 termination = TERM_SE;
16122 } else {
16124 * The EEPROM 'termination_se' field contains a bad value.
16125 * Use automatic termination instead.
16127 termination = 0;
16128 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16132 if (eep_config.termination_lvd == 0) {
16133 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
16134 } else {
16135 /* Enable manual control with low off / high off. */
16136 if (eep_config.termination_lvd == 1) {
16137 asc_dvc->cfg->termination = termination;
16139 /* Enable manual control with low off / high on. */
16140 } else if (eep_config.termination_lvd == 2) {
16141 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16143 /* Enable manual control with low on / high on. */
16144 } else if (eep_config.termination_lvd == 3) {
16145 asc_dvc->cfg->termination = termination | TERM_LVD;
16146 } else {
16148 * The EEPROM 'termination_lvd' field contains a bad value.
16149 * Use automatic termination instead.
16151 asc_dvc->cfg->termination = termination;
16152 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16156 return warn_code;
16160 * Read EEPROM configuration into the specified buffer.
16162 * Return a checksum based on the EEPROM configuration read.
16164 static ushort __devinit
16165 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16167 ushort wval, chksum;
16168 ushort *wbuf;
16169 int eep_addr;
16170 ushort *charfields;
16172 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16173 wbuf = (ushort *)cfg_buf;
16174 chksum = 0;
16176 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16177 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16178 wval = AdvReadEEPWord(iop_base, eep_addr);
16179 chksum += wval; /* Checksum is calculated from word values. */
16180 if (*charfields++) {
16181 *wbuf = le16_to_cpu(wval);
16182 } else {
16183 *wbuf = wval;
16186 /* Read checksum word. */
16187 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16188 wbuf++;
16189 charfields++;
16191 /* Read rest of EEPROM not covered by the checksum. */
16192 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16193 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16194 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16195 if (*charfields++) {
16196 *wbuf = le16_to_cpu(*wbuf);
16199 return chksum;
16203 * Read EEPROM configuration into the specified buffer.
16205 * Return a checksum based on the EEPROM configuration read.
16207 static ushort __devinit
16208 AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
16210 ushort wval, chksum;
16211 ushort *wbuf;
16212 int eep_addr;
16213 ushort *charfields;
16215 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16216 wbuf = (ushort *)cfg_buf;
16217 chksum = 0;
16219 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16220 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16221 wval = AdvReadEEPWord(iop_base, eep_addr);
16222 chksum += wval; /* Checksum is calculated from word values. */
16223 if (*charfields++) {
16224 *wbuf = le16_to_cpu(wval);
16225 } else {
16226 *wbuf = wval;
16229 /* Read checksum word. */
16230 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16231 wbuf++;
16232 charfields++;
16234 /* Read rest of EEPROM not covered by the checksum. */
16235 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16236 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16237 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16238 if (*charfields++) {
16239 *wbuf = le16_to_cpu(*wbuf);
16242 return chksum;
16246 * Read EEPROM configuration into the specified buffer.
16248 * Return a checksum based on the EEPROM configuration read.
16250 static ushort __devinit
16251 AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
16253 ushort wval, chksum;
16254 ushort *wbuf;
16255 int eep_addr;
16256 ushort *charfields;
16258 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16259 wbuf = (ushort *)cfg_buf;
16260 chksum = 0;
16262 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16263 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16264 wval = AdvReadEEPWord(iop_base, eep_addr);
16265 chksum += wval; /* Checksum is calculated from word values. */
16266 if (*charfields++) {
16267 *wbuf = le16_to_cpu(wval);
16268 } else {
16269 *wbuf = wval;
16272 /* Read checksum word. */
16273 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16274 wbuf++;
16275 charfields++;
16277 /* Read rest of EEPROM not covered by the checksum. */
16278 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16279 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16280 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16281 if (*charfields++) {
16282 *wbuf = le16_to_cpu(*wbuf);
16285 return chksum;
16289 * Read the EEPROM from specified location
16291 static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
16293 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16294 ASC_EEP_CMD_READ | eep_word_addr);
16295 AdvWaitEEPCmd(iop_base);
16296 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
16300 * Wait for EEPROM command to complete
16302 static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
16304 int eep_delay_ms;
16306 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
16307 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
16308 ASC_EEP_CMD_DONE) {
16309 break;
16311 DvcSleepMilliSecond(1);
16313 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
16314 0) {
16315 ASC_ASSERT(0);
16317 return;
16321 * Write the EEPROM from 'cfg_buf'.
16323 void __devinit
16324 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16326 ushort *wbuf;
16327 ushort addr, chksum;
16328 ushort *charfields;
16330 wbuf = (ushort *)cfg_buf;
16331 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16332 chksum = 0;
16334 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16335 AdvWaitEEPCmd(iop_base);
16338 * Write EEPROM from word 0 to word 20.
16340 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16341 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16342 ushort word;
16344 if (*charfields++) {
16345 word = cpu_to_le16(*wbuf);
16346 } else {
16347 word = *wbuf;
16349 chksum += *wbuf; /* Checksum is calculated from word values. */
16350 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16351 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16352 ASC_EEP_CMD_WRITE | addr);
16353 AdvWaitEEPCmd(iop_base);
16354 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16358 * Write EEPROM checksum at word 21.
16360 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16361 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16362 AdvWaitEEPCmd(iop_base);
16363 wbuf++;
16364 charfields++;
16367 * Write EEPROM OEM name at words 22 to 29.
16369 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16370 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16371 ushort word;
16373 if (*charfields++) {
16374 word = cpu_to_le16(*wbuf);
16375 } else {
16376 word = *wbuf;
16378 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16379 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16380 ASC_EEP_CMD_WRITE | addr);
16381 AdvWaitEEPCmd(iop_base);
16383 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16384 AdvWaitEEPCmd(iop_base);
16385 return;
16389 * Write the EEPROM from 'cfg_buf'.
16391 void __devinit
16392 AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
16394 ushort *wbuf;
16395 ushort *charfields;
16396 ushort addr, chksum;
16398 wbuf = (ushort *)cfg_buf;
16399 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16400 chksum = 0;
16402 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16403 AdvWaitEEPCmd(iop_base);
16406 * Write EEPROM from word 0 to word 20.
16408 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16409 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16410 ushort word;
16412 if (*charfields++) {
16413 word = cpu_to_le16(*wbuf);
16414 } else {
16415 word = *wbuf;
16417 chksum += *wbuf; /* Checksum is calculated from word values. */
16418 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16419 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16420 ASC_EEP_CMD_WRITE | addr);
16421 AdvWaitEEPCmd(iop_base);
16422 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16426 * Write EEPROM checksum at word 21.
16428 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16429 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16430 AdvWaitEEPCmd(iop_base);
16431 wbuf++;
16432 charfields++;
16435 * Write EEPROM OEM name at words 22 to 29.
16437 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16438 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16439 ushort word;
16441 if (*charfields++) {
16442 word = cpu_to_le16(*wbuf);
16443 } else {
16444 word = *wbuf;
16446 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16447 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16448 ASC_EEP_CMD_WRITE | addr);
16449 AdvWaitEEPCmd(iop_base);
16451 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16452 AdvWaitEEPCmd(iop_base);
16453 return;
16457 * Write the EEPROM from 'cfg_buf'.
16459 void __devinit
16460 AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
16462 ushort *wbuf;
16463 ushort *charfields;
16464 ushort addr, chksum;
16466 wbuf = (ushort *)cfg_buf;
16467 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16468 chksum = 0;
16470 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16471 AdvWaitEEPCmd(iop_base);
16474 * Write EEPROM from word 0 to word 20.
16476 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16477 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16478 ushort word;
16480 if (*charfields++) {
16481 word = cpu_to_le16(*wbuf);
16482 } else {
16483 word = *wbuf;
16485 chksum += *wbuf; /* Checksum is calculated from word values. */
16486 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16487 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16488 ASC_EEP_CMD_WRITE | addr);
16489 AdvWaitEEPCmd(iop_base);
16490 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16494 * Write EEPROM checksum at word 21.
16496 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16497 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16498 AdvWaitEEPCmd(iop_base);
16499 wbuf++;
16500 charfields++;
16503 * Write EEPROM OEM name at words 22 to 29.
16505 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16506 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16507 ushort word;
16509 if (*charfields++) {
16510 word = cpu_to_le16(*wbuf);
16511 } else {
16512 word = *wbuf;
16514 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16515 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16516 ASC_EEP_CMD_WRITE | addr);
16517 AdvWaitEEPCmd(iop_base);
16519 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16520 AdvWaitEEPCmd(iop_base);
16521 return;
16524 /* a_advlib.c */
16526 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
16528 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
16529 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
16530 * RISC to notify it a new command is ready to be executed.
16532 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
16533 * set to SCSI_MAX_RETRY.
16535 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
16536 * for DMA addresses or math operations are byte swapped to little-endian
16537 * order.
16539 * Return:
16540 * ADV_SUCCESS(1) - The request was successfully queued.
16541 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
16542 * request completes.
16543 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
16544 * host IC error.
16546 static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
16548 ulong last_int_level;
16549 AdvPortAddr iop_base;
16550 ADV_DCNT req_size;
16551 ADV_PADDR req_paddr;
16552 ADV_CARR_T *new_carrp;
16554 ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
16557 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
16559 if (scsiq->target_id > ADV_MAX_TID) {
16560 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
16561 scsiq->done_status = QD_WITH_ERROR;
16562 return ADV_ERROR;
16565 iop_base = asc_dvc->iop_base;
16567 last_int_level = DvcEnterCritical();
16570 * Allocate a carrier ensuring at least one carrier always
16571 * remains on the freelist and initialize fields.
16573 if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
16574 DvcLeaveCritical(last_int_level);
16575 return ADV_BUSY;
16577 asc_dvc->carr_freelist = (ADV_CARR_T *)
16578 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
16579 asc_dvc->carr_pending_cnt++;
16582 * Set the carrier to be a stopper by setting 'next_vpa'
16583 * to the stopper value. The current stopper will be changed
16584 * below to point to the new stopper.
16586 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16589 * Clear the ADV_SCSI_REQ_Q done flag.
16591 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
16593 req_size = sizeof(ADV_SCSI_REQ_Q);
16594 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
16595 (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
16597 ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
16598 ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
16600 /* Wait for assertion before making little-endian */
16601 req_paddr = cpu_to_le32(req_paddr);
16603 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
16604 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
16605 scsiq->scsiq_rptr = req_paddr;
16607 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
16609 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
16610 * order during initialization.
16612 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
16615 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
16616 * the microcode. The newly allocated stopper will become the new
16617 * stopper.
16619 asc_dvc->icq_sp->areq_vpa = req_paddr;
16622 * Set the 'next_vpa' pointer for the old stopper to be the
16623 * physical address of the new stopper. The RISC can only
16624 * follow physical addresses.
16626 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
16629 * Set the host adapter stopper pointer to point to the new carrier.
16631 asc_dvc->icq_sp = new_carrp;
16633 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
16634 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
16636 * Tickle the RISC to tell it to read its Command Queue Head pointer.
16638 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
16639 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
16641 * Clear the tickle value. In the ASC-3550 the RISC flag
16642 * command 'clr_tickle_a' does not work unless the host
16643 * value is cleared.
16645 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
16646 ADV_TICKLE_NOP);
16648 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16650 * Notify the RISC a carrier is ready by writing the physical
16651 * address of the new carrier stopper to the COMMA register.
16653 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
16654 le32_to_cpu(new_carrp->carr_pa));
16657 DvcLeaveCritical(last_int_level);
16659 return ADV_SUCCESS;
16663 * Reset SCSI Bus and purge all outstanding requests.
16665 * Return Value:
16666 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
16667 * ADV_FALSE(0) - Microcode command failed.
16668 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
16669 * may be hung which requires driver recovery.
16671 static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
16673 int status;
16676 * Send the SCSI Bus Reset idle start idle command which asserts
16677 * the SCSI Bus Reset signal.
16679 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
16680 if (status != ADV_TRUE) {
16681 return status;
16685 * Delay for the specified SCSI Bus Reset hold time.
16687 * The hold time delay is done on the host because the RISC has no
16688 * microsecond accurate timer.
16690 DvcDelayMicroSecond(asc_dvc, (ushort)ASC_SCSI_RESET_HOLD_TIME_US);
16693 * Send the SCSI Bus Reset end idle command which de-asserts
16694 * the SCSI Bus Reset signal and purges any pending requests.
16696 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
16697 if (status != ADV_TRUE) {
16698 return status;
16701 DvcSleepMilliSecond((ADV_DCNT)asc_dvc->scsi_reset_wait * 1000);
16703 return status;
16707 * Reset chip and SCSI Bus.
16709 * Return Value:
16710 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
16711 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
16713 static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
16715 int status;
16716 ushort wdtr_able, sdtr_able, tagqng_able;
16717 ushort ppr_able = 0;
16718 uchar tid, max_cmd[ADV_MAX_TID + 1];
16719 AdvPortAddr iop_base;
16720 ushort bios_sig;
16722 iop_base = asc_dvc->iop_base;
16725 * Save current per TID negotiated values.
16727 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16728 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16729 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16730 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16732 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16733 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
16734 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16735 max_cmd[tid]);
16739 * Force the AdvInitAsc3550/38C0800Driver() function to
16740 * perform a SCSI Bus Reset by clearing the BIOS signature word.
16741 * The initialization functions assumes a SCSI Bus Reset is not
16742 * needed if the BIOS signature word is present.
16744 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
16745 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
16748 * Stop chip and reset it.
16750 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
16751 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
16752 DvcSleepMilliSecond(100);
16753 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
16754 ADV_CTRL_REG_CMD_WR_IO_REG);
16757 * Reset Adv Library error code, if any, and try
16758 * re-initializing the chip.
16760 asc_dvc->err_code = 0;
16761 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16762 status = AdvInitAsc38C1600Driver(asc_dvc);
16763 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
16764 status = AdvInitAsc38C0800Driver(asc_dvc);
16765 } else {
16766 status = AdvInitAsc3550Driver(asc_dvc);
16769 /* Translate initialization return value to status value. */
16770 if (status == 0) {
16771 status = ADV_TRUE;
16772 } else {
16773 status = ADV_FALSE;
16777 * Restore the BIOS signature word.
16779 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
16782 * Restore per TID negotiated values.
16784 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16785 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16786 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16787 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16789 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16790 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
16791 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16792 max_cmd[tid]);
16795 return status;
16799 * Adv Library Interrupt Service Routine
16801 * This function is called by a driver's interrupt service routine.
16802 * The function disables and re-enables interrupts.
16804 * When a microcode idle command is completed, the ADV_DVC_VAR
16805 * 'idle_cmd_done' field is set to ADV_TRUE.
16807 * Note: AdvISR() can be called when interrupts are disabled or even
16808 * when there is no hardware interrupt condition present. It will
16809 * always check for completed idle commands and microcode requests.
16810 * This is an important feature that shouldn't be changed because it
16811 * allows commands to be completed from polling mode loops.
16813 * Return:
16814 * ADV_TRUE(1) - interrupt was pending
16815 * ADV_FALSE(0) - no interrupt was pending
16817 static int AdvISR(ADV_DVC_VAR *asc_dvc)
16819 AdvPortAddr iop_base;
16820 uchar int_stat;
16821 ushort target_bit;
16822 ADV_CARR_T *free_carrp;
16823 ADV_VADDR irq_next_vpa;
16824 int flags;
16825 ADV_SCSI_REQ_Q *scsiq;
16827 flags = DvcEnterCritical();
16829 iop_base = asc_dvc->iop_base;
16831 /* Reading the register clears the interrupt. */
16832 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
16834 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
16835 ADV_INTR_STATUS_INTRC)) == 0) {
16836 DvcLeaveCritical(flags);
16837 return ADV_FALSE;
16841 * Notify the driver of an asynchronous microcode condition by
16842 * calling the ADV_DVC_VAR.async_callback function. The function
16843 * is passed the microcode ASC_MC_INTRB_CODE byte value.
16845 if (int_stat & ADV_INTR_STATUS_INTRB) {
16846 uchar intrb_code;
16848 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
16850 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
16851 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
16852 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
16853 asc_dvc->carr_pending_cnt != 0) {
16854 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
16855 ADV_TICKLE_A);
16856 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
16857 AdvWriteByteRegister(iop_base,
16858 IOPB_TICKLE,
16859 ADV_TICKLE_NOP);
16864 if (asc_dvc->async_callback != 0) {
16865 (*asc_dvc->async_callback) (asc_dvc, intrb_code);
16870 * Check if the IRQ stopper carrier contains a completed request.
16872 while (((irq_next_vpa =
16873 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
16875 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
16876 * The RISC will have set 'areq_vpa' to a virtual address.
16878 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
16879 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
16880 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
16881 * in AdvExeScsiQueue().
16883 scsiq = (ADV_SCSI_REQ_Q *)
16884 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
16887 * Request finished with good status and the queue was not
16888 * DMAed to host memory by the firmware. Set all status fields
16889 * to indicate good status.
16891 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
16892 scsiq->done_status = QD_NO_ERROR;
16893 scsiq->host_status = scsiq->scsi_status = 0;
16894 scsiq->data_cnt = 0L;
16898 * Advance the stopper pointer to the next carrier
16899 * ignoring the lower four bits. Free the previous
16900 * stopper carrier.
16902 free_carrp = asc_dvc->irq_sp;
16903 asc_dvc->irq_sp = (ADV_CARR_T *)
16904 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
16906 free_carrp->next_vpa =
16907 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
16908 asc_dvc->carr_freelist = free_carrp;
16909 asc_dvc->carr_pending_cnt--;
16911 ASC_ASSERT(scsiq != NULL);
16912 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
16915 * Clear request microcode control flag.
16917 scsiq->cntl = 0;
16920 * Notify the driver of the completed request by passing
16921 * the ADV_SCSI_REQ_Q pointer to its callback function.
16923 scsiq->a_flag |= ADV_SCSIQ_DONE;
16924 (*asc_dvc->isr_callback) (asc_dvc, scsiq);
16926 * Note: After the driver callback function is called, 'scsiq'
16927 * can no longer be referenced.
16929 * Fall through and continue processing other completed
16930 * requests...
16934 * Disable interrupts again in case the driver inadvertently
16935 * enabled interrupts in its callback function.
16937 * The DvcEnterCritical() return value is ignored, because
16938 * the 'flags' saved when AdvISR() was first entered will be
16939 * used to restore the interrupt flag on exit.
16941 (void)DvcEnterCritical();
16943 DvcLeaveCritical(flags);
16944 return ADV_TRUE;
16948 * Send an idle command to the chip and wait for completion.
16950 * Command completion is polled for once per microsecond.
16952 * The function can be called from anywhere including an interrupt handler.
16953 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
16954 * functions to prevent reentrancy.
16956 * Return Values:
16957 * ADV_TRUE - command completed successfully
16958 * ADV_FALSE - command failed
16959 * ADV_ERROR - command timed out
16961 static int
16962 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
16963 ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
16965 ulong last_int_level;
16966 int result;
16967 ADV_DCNT i, j;
16968 AdvPortAddr iop_base;
16970 last_int_level = DvcEnterCritical();
16972 iop_base = asc_dvc->iop_base;
16975 * Clear the idle command status which is set by the microcode
16976 * to a non-zero value to indicate when the command is completed.
16977 * The non-zero result is one of the IDLE_CMD_STATUS_* values
16978 * defined in a_advlib.h.
16980 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
16983 * Write the idle command value after the idle command parameter
16984 * has been written to avoid a race condition. If the order is not
16985 * followed, the microcode may process the idle command before the
16986 * parameters have been written to LRAM.
16988 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
16989 cpu_to_le32(idle_cmd_parameter));
16990 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
16993 * Tickle the RISC to tell it to process the idle command.
16995 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
16996 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
16998 * Clear the tickle value. In the ASC-3550 the RISC flag
16999 * command 'clr_tickle_b' does not work unless the host
17000 * value is cleared.
17002 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17005 /* Wait for up to 100 millisecond for the idle command to timeout. */
17006 for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
17007 /* Poll once each microsecond for command completion. */
17008 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
17009 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
17010 result);
17011 if (result != 0) {
17012 DvcLeaveCritical(last_int_level);
17013 return result;
17015 DvcDelayMicroSecond(asc_dvc, (ushort)1);
17019 ASC_ASSERT(0); /* The idle command should never timeout. */
17020 DvcLeaveCritical(last_int_level);
17021 return ADV_ERROR;
17024 static int __devinit
17025 advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
17027 int req_cnt = 0;
17028 adv_req_t *reqp = NULL;
17029 int sg_cnt = 0;
17030 adv_sgblk_t *sgp;
17031 int warn_code, err_code;
17034 * Allocate buffer carrier structures. The total size
17035 * is about 4 KB, so allocate all at once.
17037 boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
17038 ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp);
17040 if (!boardp->carrp)
17041 goto kmalloc_failed;
17044 * Allocate up to 'max_host_qng' request structures for the Wide
17045 * board. The total size is about 16 KB, so allocate all at once.
17046 * If the allocation fails decrement and try again.
17048 for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
17049 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
17051 ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, "
17052 "bytes %lu\n", reqp, req_cnt,
17053 (ulong)sizeof(adv_req_t) * req_cnt);
17055 if (reqp)
17056 break;
17059 if (!reqp)
17060 goto kmalloc_failed;
17062 boardp->orig_reqp = reqp;
17065 * Allocate up to ADV_TOT_SG_BLOCK request structures for
17066 * the Wide board. Each structure is about 136 bytes.
17068 boardp->adv_sgblkp = NULL;
17069 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
17070 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
17072 if (!sgp)
17073 break;
17075 sgp->next_sgblkp = boardp->adv_sgblkp;
17076 boardp->adv_sgblkp = sgp;
17080 ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n",
17081 sg_cnt, sizeof(adv_sgblk_t),
17082 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
17084 if (!boardp->adv_sgblkp)
17085 goto kmalloc_failed;
17087 adv_dvc_varp->carrier_buf = boardp->carrp;
17090 * Point 'adv_reqp' to the request structures and
17091 * link them together.
17093 req_cnt--;
17094 reqp[req_cnt].next_reqp = NULL;
17095 for (; req_cnt > 0; req_cnt--) {
17096 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
17098 boardp->adv_reqp = &reqp[0];
17100 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17101 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n");
17102 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
17103 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17104 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()"
17105 "\n");
17106 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
17107 } else {
17108 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()"
17109 "\n");
17110 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
17112 err_code = adv_dvc_varp->err_code;
17114 if (warn_code || err_code) {
17115 ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
17116 " error 0x%x\n", boardp->id, warn_code, err_code);
17119 goto exit;
17121 kmalloc_failed:
17122 ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
17123 "failed\n", boardp->id);
17124 err_code = ADV_ERROR;
17125 exit:
17126 return err_code;
17129 static void advansys_wide_free_mem(asc_board_t *boardp)
17131 kfree(boardp->carrp);
17132 boardp->carrp = NULL;
17133 kfree(boardp->orig_reqp);
17134 boardp->orig_reqp = boardp->adv_reqp = NULL;
17135 while (boardp->adv_sgblkp) {
17136 adv_sgblk_t *sgp = boardp->adv_sgblkp;
17137 boardp->adv_sgblkp = sgp->next_sgblkp;
17138 kfree(sgp);
17142 static struct Scsi_Host *__devinit
17143 advansys_board_found(int iop, struct device *dev, int bus_type)
17145 struct Scsi_Host *shost;
17146 struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL;
17147 asc_board_t *boardp;
17148 ASC_DVC_VAR *asc_dvc_varp = NULL;
17149 ADV_DVC_VAR *adv_dvc_varp = NULL;
17150 int share_irq;
17151 int iolen = 0;
17152 ADV_PADDR pci_memory_address;
17153 int warn_code, err_code;
17154 int ret;
17157 * Adapter found.
17159 * Register the adapter, get its configuration, and
17160 * initialize it.
17162 ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n");
17163 shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t));
17165 if (!shost)
17166 return NULL;
17168 /* Initialize private per board data */
17169 boardp = ASC_BOARDP(shost);
17170 memset(boardp, 0, sizeof(asc_board_t));
17171 boardp->id = asc_board_count++;
17173 /* Initialize spinlock. */
17174 spin_lock_init(&boardp->lock);
17177 * Handle both narrow and wide boards.
17179 * If a Wide board was detected, set the board structure
17180 * wide board flag. Set-up the board structure based on
17181 * the board type.
17183 #ifdef CONFIG_PCI
17184 if (bus_type == ASC_IS_PCI &&
17185 (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
17186 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
17187 pdev->device == PCI_DEVICE_ID_38C1600_REV1)) {
17188 boardp->flags |= ASC_IS_WIDE_BOARD;
17190 #endif /* CONFIG_PCI */
17192 if (ASC_NARROW_BOARD(boardp)) {
17193 ASC_DBG(1, "advansys_board_found: narrow board\n");
17194 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
17195 asc_dvc_varp->bus_type = bus_type;
17196 asc_dvc_varp->drv_ptr = boardp;
17197 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
17198 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
17199 asc_dvc_varp->iop_base = iop;
17200 asc_dvc_varp->isr_callback = asc_isr_callback;
17201 } else {
17202 ASC_DBG(1, "advansys_board_found: wide board\n");
17203 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
17204 adv_dvc_varp->drv_ptr = boardp;
17205 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
17206 adv_dvc_varp->isr_callback = adv_isr_callback;
17207 adv_dvc_varp->async_callback = adv_async_callback;
17208 #ifdef CONFIG_PCI
17209 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
17210 ASC_DBG(1, "advansys_board_found: ASC-3550\n");
17211 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
17212 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
17213 ASC_DBG(1, "advansys_board_found: ASC-38C0800\n");
17214 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
17215 } else {
17216 ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
17217 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
17219 #endif /* CONFIG_PCI */
17222 * Map the board's registers into virtual memory for
17223 * PCI slave access. Only memory accesses are used to
17224 * access the board's registers.
17226 * Note: The PCI register base address is not always
17227 * page aligned, but the address passed to ioremap()
17228 * must be page aligned. It is guaranteed that the
17229 * PCI register base address will not cross a page
17230 * boundary.
17232 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17233 iolen = ADV_3550_IOLEN;
17234 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17235 iolen = ADV_38C0800_IOLEN;
17236 } else {
17237 iolen = ADV_38C1600_IOLEN;
17239 #ifdef CONFIG_PCI
17240 pci_memory_address = pci_resource_start(pdev, 1);
17241 ASC_DBG1(1,
17242 "advansys_board_found: pci_memory_address: 0x%lx\n",
17243 (ulong)pci_memory_address);
17244 if ((boardp->ioremap_addr =
17245 ioremap(pci_memory_address & PAGE_MASK, PAGE_SIZE)) == 0) {
17246 ASC_PRINT3
17247 ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
17248 boardp->id, pci_memory_address, iolen);
17249 goto err_shost;
17251 ASC_DBG1(1, "advansys_board_found: ioremap_addr: 0x%lx\n",
17252 (ulong)boardp->ioremap_addr);
17253 adv_dvc_varp->iop_base = (AdvPortAddr)
17254 (boardp->ioremap_addr +
17255 (pci_memory_address - (pci_memory_address & PAGE_MASK)));
17256 ASC_DBG1(1, "advansys_board_found: iop_base: 0x%lx\n",
17257 adv_dvc_varp->iop_base);
17258 #endif /* CONFIG_PCI */
17261 * Even though it isn't used to access wide boards, other
17262 * than for the debug line below, save I/O Port address so
17263 * that it can be reported.
17265 boardp->ioport = iop;
17267 ASC_DBG2(1,
17268 "advansys_board_found: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
17269 (ushort)inp(iop + 1), (ushort)inpw(iop));
17272 #ifdef CONFIG_PROC_FS
17274 * Allocate buffer for printing information from
17275 * /proc/scsi/advansys/[0...].
17277 boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
17278 if (!boardp->prtbuf) {
17279 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
17280 "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
17281 goto err_unmap;
17283 #endif /* CONFIG_PROC_FS */
17285 if (ASC_NARROW_BOARD(boardp)) {
17286 asc_dvc_varp->cfg->dev = dev;
17288 * Set the board bus type and PCI IRQ before
17289 * calling AscInitGetConfig().
17291 switch (asc_dvc_varp->bus_type) {
17292 #ifdef CONFIG_ISA
17293 case ASC_IS_ISA:
17294 shost->unchecked_isa_dma = TRUE;
17295 share_irq = 0;
17296 break;
17297 case ASC_IS_VL:
17298 shost->unchecked_isa_dma = FALSE;
17299 share_irq = 0;
17300 break;
17301 case ASC_IS_EISA:
17302 shost->unchecked_isa_dma = FALSE;
17303 share_irq = IRQF_SHARED;
17304 break;
17305 #endif /* CONFIG_ISA */
17306 #ifdef CONFIG_PCI
17307 case ASC_IS_PCI:
17308 shost->irq = asc_dvc_varp->irq_no = pdev->irq;
17309 asc_dvc_varp->cfg->pci_slot_info =
17310 ASC_PCI_MKID(pdev->bus->number,
17311 PCI_SLOT(pdev->devfn),
17312 PCI_FUNC(pdev->devfn));
17313 shost->unchecked_isa_dma = FALSE;
17314 share_irq = IRQF_SHARED;
17315 break;
17316 #endif /* CONFIG_PCI */
17317 default:
17318 ASC_PRINT2
17319 ("advansys_board_found: board %d: unknown adapter type: %d\n",
17320 boardp->id, asc_dvc_varp->bus_type);
17321 shost->unchecked_isa_dma = TRUE;
17322 share_irq = 0;
17323 break;
17325 } else {
17326 adv_dvc_varp->cfg->dev = dev;
17328 * For Wide boards set PCI information before calling
17329 * AdvInitGetConfig().
17331 #ifdef CONFIG_PCI
17332 shost->irq = adv_dvc_varp->irq_no = pdev->irq;
17333 adv_dvc_varp->cfg->pci_slot_info =
17334 ASC_PCI_MKID(pdev->bus->number,
17335 PCI_SLOT(pdev->devfn),
17336 PCI_FUNC(pdev->devfn));
17337 shost->unchecked_isa_dma = FALSE;
17338 share_irq = IRQF_SHARED;
17339 #endif /* CONFIG_PCI */
17343 * Read the board configuration.
17345 if (ASC_NARROW_BOARD(boardp)) {
17347 * NOTE: AscInitGetConfig() may change the board's
17348 * bus_type value. The bus_type value should no
17349 * longer be used. If the bus_type field must be
17350 * referenced only use the bit-wise AND operator "&".
17352 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
17353 switch (ret = AscInitGetConfig(asc_dvc_varp)) {
17354 case 0: /* No error */
17355 break;
17356 case ASC_WARN_IO_PORT_ROTATE:
17357 ASC_PRINT1
17358 ("AscInitGetConfig: board %d: I/O port address modified\n",
17359 boardp->id);
17360 break;
17361 case ASC_WARN_AUTO_CONFIG:
17362 ASC_PRINT1
17363 ("AscInitGetConfig: board %d: I/O port increment switch enabled\n",
17364 boardp->id);
17365 break;
17366 case ASC_WARN_EEPROM_CHKSUM:
17367 ASC_PRINT1
17368 ("AscInitGetConfig: board %d: EEPROM checksum error\n",
17369 boardp->id);
17370 break;
17371 case ASC_WARN_IRQ_MODIFIED:
17372 ASC_PRINT1
17373 ("AscInitGetConfig: board %d: IRQ modified\n",
17374 boardp->id);
17375 break;
17376 case ASC_WARN_CMD_QNG_CONFLICT:
17377 ASC_PRINT1
17378 ("AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
17379 boardp->id);
17380 break;
17381 default:
17382 ASC_PRINT2
17383 ("AscInitGetConfig: board %d: unknown warning: 0x%x\n",
17384 boardp->id, ret);
17385 break;
17387 if ((err_code = asc_dvc_varp->err_code) != 0) {
17388 ASC_PRINT3
17389 ("AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
17390 boardp->id,
17391 asc_dvc_varp->init_state, asc_dvc_varp->err_code);
17393 } else {
17394 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
17395 if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
17396 ASC_PRINT2
17397 ("AdvInitGetConfig: board %d: warning: 0x%x\n",
17398 boardp->id, ret);
17400 if ((err_code = adv_dvc_varp->err_code) != 0) {
17401 ASC_PRINT2
17402 ("AdvInitGetConfig: board %d error: err_code 0x%x\n",
17403 boardp->id, adv_dvc_varp->err_code);
17407 if (err_code != 0)
17408 goto err_free_proc;
17411 * Save the EEPROM configuration so that it can be displayed
17412 * from /proc/scsi/advansys/[0...].
17414 if (ASC_NARROW_BOARD(boardp)) {
17416 ASCEEP_CONFIG *ep;
17419 * Set the adapter's target id bit in the 'init_tidmask' field.
17421 boardp->init_tidmask |=
17422 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
17425 * Save EEPROM settings for the board.
17427 ep = &boardp->eep_config.asc_eep;
17429 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
17430 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
17431 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
17432 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
17433 ep->start_motor = asc_dvc_varp->start_motor;
17434 ep->cntl = asc_dvc_varp->dvc_cntl;
17435 ep->no_scam = asc_dvc_varp->no_scam;
17436 ep->max_total_qng = asc_dvc_varp->max_total_qng;
17437 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
17438 /* 'max_tag_qng' is set to the same value for every device. */
17439 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
17440 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
17441 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
17442 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
17443 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
17444 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
17445 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
17448 * Modify board configuration.
17450 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
17451 switch (ret = AscInitSetConfig(asc_dvc_varp)) {
17452 case 0: /* No error. */
17453 break;
17454 case ASC_WARN_IO_PORT_ROTATE:
17455 ASC_PRINT1
17456 ("AscInitSetConfig: board %d: I/O port address modified\n",
17457 boardp->id);
17458 break;
17459 case ASC_WARN_AUTO_CONFIG:
17460 ASC_PRINT1
17461 ("AscInitSetConfig: board %d: I/O port increment switch enabled\n",
17462 boardp->id);
17463 break;
17464 case ASC_WARN_EEPROM_CHKSUM:
17465 ASC_PRINT1
17466 ("AscInitSetConfig: board %d: EEPROM checksum error\n",
17467 boardp->id);
17468 break;
17469 case ASC_WARN_IRQ_MODIFIED:
17470 ASC_PRINT1
17471 ("AscInitSetConfig: board %d: IRQ modified\n",
17472 boardp->id);
17473 break;
17474 case ASC_WARN_CMD_QNG_CONFLICT:
17475 ASC_PRINT1
17476 ("AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
17477 boardp->id);
17478 break;
17479 default:
17480 ASC_PRINT2
17481 ("AscInitSetConfig: board %d: unknown warning: 0x%x\n",
17482 boardp->id, ret);
17483 break;
17485 if (asc_dvc_varp->err_code != 0) {
17486 ASC_PRINT3
17487 ("AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
17488 boardp->id,
17489 asc_dvc_varp->init_state, asc_dvc_varp->err_code);
17490 goto err_free_proc;
17494 * Finish initializing the 'Scsi_Host' structure.
17496 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
17497 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
17498 shost->irq = asc_dvc_varp->irq_no;
17500 } else {
17501 ADVEEP_3550_CONFIG *ep_3550;
17502 ADVEEP_38C0800_CONFIG *ep_38C0800;
17503 ADVEEP_38C1600_CONFIG *ep_38C1600;
17506 * Save Wide EEP Configuration Information.
17508 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17509 ep_3550 = &boardp->eep_config.adv_3550_eep;
17511 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
17512 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
17513 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17514 ep_3550->termination = adv_dvc_varp->cfg->termination;
17515 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
17516 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
17517 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
17518 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
17519 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
17520 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
17521 ep_3550->start_motor = adv_dvc_varp->start_motor;
17522 ep_3550->scsi_reset_delay =
17523 adv_dvc_varp->scsi_reset_wait;
17524 ep_3550->serial_number_word1 =
17525 adv_dvc_varp->cfg->serial1;
17526 ep_3550->serial_number_word2 =
17527 adv_dvc_varp->cfg->serial2;
17528 ep_3550->serial_number_word3 =
17529 adv_dvc_varp->cfg->serial3;
17530 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17531 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
17533 ep_38C0800->adapter_scsi_id =
17534 adv_dvc_varp->chip_scsi_id;
17535 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
17536 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17537 ep_38C0800->termination_lvd =
17538 adv_dvc_varp->cfg->termination;
17539 ep_38C0800->disc_enable =
17540 adv_dvc_varp->cfg->disc_enable;
17541 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
17542 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
17543 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
17544 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
17545 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
17546 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
17547 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
17548 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
17549 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
17550 ep_38C0800->scsi_reset_delay =
17551 adv_dvc_varp->scsi_reset_wait;
17552 ep_38C0800->serial_number_word1 =
17553 adv_dvc_varp->cfg->serial1;
17554 ep_38C0800->serial_number_word2 =
17555 adv_dvc_varp->cfg->serial2;
17556 ep_38C0800->serial_number_word3 =
17557 adv_dvc_varp->cfg->serial3;
17558 } else {
17559 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
17561 ep_38C1600->adapter_scsi_id =
17562 adv_dvc_varp->chip_scsi_id;
17563 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
17564 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17565 ep_38C1600->termination_lvd =
17566 adv_dvc_varp->cfg->termination;
17567 ep_38C1600->disc_enable =
17568 adv_dvc_varp->cfg->disc_enable;
17569 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
17570 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
17571 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
17572 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
17573 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
17574 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
17575 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
17576 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
17577 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
17578 ep_38C1600->scsi_reset_delay =
17579 adv_dvc_varp->scsi_reset_wait;
17580 ep_38C1600->serial_number_word1 =
17581 adv_dvc_varp->cfg->serial1;
17582 ep_38C1600->serial_number_word2 =
17583 adv_dvc_varp->cfg->serial2;
17584 ep_38C1600->serial_number_word3 =
17585 adv_dvc_varp->cfg->serial3;
17589 * Set the adapter's target id bit in the 'init_tidmask' field.
17591 boardp->init_tidmask |=
17592 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
17595 * Finish initializing the 'Scsi_Host' structure.
17597 shost->irq = adv_dvc_varp->irq_no;
17601 * Channels are numbered beginning with 0. For AdvanSys one host
17602 * structure supports one channel. Multi-channel boards have a
17603 * separate host structure for each channel.
17605 shost->max_channel = 0;
17606 if (ASC_NARROW_BOARD(boardp)) {
17607 shost->max_id = ASC_MAX_TID + 1;
17608 shost->max_lun = ASC_MAX_LUN + 1;
17610 shost->io_port = asc_dvc_varp->iop_base;
17611 boardp->asc_n_io_port = ASC_IOADR_GAP;
17612 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
17614 /* Set maximum number of queues the adapter can handle. */
17615 shost->can_queue = asc_dvc_varp->max_total_qng;
17616 } else {
17617 shost->max_id = ADV_MAX_TID + 1;
17618 shost->max_lun = ADV_MAX_LUN + 1;
17621 * Save the I/O Port address and length even though
17622 * I/O ports are not used to access Wide boards.
17623 * Instead the Wide boards are accessed with
17624 * PCI Memory Mapped I/O.
17626 shost->io_port = iop;
17627 boardp->asc_n_io_port = iolen;
17629 shost->this_id = adv_dvc_varp->chip_scsi_id;
17631 /* Set maximum number of queues the adapter can handle. */
17632 shost->can_queue = adv_dvc_varp->max_host_qng;
17636 * 'n_io_port' currently is one byte.
17638 * Set a value to 'n_io_port', but never referenced it because
17639 * it may be truncated.
17641 shost->n_io_port = boardp->asc_n_io_port <= 255 ?
17642 boardp->asc_n_io_port : 255;
17645 * Following v1.3.89, 'cmd_per_lun' is no longer needed
17646 * and should be set to zero.
17648 * But because of a bug introduced in v1.3.89 if the driver is
17649 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
17650 * SCSI function 'allocate_device' will panic. To allow the driver
17651 * to work as a module in these kernels set 'cmd_per_lun' to 1.
17653 * Note: This is wrong. cmd_per_lun should be set to the depth
17654 * you want on untagged devices always.
17655 #ifdef MODULE
17657 shost->cmd_per_lun = 1;
17658 /* #else
17659 shost->cmd_per_lun = 0;
17660 #endif */
17663 * Set the maximum number of scatter-gather elements the
17664 * adapter can handle.
17666 if (ASC_NARROW_BOARD(boardp)) {
17668 * Allow two commands with 'sg_tablesize' scatter-gather
17669 * elements to be executed simultaneously. This value is
17670 * the theoretical hardware limit. It may be decreased
17671 * below.
17673 shost->sg_tablesize =
17674 (((asc_dvc_varp->max_total_qng - 2) / 2) *
17675 ASC_SG_LIST_PER_Q) + 1;
17676 } else {
17677 shost->sg_tablesize = ADV_MAX_SG_LIST;
17681 * The value of 'sg_tablesize' can not exceed the SCSI
17682 * mid-level driver definition of SG_ALL. SG_ALL also
17683 * must not be exceeded, because it is used to define the
17684 * size of the scatter-gather table in 'struct asc_sg_head'.
17686 if (shost->sg_tablesize > SG_ALL) {
17687 shost->sg_tablesize = SG_ALL;
17690 ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize);
17692 /* BIOS start address. */
17693 if (ASC_NARROW_BOARD(boardp)) {
17694 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
17695 asc_dvc_varp->bus_type);
17696 } else {
17698 * Fill-in BIOS board variables. The Wide BIOS saves
17699 * information in LRAM that is used by the driver.
17701 AdvReadWordLram(adv_dvc_varp->iop_base,
17702 BIOS_SIGNATURE, boardp->bios_signature);
17703 AdvReadWordLram(adv_dvc_varp->iop_base,
17704 BIOS_VERSION, boardp->bios_version);
17705 AdvReadWordLram(adv_dvc_varp->iop_base,
17706 BIOS_CODESEG, boardp->bios_codeseg);
17707 AdvReadWordLram(adv_dvc_varp->iop_base,
17708 BIOS_CODELEN, boardp->bios_codelen);
17710 ASC_DBG2(1,
17711 "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n",
17712 boardp->bios_signature, boardp->bios_version);
17714 ASC_DBG2(1,
17715 "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n",
17716 boardp->bios_codeseg, boardp->bios_codelen);
17719 * If the BIOS saved a valid signature, then fill in
17720 * the BIOS code segment base address.
17722 if (boardp->bios_signature == 0x55AA) {
17724 * Convert x86 realmode code segment to a linear
17725 * address by shifting left 4.
17727 shost->base = ((ulong)boardp->bios_codeseg << 4);
17728 } else {
17729 shost->base = 0;
17734 * Register Board Resources - I/O Port, DMA, IRQ
17737 /* Register DMA Channel for Narrow boards. */
17738 shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
17739 #ifdef CONFIG_ISA
17740 if (ASC_NARROW_BOARD(boardp)) {
17741 /* Register DMA channel for ISA bus. */
17742 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
17743 shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
17744 ret = request_dma(shost->dma_channel, "advansys");
17745 if (ret) {
17746 ASC_PRINT3
17747 ("advansys_board_found: board %d: request_dma() %d failed %d\n",
17748 boardp->id, shost->dma_channel, ret);
17749 goto err_free_proc;
17751 AscEnableIsaDma(shost->dma_channel);
17754 #endif /* CONFIG_ISA */
17756 /* Register IRQ Number. */
17757 ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq);
17759 ret = request_irq(shost->irq, advansys_interrupt, share_irq,
17760 "advansys", shost);
17762 if (ret) {
17763 if (ret == -EBUSY) {
17764 ASC_PRINT2
17765 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
17766 boardp->id, shost->irq);
17767 } else if (ret == -EINVAL) {
17768 ASC_PRINT2
17769 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
17770 boardp->id, shost->irq);
17771 } else {
17772 ASC_PRINT3
17773 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
17774 boardp->id, shost->irq, ret);
17776 goto err_free_dma;
17780 * Initialize board RISC chip and enable interrupts.
17782 if (ASC_NARROW_BOARD(boardp)) {
17783 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
17784 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
17785 err_code = asc_dvc_varp->err_code;
17787 if (warn_code || err_code) {
17788 ASC_PRINT4
17789 ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
17790 boardp->id,
17791 asc_dvc_varp->init_state, warn_code, err_code);
17793 } else {
17794 err_code = advansys_wide_init_chip(boardp, adv_dvc_varp);
17797 if (err_code != 0)
17798 goto err_free_wide_mem;
17800 ASC_DBG_PRT_SCSI_HOST(2, shost);
17802 ret = scsi_add_host(shost, dev);
17803 if (ret)
17804 goto err_free_wide_mem;
17806 scsi_scan_host(shost);
17807 return shost;
17809 err_free_wide_mem:
17810 advansys_wide_free_mem(boardp);
17811 free_irq(shost->irq, shost);
17812 err_free_dma:
17813 if (shost->dma_channel != NO_ISA_DMA)
17814 free_dma(shost->dma_channel);
17815 err_free_proc:
17816 kfree(boardp->prtbuf);
17817 err_unmap:
17818 if (boardp->ioremap_addr)
17819 iounmap(boardp->ioremap_addr);
17820 err_shost:
17821 scsi_host_put(shost);
17822 return NULL;
17826 * advansys_release()
17828 * Release resources allocated for a single AdvanSys adapter.
17830 static int advansys_release(struct Scsi_Host *shost)
17832 asc_board_t *boardp;
17834 ASC_DBG(1, "advansys_release: begin\n");
17835 scsi_remove_host(shost);
17836 boardp = ASC_BOARDP(shost);
17837 free_irq(shost->irq, shost);
17838 if (shost->dma_channel != NO_ISA_DMA) {
17839 ASC_DBG(1, "advansys_release: free_dma()\n");
17840 free_dma(shost->dma_channel);
17842 if (ASC_WIDE_BOARD(boardp)) {
17843 iounmap(boardp->ioremap_addr);
17844 advansys_wide_free_mem(boardp);
17846 kfree(boardp->prtbuf);
17847 scsi_host_put(shost);
17848 ASC_DBG(1, "advansys_release: end\n");
17849 return 0;
17852 static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
17853 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
17854 0x0210, 0x0230, 0x0250, 0x0330
17857 static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
17859 PortAddr iop_base = _asc_def_iop_base[id];
17860 struct Scsi_Host *shost;
17862 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
17863 ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n",
17864 iop_base);
17865 return -ENODEV;
17867 ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base);
17868 if (!AscFindSignature(iop_base))
17869 goto nodev;
17870 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
17871 goto nodev;
17873 shost = advansys_board_found(iop_base, dev, ASC_IS_ISA);
17874 if (!shost)
17875 goto nodev;
17877 dev_set_drvdata(dev, shost);
17878 return 0;
17880 nodev:
17881 release_region(iop_base, ASC_IOADR_GAP);
17882 return -ENODEV;
17885 static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
17887 int ioport = _asc_def_iop_base[id];
17888 advansys_release(dev_get_drvdata(dev));
17889 release_region(ioport, ASC_IOADR_GAP);
17890 return 0;
17893 static struct isa_driver advansys_isa_driver = {
17894 .probe = advansys_isa_probe,
17895 .remove = __devexit_p(advansys_isa_remove),
17896 .driver = {
17897 .owner = THIS_MODULE,
17898 .name = "advansys",
17902 static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
17904 PortAddr iop_base = _asc_def_iop_base[id];
17905 struct Scsi_Host *shost;
17907 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
17908 ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n",
17909 iop_base);
17910 return -ENODEV;
17912 ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base);
17913 if (!AscFindSignature(iop_base))
17914 goto nodev;
17916 * I don't think this condition can actually happen, but the old
17917 * driver did it, and the chances of finding a VLB setup in 2007
17918 * to do testing with is slight to none.
17920 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
17921 goto nodev;
17923 shost = advansys_board_found(iop_base, dev, ASC_IS_VL);
17924 if (!shost)
17925 goto nodev;
17927 dev_set_drvdata(dev, shost);
17928 return 0;
17930 nodev:
17931 release_region(iop_base, ASC_IOADR_GAP);
17932 return -ENODEV;
17935 static struct isa_driver advansys_vlb_driver = {
17936 .probe = advansys_vlb_probe,
17937 .remove = __devexit_p(advansys_isa_remove),
17938 .driver = {
17939 .owner = THIS_MODULE,
17940 .name = "advansys",
17944 static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
17945 { "ABP7401" },
17946 { "ABP7501" },
17947 { "" }
17950 MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
17953 * EISA is a little more tricky than PCI; each EISA device may have two
17954 * channels, and this driver is written to make each channel its own Scsi_Host
17956 struct eisa_scsi_data {
17957 struct Scsi_Host *host[2];
17960 static int __devinit advansys_eisa_probe(struct device *dev)
17962 int i, ioport;
17963 int err;
17964 struct eisa_device *edev = to_eisa_device(dev);
17965 struct eisa_scsi_data *data;
17967 err = -ENOMEM;
17968 data = kzalloc(sizeof(*data), GFP_KERNEL);
17969 if (!data)
17970 goto fail;
17971 ioport = edev->base_addr + 0xc30;
17973 err = -ENODEV;
17974 for (i = 0; i < 2; i++, ioport += 0x20) {
17975 if (!request_region(ioport, ASC_IOADR_GAP, "advansys")) {
17976 printk(KERN_WARNING "Region %x-%x busy\n", ioport,
17977 ioport + ASC_IOADR_GAP - 1);
17978 continue;
17980 if (!AscFindSignature(ioport)) {
17981 release_region(ioport, ASC_IOADR_GAP);
17982 continue;
17986 * I don't know why we need to do this for EISA chips, but
17987 * not for any others. It looks to be equivalent to
17988 * AscGetChipCfgMsw, but I may have overlooked something,
17989 * so I'm not converting it until I get an EISA board to
17990 * test with.
17992 inw(ioport + 4);
17993 data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA);
17994 if (data->host[i]) {
17995 err = 0;
17996 } else {
17997 release_region(ioport, ASC_IOADR_GAP);
18001 if (err) {
18002 kfree(data);
18003 } else {
18004 dev_set_drvdata(dev, data);
18007 fail:
18008 return err;
18011 static __devexit int advansys_eisa_remove(struct device *dev)
18013 int i;
18014 struct eisa_scsi_data *data = dev_get_drvdata(dev);
18016 for (i = 0; i < 2; i++) {
18017 int ioport;
18018 struct Scsi_Host *shost = data->host[i];
18019 if (!shost)
18020 continue;
18021 ioport = shost->io_port;
18022 advansys_release(shost);
18023 release_region(ioport, ASC_IOADR_GAP);
18026 kfree(data);
18027 return 0;
18030 static struct eisa_driver advansys_eisa_driver = {
18031 .id_table = advansys_eisa_table,
18032 .driver = {
18033 .name = "advansys",
18034 .probe = advansys_eisa_probe,
18035 .remove = __devexit_p(advansys_eisa_remove),
18039 /* PCI Devices supported by this driver */
18040 static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
18041 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
18042 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18043 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
18044 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18045 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
18046 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18047 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
18048 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18049 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
18050 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18051 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
18052 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18056 MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
18058 static void __devinit advansys_set_latency(struct pci_dev *pdev)
18060 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
18061 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
18062 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
18063 } else {
18064 u8 latency;
18065 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
18066 if (latency < 0x20)
18067 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
18071 static int __devinit
18072 advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
18074 int err, ioport;
18075 struct Scsi_Host *shost;
18077 err = pci_enable_device(pdev);
18078 if (err)
18079 goto fail;
18080 err = pci_request_regions(pdev, "advansys");
18081 if (err)
18082 goto disable_device;
18083 pci_set_master(pdev);
18084 advansys_set_latency(pdev);
18086 if (pci_resource_len(pdev, 0) == 0)
18087 goto nodev;
18089 ioport = pci_resource_start(pdev, 0);
18090 shost = advansys_board_found(ioport, &pdev->dev, ASC_IS_PCI);
18092 if (!shost)
18093 goto nodev;
18095 pci_set_drvdata(pdev, shost);
18096 return 0;
18098 nodev:
18099 err = -ENODEV;
18100 pci_release_regions(pdev);
18101 disable_device:
18102 pci_disable_device(pdev);
18103 fail:
18104 return err;
18107 static void __devexit advansys_pci_remove(struct pci_dev *pdev)
18109 advansys_release(pci_get_drvdata(pdev));
18110 pci_release_regions(pdev);
18111 pci_disable_device(pdev);
18114 static struct pci_driver advansys_pci_driver = {
18115 .name = "advansys",
18116 .id_table = advansys_pci_tbl,
18117 .probe = advansys_pci_probe,
18118 .remove = __devexit_p(advansys_pci_remove),
18121 static int __init advansys_init(void)
18123 int error;
18125 error = isa_register_driver(&advansys_isa_driver,
18126 ASC_IOADR_TABLE_MAX_IX);
18127 if (error)
18128 goto fail;
18130 error = isa_register_driver(&advansys_vlb_driver,
18131 ASC_IOADR_TABLE_MAX_IX);
18132 if (error)
18133 goto unregister_isa;
18135 error = eisa_driver_register(&advansys_eisa_driver);
18136 if (error)
18137 goto unregister_vlb;
18139 error = pci_register_driver(&advansys_pci_driver);
18140 if (error)
18141 goto unregister_eisa;
18143 return 0;
18145 unregister_eisa:
18146 eisa_driver_unregister(&advansys_eisa_driver);
18147 unregister_vlb:
18148 isa_unregister_driver(&advansys_vlb_driver);
18149 unregister_isa:
18150 isa_unregister_driver(&advansys_isa_driver);
18151 fail:
18152 return error;
18155 static void __exit advansys_exit(void)
18157 pci_unregister_driver(&advansys_pci_driver);
18158 eisa_driver_unregister(&advansys_eisa_driver);
18159 isa_unregister_driver(&advansys_vlb_driver);
18160 isa_unregister_driver(&advansys_isa_driver);
18163 module_init(advansys_init);
18164 module_exit(advansys_exit);
18166 MODULE_LICENSE("GPL");