[SCSI] aic79xx, aic7xxx: Fix incorrect width setting
[linux-2.6-block.git] / drivers / scsi / advansys.c
CommitLineData
1da177e4
LT
1#define ASC_VERSION "3.3K" /* AdvanSys Driver Version */
2
3/*
4 * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
5 *
6 * Copyright (c) 1995-2000 Advanced System Products, Inc.
7 * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
8 * All Rights Reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that redistributions of source
12 * code retain the above copyright notice and this comment without
13 * modification.
14 *
15 * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
16 * changed its name to ConnectCom Solutions, Inc.
17 *
18 */
19
20/*
21
22 Documentation for the AdvanSys Driver
23
24 A. Linux Kernels Supported by this Driver
25 B. Adapters Supported by this Driver
26 C. Linux source files modified by AdvanSys Driver
27 D. Source Comments
28 E. Driver Compile Time Options and Debugging
29 F. Driver LILO Option
30 G. Tests to run before releasing new driver
31 H. Release History
32 I. Known Problems/Fix List
33 J. Credits (Chronological Order)
34
35 A. Linux Kernels Supported by this Driver
36
37 This driver has been tested in the following Linux kernels: v2.2.18
38 v2.4.0. The driver is supported on v2.2 and v2.4 kernels and on x86,
39 alpha, and PowerPC platforms.
40
41 B. Adapters Supported by this Driver
42
43 AdvanSys (Advanced System Products, Inc.) manufactures the following
44 RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow
45 (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI
46 buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit
47 transfer) SCSI Host Adapters for the PCI bus.
48
49 The CDB counts below indicate the number of SCSI CDB (Command
50 Descriptor Block) requests that can be stored in the RISC chip
51 cache and board LRAM. A CDB is a single SCSI command. The driver
52 detect routine will display the number of CDBs available for each
53 adapter detected. The number of CDBs used by the driver can be
54 lowered in the BIOS by changing the 'Host Queue Size' adapter setting.
55
56 Laptop Products:
57 ABP-480 - Bus-Master CardBus (16 CDB) (2.4 kernel and greater)
58
59 Connectivity Products:
60 ABP510/5150 - Bus-Master ISA (240 CDB)
61 ABP5140 - Bus-Master ISA PnP (16 CDB)
62 ABP5142 - Bus-Master ISA PnP with floppy (16 CDB)
63 ABP902/3902 - Bus-Master PCI (16 CDB)
64 ABP3905 - Bus-Master PCI (16 CDB)
65 ABP915 - Bus-Master PCI (16 CDB)
66 ABP920 - Bus-Master PCI (16 CDB)
67 ABP3922 - Bus-Master PCI (16 CDB)
68 ABP3925 - Bus-Master PCI (16 CDB)
69 ABP930 - Bus-Master PCI (16 CDB)
70 ABP930U - Bus-Master PCI Ultra (16 CDB)
71 ABP930UA - Bus-Master PCI Ultra (16 CDB)
72 ABP960 - Bus-Master PCI MAC/PC (16 CDB)
73 ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
74
75 Single Channel Products:
76 ABP542 - Bus-Master ISA with floppy (240 CDB)
77 ABP742 - Bus-Master EISA (240 CDB)
78 ABP842 - Bus-Master VL (240 CDB)
79 ABP940 - Bus-Master PCI (240 CDB)
80 ABP940U - Bus-Master PCI Ultra (240 CDB)
81 ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB)
82 ABP970 - Bus-Master PCI MAC/PC (240 CDB)
83 ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
84 ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB)
85 ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB)
86 ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB)
87 ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB)
88
89 Multi-Channel Products:
90 ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
91 ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
92 ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
93 ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel)
94 ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
95 ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
96 ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.)
97 ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB)
98 ABP3950U3W - Bus-Master PCI Dual LVD2/Ultra3-Wide (253 CDB)
99
100 C. Linux source files modified by AdvanSys Driver
101
102 This section for historical purposes documents the changes
103 originally made to the Linux kernel source to add the advansys
104 driver. As Linux has changed some of these files have also
105 been modified.
106
107 1. linux/arch/i386/config.in:
108
109 bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
110
111 2. linux/drivers/scsi/hosts.c:
112
113 #ifdef CONFIG_SCSI_ADVANSYS
114 #include "advansys.h"
115 #endif
116
d0be4a7d 117 and after "static struct scsi_host_template builtin_scsi_hosts[] =":
1da177e4
LT
118
119 #ifdef CONFIG_SCSI_ADVANSYS
120 ADVANSYS,
121 #endif
122
123 3. linux/drivers/scsi/Makefile:
124
125 ifdef CONFIG_SCSI_ADVANSYS
126 SCSI_SRCS := $(SCSI_SRCS) advansys.c
127 SCSI_OBJS := $(SCSI_OBJS) advansys.o
128 else
129 SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
130 endif
131
132 4. linux/init/main.c:
133
134 extern void advansys_setup(char *str, int *ints);
135
136 and add the following lines to the bootsetups[] array.
137
138 #ifdef CONFIG_SCSI_ADVANSYS
139 { "advansys=", advansys_setup },
140 #endif
141
142 D. Source Comments
143
144 1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
145
146 2. This driver should be maintained in multiple files. But to make
147 it easier to include with Linux and to follow Linux conventions,
148 the whole driver is maintained in the source files advansys.h and
149 advansys.c. In this file logical sections of the driver begin with
150 a comment that contains '---'. The following are the logical sections
151 of the driver below.
152
153 --- Linux Version
154 --- Linux Include File
155 --- Driver Options
156 --- Debugging Header
157 --- Asc Library Constants and Macros
158 --- Adv Library Constants and Macros
159 --- Driver Constants and Macros
160 --- Driver Structures
161 --- Driver Data
162 --- Driver Function Prototypes
d0be4a7d 163 --- Linux 'struct scsi_host_template' and advansys_setup() Functions
1da177e4
LT
164 --- Loadable Driver Support
165 --- Miscellaneous Driver Functions
166 --- Functions Required by the Asc Library
167 --- Functions Required by the Adv Library
168 --- Tracing and Debugging Functions
169 --- Asc Library Functions
170 --- Adv Library Functions
171
172 3. The string 'XXX' is used to flag code that needs to be re-written
173 or that contains a problem that needs to be addressed.
174
175 4. I have stripped comments from and reformatted the source for the
176 Asc Library and Adv Library to reduce the size of this file. This
177 source can be found under the following headings. The Asc Library
178 is used to support Narrow Boards. The Adv Library is used to
179 support Wide Boards.
180
181 --- Asc Library Constants and Macros
182 --- Adv Library Constants and Macros
183 --- Asc Library Functions
184 --- Adv Library Functions
185
186 E. Driver Compile Time Options and Debugging
187
188 In this source file the following constants can be defined. They are
189 defined in the source below. Both of these options are enabled by
190 default.
191
192 1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled)
193
194 Enabling this option adds assertion logic statements to the
195 driver. If an assertion fails a message will be displayed to
196 the console, but the system will continue to operate. Any
197 assertions encountered should be reported to the person
198 responsible for the driver. Assertion statements may proactively
199 detect problems with the driver and facilitate fixing these
200 problems. Enabling assertions will add a small overhead to the
201 execution of the driver.
202
203 2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled)
204
205 Enabling this option adds tracing functions to the driver and
206 the ability to set a driver tracing level at boot time. This
207 option will also export symbols not required outside the driver to
208 the kernel name space. This option is very useful for debugging
209 the driver, but it will add to the size of the driver execution
210 image and add overhead to the execution of the driver.
211
212 The amount of debugging output can be controlled with the global
213 variable 'asc_dbglvl'. The higher the number the more output. By
214 default the debug level is 0.
215
216 If the driver is loaded at boot time and the LILO Driver Option
217 is included in the system, the debug level can be changed by
218 specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
219 first three hex digits of the pseudo I/O Port must be set to
220 'deb' and the fourth hex digit specifies the debug level: 0 - F.
221 The following command line will look for an adapter at 0x330
222 and set the debug level to 2.
223
224 linux advansys=0x330,0,0,0,0xdeb2
225
226 If the driver is built as a loadable module this variable can be
227 defined when the driver is loaded. The following insmod command
228 will set the debug level to one.
229
230 insmod advansys.o asc_dbglvl=1
231
232 Debugging Message Levels:
233 0: Errors Only
234 1: High-Level Tracing
235 2-N: Verbose Tracing
236
237 To enable debug output to console, please make sure that:
238
239 a. System and kernel logging is enabled (syslogd, klogd running).
240 b. Kernel messages are routed to console output. Check
241 /etc/syslog.conf for an entry similar to this:
242
243 kern.* /dev/console
244
245 c. klogd is started with the appropriate -c parameter
246 (e.g. klogd -c 8)
247
248 This will cause printk() messages to be be displayed on the
249 current console. Refer to the klogd(8) and syslogd(8) man pages
250 for details.
251
252 Alternatively you can enable printk() to console with this
253 program. However, this is not the 'official' way to do this.
254 Debug output is logged in /var/log/messages.
255
256 main()
257 {
258 syscall(103, 7, 0, 0);
259 }
260
261 Increasing LOG_BUF_LEN in kernel/printk.c to something like
262 40960 allows more debug messages to be buffered in the kernel
263 and written to the console or log file.
264
265 3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0)
266
267 Enabling this option adds statistics collection and display
268 through /proc to the driver. The information is useful for
269 monitoring driver and device performance. It will add to the
270 size of the driver execution image and add minor overhead to
271 the execution of the driver.
272
273 Statistics are maintained on a per adapter basis. Driver entry
274 point call counts and transfer size counts are maintained.
275 Statistics are only available for kernels greater than or equal
276 to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured.
277
278 AdvanSys SCSI adapter files have the following path name format:
279
280 /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
281
282 This information can be displayed with cat. For example:
283
284 cat /proc/scsi/advansys/0
285
286 When ADVANSYS_STATS is not defined the AdvanSys /proc files only
287 contain adapter and device configuration information.
288
289 F. Driver LILO Option
290
291 If init/main.c is modified as described in the 'Directions for Adding
292 the AdvanSys Driver to Linux' section (B.4.) above, the driver will
293 recognize the 'advansys' LILO command line and /etc/lilo.conf option.
294 This option can be used to either disable I/O port scanning or to limit
295 scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
296 PCI boards will still be searched for and detected. This option only
297 affects searching for ISA and VL boards.
298
299 Examples:
300 1. Eliminate I/O port scanning:
301 boot: linux advansys=
302 or
303 boot: linux advansys=0x0
304 2. Limit I/O port scanning to one I/O port:
305 boot: linux advansys=0x110
306 3. Limit I/O port scanning to four I/O ports:
307 boot: linux advansys=0x110,0x210,0x230,0x330
308
309 For a loadable module the same effect can be achieved by setting
310 the 'asc_iopflag' variable and 'asc_ioport' array when loading
311 the driver, e.g.
312
313 insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
314
315 If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1)
316 I/O Port may be added to specify the driver debug level. Refer to
317 the 'Driver Compile Time Options and Debugging' section above for
318 more information.
319
320 G. Tests to run before releasing new driver
321
322 1. In the supported kernels verify there are no warning or compile
323 errors when the kernel is built as both a driver and as a module
324 and with the following options:
325
326 ADVANSYS_DEBUG - enabled and disabled
327 CONFIG_SMP - enabled and disabled
328 CONFIG_PROC_FS - enabled and disabled
329
330 2. Run tests on an x86, alpha, and PowerPC with at least one narrow
331 card and one wide card attached to a hard disk and CD-ROM drive:
332 fdisk, mkfs, fsck, bonnie, copy/compare test from the
333 CD-ROM to the hard drive.
334
335 H. Release History
336
337 BETA-1.0 (12/23/95):
338 First Release
339
340 BETA-1.1 (12/28/95):
341 1. Prevent advansys_detect() from being called twice.
342 2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
343
344 1.2 (1/12/96):
345 1. Prevent re-entrancy in the interrupt handler which
346 resulted in the driver hanging Linux.
347 2. Fix problem that prevented ABP-940 cards from being
348 recognized on some PCI motherboards.
349 3. Add support for the ABP-5140 PnP ISA card.
350 4. Fix check condition return status.
351 5. Add conditionally compiled code for Linux v1.3.X.
352
353 1.3 (2/23/96):
354 1. Fix problem in advansys_biosparam() that resulted in the
355 wrong drive geometry being returned for drives > 1GB with
356 extended translation enabled.
357 2. Add additional tracing during device initialization.
358 3. Change code that only applies to ISA PnP adapter.
359 4. Eliminate 'make dep' warning.
360 5. Try to fix problem with handling resets by increasing their
361 timeout value.
362
363 1.4 (5/8/96):
364 1. Change definitions to eliminate conflicts with other subsystems.
365 2. Add versioning code for the shared interrupt changes.
366 3. Eliminate problem in asc_rmqueue() with iterating after removing
367 a request.
368 4. Remove reset request loop problem from the "Known Problems or
369 Issues" section. This problem was isolated and fixed in the
370 mid-level SCSI driver.
371
372 1.5 (8/8/96):
373 1. Add support for ABP-940U (PCI Ultra) adapter.
1d6f359a 374 2. Add support for IRQ sharing by setting the IRQF_SHARED flag for
1da177e4
LT
375 request_irq and supplying a dev_id pointer to both request_irq()
376 and free_irq().
377 3. In AscSearchIOPortAddr11() restore a call to check_region() which
378 should be used before I/O port probing.
379 4. Fix bug in asc_prt_hex() which resulted in the displaying
380 the wrong data.
381 5. Incorporate miscellaneous Asc Library bug fixes and new microcode.
382 6. Change driver versioning to be specific to each Linux sub-level.
383 7. Change statistics gathering to be per adapter instead of global
384 to the driver.
385 8. Add more information and statistics to the adapter /proc file:
386 /proc/scsi/advansys[0...].
387 9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list.
388 This problem has been addressed with the SCSI mid-level changes
389 made in v1.3.89. The advansys_select_queue_depths() function
390 was added for the v1.3.89 changes.
391
392 1.6 (9/10/96):
393 1. Incorporate miscellaneous Asc Library bug fixes and new microcode.
394
395 1.7 (9/25/96):
396 1. Enable clustering and optimize the setting of the maximum number
397 of scatter gather elements for any particular board. Clustering
398 increases CPU utilization, but results in a relatively larger
399 increase in I/O throughput.
400 2. Improve the performance of the request queuing functions by
401 adding a last pointer to the queue structure.
402 3. Correct problems with reset and abort request handling that
403 could have hung or crashed Linux.
404 4. Add more information to the adapter /proc file:
405 /proc/scsi/advansys[0...].
406 5. Remove the request timeout issue form the driver issues list.
407 6. Miscellaneous documentation additions and changes.
408
409 1.8 (10/4/96):
410 1. Make changes to handle the new v2.1.0 kernel memory mapping
411 in which a kernel virtual address may not be equivalent to its
412 bus or DMA memory address.
413 2. Change abort and reset request handling to make it yet even
414 more robust.
415 3. Try to mitigate request starvation by sending ordered requests
416 to heavily loaded, tag queuing enabled devices.
417 4. Maintain statistics on request response time.
418 5. Add request response time statistics and other information to
419 the adapter /proc file: /proc/scsi/advansys[0...].
420
421 1.9 (10/21/96):
422 1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to
423 make use of mid-level SCSI driver device queue depth flow
424 control mechanism. This will eliminate aborts caused by a
425 device being unable to keep up with requests and eliminate
426 repeat busy or QUEUE FULL status returned by a device.
427 2. Incorporate miscellaneous Asc Library bug fixes.
428 3. To allow the driver to work in kernels with broken module
429 support set 'cmd_per_lun' if the driver is compiled as a
430 module. This change affects kernels v1.3.89 to present.
431 4. Remove PCI BIOS address from the driver banner. The PCI BIOS
432 is relocated by the motherboard BIOS and its new address can
433 not be determined by the driver.
434 5. Add mid-level SCSI queue depth information to the adapter
435 /proc file: /proc/scsi/advansys[0...].
436
437 2.0 (11/14/96):
438 1. Change allocation of global structures used for device
439 initialization to guarantee they are in DMA-able memory.
440 Previously when the driver was loaded as a module these
441 structures might not have been in DMA-able memory, causing
442 device initialization to fail.
443
444 2.1 (12/30/96):
445 1. In advansys_reset(), if the request is a synchronous reset
446 request, even if the request serial number has changed, then
447 complete the request.
448 2. Add Asc Library bug fixes including new microcode.
449 3. Clear inquiry buffer before using it.
450 4. Correct ifdef typo.
451
452 2.2 (1/15/97):
453 1. Add Asc Library bug fixes including new microcode.
454 2. Add synchronous data transfer rate information to the
455 adapter /proc file: /proc/scsi/advansys[0...].
456 3. Change ADVANSYS_DEBUG to be disabled by default. This
457 will reduce the size of the driver image, eliminate execution
458 overhead, and remove unneeded symbols from the kernel symbol
459 space that were previously added by the driver.
460 4. Add new compile-time option ADVANSYS_ASSERT for assertion
461 code that used to be defined within ADVANSYS_DEBUG. This
462 option is enabled by default.
463
464 2.8 (5/26/97):
465 1. Change version number to 2.8 to synchronize the Linux driver
466 version numbering with other AdvanSys drivers.
467 2. Reformat source files without tabs to present the same view
468 of the file to everyone regardless of the editor tab setting
469 being used.
470 3. Add Asc Library bug fixes.
471
472 3.1A (1/8/98):
473 1. Change version number to 3.1 to indicate that support for
474 Ultra-Wide adapters (ABP-940UW) is included in this release.
475 2. Add Asc Library (Narrow Board) bug fixes.
476 3. Report an underrun condition with the host status byte set
477 to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which
478 causes the underrun condition to be ignored. When Linux defines
479 its own DID_UNDERRUN the constant defined in this file can be
480 removed.
481 4. Add patch to AscWaitTixISRDone().
482 5. Add support for up to 16 different AdvanSys host adapter SCSI
483 channels in one system. This allows four cards with four channels
484 to be used in one system.
485
486 3.1B (1/9/98):
487 1. Handle that PCI register base addresses are not always page
488 aligned even though ioremap() requires that the address argument
489 be page aligned.
490
491 3.1C (1/10/98):
492 1. Update latest BIOS version checked for from the /proc file.
493 2. Don't set microcode SDTR variable at initialization. Instead
494 wait until device capabilities have been detected from an Inquiry
495 command.
496
497 3.1D (1/21/98):
498 1. Improve performance when the driver is compiled as module by
499 allowing up to 64 scatter-gather elements instead of 8.
500
501 3.1E (5/1/98):
502 1. Set time delay in AscWaitTixISRDone() to 1000 ms.
503 2. Include SMP locking changes.
504 3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS
505 access functions.
506 4. Update board serial number printing.
1d6f359a 507 5. Try allocating an IRQ both with and without the IRQF_DISABLED
1da177e4 508 flag set to allow IRQ sharing with drivers that do not set
1d6f359a 509 the IRQF_DISABLED flag. Also display a more descriptive error
1da177e4
LT
510 message if request_irq() fails.
511 6. Update to latest Asc and Adv Libraries.
512
513 3.2A (7/22/99):
514 1. Update Adv Library to 4.16 which includes support for
515 the ASC38C0800 (Ultra2/LVD) IC.
516
517 3.2B (8/23/99):
518 1. Correct PCI compile time option for v2.1.93 and greater
519 kernels, advansys_info() string, and debug compile time
520 option.
521 2. Correct DvcSleepMilliSecond() for v2.1.0 and greater
522 kernels. This caused an LVD detection/BIST problem problem
523 among other things.
524 3. Sort PCI cards by PCI Bus, Slot, Function ascending order
525 to be consistent with the BIOS.
526 4. Update to Asc Library S121 and Adv Library 5.2.
527
528 3.2C (8/24/99):
529 1. Correct PCI card detection bug introduced in 3.2B that
530 prevented PCI cards from being detected in kernels older
531 than v2.1.93.
532
533 3.2D (8/26/99):
534 1. Correct /proc device synchronous speed information display.
535 Also when re-negotiation is pending for a target device
536 note this condition with an * and footnote.
537 2. Correct initialization problem with Ultra-Wide cards that
538 have a pre-3.2 BIOS. A microcode variable changed locations
539 in 3.2 and greater BIOSes which caused WDTR to be attempted
540 erroneously with drives that don't support WDTR.
541
542 3.2E (8/30/99):
543 1. Fix compile error caused by v2.3.13 PCI structure change.
544 2. Remove field from ASCEEP_CONFIG that resulted in an EEPROM
545 checksum error for ISA cards.
546 3. Remove ASC_QUEUE_FLOW_CONTROL conditional code. The mid-level
547 SCSI changes that it depended on were never included in Linux.
548
549 3.2F (9/3/99):
550 1. Handle new initial function code added in v2.3.16 for all
551 driver versions.
552
553 3.2G (9/8/99):
554 1. Fix PCI board detection in v2.3.13 and greater kernels.
555 2. Fix comiple errors in v2.3.X with debugging enabled.
556
557 3.2H (9/13/99):
558 1. Add 64-bit address, long support for Alpha and UltraSPARC.
559 The driver has been verified to work on an Alpha system.
560 2. Add partial byte order handling support for Power PC and
561 other big-endian platforms. This support has not yet been
562 completed or verified.
563 3. For wide boards replace block zeroing of request and
564 scatter-gather structures with individual field initialization
565 to improve performance.
566 4. Correct and clarify ROM BIOS version detection.
567
568 3.2I (10/8/99):
569 1. Update to Adv Library 5.4.
570 2. Add v2.3.19 underrun reporting to asc_isr_callback() and
571 adv_isr_callback(). Remove DID_UNDERRUN constant and other
572 no longer needed code that previously documented the lack
573 of underrun handling.
574
575 3.2J (10/14/99):
576 1. Eliminate compile errors for v2.0 and earlier kernels.
577
578 3.2K (11/15/99):
579 1. Correct debug compile error in asc_prt_adv_scsi_req_q().
580 2. Update Adv Library to 5.5.
581 3. Add ifdef handling for /proc changes added in v2.3.28.
582 4. Increase Wide board scatter-gather list maximum length to
583 255 when the driver is compiled into the kernel.
584
585 3.2L (11/18/99):
586 1. Fix bug in adv_get_sglist() that caused an assertion failure
587 at line 7475. The reqp->sgblkp pointer must be initialized
588 to NULL in adv_get_sglist().
589
590 3.2M (11/29/99):
591 1. Really fix bug in adv_get_sglist().
592 2. Incorporate v2.3.29 changes into driver.
593
594 3.2N (4/1/00):
595 1. Add CONFIG_ISA ifdef code.
596 2. Include advansys_interrupts_enabled name change patch.
597 3. For >= v2.3.28 use new SCSI error handling with new function
598 advansys_eh_bus_reset(). Don't include an abort function
599 because of base library limitations.
600 4. For >= v2.3.28 use per board lock instead of io_request_lock.
601 5. For >= v2.3.28 eliminate advansys_command() and
602 advansys_command_done().
603 6. Add some changes for PowerPC (Big Endian) support, but it isn't
604 working yet.
605 7. Fix "nonexistent resource free" problem that occurred on a module
606 unload for boards with an I/O space >= 255. The 'n_io_port' field
607 is only one byte and can not be used to hold an ioport length more
608 than 255.
609
610 3.3A (4/4/00):
611 1. Update to Adv Library 5.8.
612 2. For wide cards add support for CDBs up to 16 bytes.
613 3. Eliminate warnings when CONFIG_PROC_FS is not defined.
614
615 3.3B (5/1/00):
616 1. Support for PowerPC (Big Endian) wide cards. Narrow cards
617 still need work.
618 2. Change bitfields to shift and mask access for endian
619 portability.
620
621 3.3C (10/13/00):
622 1. Update for latest 2.4 kernel.
623 2. Test ABP-480 CardBus support in 2.4 kernel - works!
624 3. Update to Asc Library S123.
625 4. Update to Adv Library 5.12.
626
627 3.3D (11/22/00):
628 1. Update for latest 2.4 kernel.
629 2. Create patches for 2.2 and 2.4 kernels.
630
631 3.3E (1/9/01):
632 1. Now that 2.4 is released remove ifdef code for kernel versions
633 less than 2.2. The driver is now only supported in kernels 2.2,
634 2.4, and greater.
635 2. Add code to release and acquire the io_request_lock in
636 the driver entrypoint functions: advansys_detect and
637 advansys_queuecommand. In kernel 2.4 the SCSI mid-level driver
638 still holds the io_request_lock on entry to SCSI low-level drivers.
639 This was supposed to be removed before 2.4 was released but never
640 happened. When the mid-level SCSI driver is changed all references
641 to the io_request_lock should be removed from the driver.
642 3. Simplify error handling by removing advansys_abort(),
643 AscAbortSRB(), AscResetDevice(). SCSI bus reset requests are
644 now handled by resetting the SCSI bus and fully re-initializing
645 the chip. This simple method of error recovery has proven to work
646 most reliably after attempts at different methods. Also now only
647 support the "new" error handling method and remove the obsolete
648 error handling interface.
649 4. Fix debug build errors.
650
651 3.3F (1/24/01):
652 1. Merge with ConnectCom version from Andy Kellner which
653 updates Adv Library to 5.14.
654 2. Make PowerPC (Big Endian) work for narrow cards and
655 fix problems writing EEPROM for wide cards.
656 3. Remove interrupts_enabled assertion function.
657
658 3.3G (2/16/01):
659 1. Return an error from narrow boards if passed a 16 byte
660 CDB. The wide board can already handle 16 byte CDBs.
661
662 3.3GJ (4/15/02):
663 1. hacks for lk 2.5 series (D. Gilbert)
664
665 3.3GJD (10/14/02):
666 1. change select_queue_depths to slave_configure
667 2. make cmd_per_lun be sane again
668
669 3.3K [2004/06/24]:
670 1. continuing cleanup for lk 2.6 series
671 2. Fix problem in lk 2.6.7-bk2 that broke PCI wide cards
672 3. Fix problem that oopsed ISA cards
673
674 I. Known Problems/Fix List (XXX)
675
676 1. Need to add memory mapping workaround. Test the memory mapping.
677 If it doesn't work revert to I/O port access. Can a test be done
678 safely?
679 2. Handle an interrupt not working. Keep an interrupt counter in
680 the interrupt handler. In the timeout function if the interrupt
681 has not occurred then print a message and run in polled mode.
682 3. Allow bus type scanning order to be changed.
683 4. Need to add support for target mode commands, cf. CAM XPT.
684
685 J. Credits (Chronological Order)
686
687 Bob Frey <bfrey@turbolinux.com.cn> wrote the AdvanSys SCSI driver
688 and maintained it up to 3.3F. He continues to answer questions
689 and help maintain the driver.
690
691 Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and
692 basis for the Linux v1.3.X changes which were included in the
693 1.2 release.
694
695 Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug
696 in advansys_biosparam() which was fixed in the 1.3 release.
697
698 Erik Ratcliffe <erik@caldera.com> has done testing of the
699 AdvanSys driver in the Caldera releases.
700
701 Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to
702 AscWaitTixISRDone() which he found necessary to make the
703 driver work with a SCSI-1 disk.
704
705 Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide
706 support in the 3.1A driver.
707
708 Doug Gilbert <dgilbert@interlog.com> has made changes and
709 suggestions to improve the driver and done a lot of testing.
710
711 Ken Mort <ken@mort.net> reported a DEBUG compile bug fixed
712 in 3.2K.
713
714 Tom Rini <trini@kernel.crashing.org> provided the CONFIG_ISA
715 patch and helped with PowerPC wide and narrow board support.
716
717 Philip Blundell <philb@gnu.org> provided an
718 advansys_interrupts_enabled patch.
719
720 Dave Jones <dave@denial.force9.co.uk> reported the compiler
721 warnings generated when CONFIG_PROC_FS was not defined in
722 the 3.2M driver.
723
724 Jerry Quinn <jlquinn@us.ibm.com> fixed PowerPC support (endian
725 problems) for wide cards.
726
727 Bryan Henderson <bryanh@giraffe-data.com> helped debug narrow
728 card error handling.
729
730 Manuel Veloso <veloso@pobox.com> worked hard on PowerPC narrow
731 board support and fixed a bug in AscGetEEPConfig().
732
733 Arnaldo Carvalho de Melo <acme@conectiva.com.br> made
734 save_flags/restore_flags changes.
735
736 Andy Kellner <AKellner@connectcom.net> continues the Advansys SCSI
737 driver development for ConnectCom (Version > 3.3F).
738
739 K. ConnectCom (AdvanSys) Contact Information
740
741 Mail: ConnectCom Solutions, Inc.
742 1150 Ringwood Court
743 San Jose, CA 95131
744 Operator/Sales: 1-408-383-9400
745 FAX: 1-408-383-9612
746 Tech Support: 1-408-467-2930
747 Tech Support E-Mail: linux@connectcom.net
748 FTP Site: ftp.connectcom.net (login: anonymous)
749 Web Site: http://www.connectcom.net
750
751*/
752
753/*
754 * --- Linux Include Files
755 */
756
1da177e4
LT
757#include <linux/module.h>
758
759#if defined(CONFIG_X86) && !defined(CONFIG_ISA)
760#define CONFIG_ISA
761#endif /* CONFIG_X86 && !CONFIG_ISA */
762
763#include <linux/string.h>
764#include <linux/kernel.h>
765#include <linux/types.h>
766#include <linux/ioport.h>
767#include <linux/interrupt.h>
768#include <linux/delay.h>
769#include <linux/slab.h>
770#include <linux/mm.h>
771#include <linux/proc_fs.h>
772#include <linux/init.h>
773#include <linux/blkdev.h>
774#include <linux/stat.h>
775#include <linux/spinlock.h>
776#include <linux/dma-mapping.h>
777
778#include <asm/io.h>
779#include <asm/system.h>
780#include <asm/dma.h>
781
782/* FIXME: (by jejb@steeleye.com) This warning is present for two
783 * reasons:
784 *
785 * 1) This driver badly needs converting to the correct driver model
786 * probing API
787 *
788 * 2) Although all of the necessary command mapping places have the
789 * appropriate dma_map.. APIs, the driver still processes its internal
790 * queue using bus_to_virt() and virt_to_bus() which are illegal under
791 * the API. The entire queue processing structure will need to be
792 * altered to fix this.
793 */
794#warning this driver is still not properly converted to the DMA API
795
796#include <scsi/scsi_cmnd.h>
797#include <scsi/scsi_device.h>
798#include <scsi/scsi_tcq.h>
799#include <scsi/scsi.h>
800#include <scsi/scsi_host.h>
1da177e4
LT
801#ifdef CONFIG_PCI
802#include <linux/pci.h>
803#endif /* CONFIG_PCI */
804
805
806/*
807 * --- Driver Options
808 */
809
810/* Enable driver assertions. */
811#define ADVANSYS_ASSERT
812
813/* Enable driver /proc statistics. */
814#define ADVANSYS_STATS
815
816/* Enable driver tracing. */
817/* #define ADVANSYS_DEBUG */
818
819
820/*
821 * --- Debugging Header
822 */
823
824#ifdef ADVANSYS_DEBUG
825#define STATIC
826#else /* ADVANSYS_DEBUG */
827#define STATIC static
828#endif /* ADVANSYS_DEBUG */
829
830
831/*
832 * --- Asc Library Constants and Macros
833 */
834
835#define ASC_LIB_VERSION_MAJOR 1
836#define ASC_LIB_VERSION_MINOR 24
837#define ASC_LIB_SERIAL_NUMBER 123
838
839/*
840 * Portable Data Types
841 *
842 * Any instance where a 32-bit long or pointer type is assumed
843 * for precision or HW defined structures, the following define
844 * types must be used. In Linux the char, short, and int types
845 * are all consistent at 8, 16, and 32 bits respectively. Pointers
846 * and long types are 64 bits on Alpha and UltraSPARC.
847 */
848#define ASC_PADDR __u32 /* Physical/Bus address data type. */
849#define ASC_VADDR __u32 /* Virtual address data type. */
850#define ASC_DCNT __u32 /* Unsigned Data count type. */
851#define ASC_SDCNT __s32 /* Signed Data count type. */
852
853/*
854 * These macros are used to convert a virtual address to a
855 * 32-bit value. This currently can be used on Linux Alpha
856 * which uses 64-bit virtual address but a 32-bit bus address.
857 * This is likely to break in the future, but doing this now
858 * will give us time to change the HW and FW to handle 64-bit
859 * addresses.
860 */
861#define ASC_VADDR_TO_U32 virt_to_bus
862#define ASC_U32_TO_VADDR bus_to_virt
863
864typedef unsigned char uchar;
865
866#ifndef TRUE
867#define TRUE (1)
868#endif
869#ifndef FALSE
870#define FALSE (0)
871#endif
872
873#define EOF (-1)
874#define ERR (-1)
875#define UW_ERR (uint)(0xFFFF)
876#define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
877#define AscPCIConfigVendorIDRegister 0x0000
878#define AscPCIConfigDeviceIDRegister 0x0002
879#define AscPCIConfigCommandRegister 0x0004
880#define AscPCIConfigStatusRegister 0x0006
881#define AscPCIConfigRevisionIDRegister 0x0008
882#define AscPCIConfigCacheSize 0x000C
883#define AscPCIConfigLatencyTimer 0x000D
884#define AscPCIIOBaseRegister 0x0010
885#define AscPCICmdRegBits_IOMemBusMaster 0x0007
886#define ASC_PCI_ID2BUS(id) ((id) & 0xFF)
887#define ASC_PCI_ID2DEV(id) (((id) >> 11) & 0x1F)
888#define ASC_PCI_ID2FUNC(id) (((id) >> 8) & 0x7)
889#define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
1da177e4
LT
890#define ASC_PCI_REVISION_3150 0x02
891#define ASC_PCI_REVISION_3050 0x03
892
893#define ASC_DVCLIB_CALL_DONE (1)
894#define ASC_DVCLIB_CALL_FAILED (0)
895#define ASC_DVCLIB_CALL_ERROR (-1)
896
2672ea86
DJ
897#define PCI_VENDOR_ID_ASP 0x10cd
898#define PCI_DEVICE_ID_ASP_1200A 0x1100
899#define PCI_DEVICE_ID_ASP_ABP940 0x1200
900#define PCI_DEVICE_ID_ASP_ABP940U 0x1300
901#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
902#define PCI_DEVICE_ID_38C0800_REV1 0x2500
903#define PCI_DEVICE_ID_38C1600_REV1 0x2700
904
1da177e4
LT
905/*
906 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
907 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
908 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
909 * SRB structure.
910 */
911#define CC_VERY_LONG_SG_LIST 0
912#define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
913
914#define PortAddr unsigned short /* port address size */
915#define inp(port) inb(port)
916#define outp(port, byte) outb((byte), (port))
917
918#define inpw(port) inw(port)
919#define outpw(port, word) outw((word), (port))
920
921#define ASC_MAX_SG_QUEUE 7
922#define ASC_MAX_SG_LIST 255
923
924#define ASC_CS_TYPE unsigned short
925
926#define ASC_IS_ISA (0x0001)
927#define ASC_IS_ISAPNP (0x0081)
928#define ASC_IS_EISA (0x0002)
929#define ASC_IS_PCI (0x0004)
930#define ASC_IS_PCI_ULTRA (0x0104)
931#define ASC_IS_PCMCIA (0x0008)
932#define ASC_IS_MCA (0x0020)
933#define ASC_IS_VL (0x0040)
934#define ASC_ISA_PNP_PORT_ADDR (0x279)
935#define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
936#define ASC_IS_WIDESCSI_16 (0x0100)
937#define ASC_IS_WIDESCSI_32 (0x0200)
938#define ASC_IS_BIG_ENDIAN (0x8000)
939#define ASC_CHIP_MIN_VER_VL (0x01)
940#define ASC_CHIP_MAX_VER_VL (0x07)
941#define ASC_CHIP_MIN_VER_PCI (0x09)
942#define ASC_CHIP_MAX_VER_PCI (0x0F)
943#define ASC_CHIP_VER_PCI_BIT (0x08)
944#define ASC_CHIP_MIN_VER_ISA (0x11)
945#define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
946#define ASC_CHIP_MAX_VER_ISA (0x27)
947#define ASC_CHIP_VER_ISA_BIT (0x30)
948#define ASC_CHIP_VER_ISAPNP_BIT (0x20)
949#define ASC_CHIP_VER_ASYN_BUG (0x21)
950#define ASC_CHIP_VER_PCI 0x08
951#define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
952#define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
953#define ASC_CHIP_MIN_VER_EISA (0x41)
954#define ASC_CHIP_MAX_VER_EISA (0x47)
955#define ASC_CHIP_VER_EISA_BIT (0x40)
956#define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
957#define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER 0x21
958#define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER 0x0A
959#define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL)
960#define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
961#define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL)
962#define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
963#define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL)
964#define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
965#define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL)
966#define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL)
967
968#define ASC_SCSI_ID_BITS 3
969#define ASC_SCSI_TIX_TYPE uchar
970#define ASC_ALL_DEVICE_BIT_SET 0xFF
971#define ASC_SCSI_BIT_ID_TYPE uchar
972#define ASC_MAX_TID 7
973#define ASC_MAX_LUN 7
974#define ASC_SCSI_WIDTH_BIT_SET 0xFF
975#define ASC_MAX_SENSE_LEN 32
976#define ASC_MIN_SENSE_LEN 14
977#define ASC_MAX_CDB_LEN 12
978#define ASC_SCSI_RESET_HOLD_TIME_US 60
979
980#define ADV_INQ_CLOCKING_ST_ONLY 0x0
981#define ADV_INQ_CLOCKING_DT_ONLY 0x1
982#define ADV_INQ_CLOCKING_ST_AND_DT 0x3
983
984/*
985 * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
986 * and CmdDt (Command Support Data) field bit definitions.
987 */
988#define ADV_INQ_RTN_VPD_AND_CMDDT 0x3
989#define ADV_INQ_RTN_CMDDT_FOR_OP_CODE 0x2
990#define ADV_INQ_RTN_VPD_FOR_PG_CODE 0x1
991#define ADV_INQ_RTN_STD_INQUIRY_DATA 0x0
992
993#define ASC_SCSIDIR_NOCHK 0x00
994#define ASC_SCSIDIR_T2H 0x08
995#define ASC_SCSIDIR_H2T 0x10
996#define ASC_SCSIDIR_NODATA 0x18
997#define SCSI_ASC_NOMEDIA 0x3A
998#define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4))
999#define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F))
1000#define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13))
1001#define PUT_CDB1(x) ((uchar)((uint)(x) >> 8))
1002#define MS_CMD_DONE 0x00
1003#define MS_EXTEND 0x01
1004#define MS_SDTR_LEN 0x03
1005#define MS_SDTR_CODE 0x01
1006#define MS_WDTR_LEN 0x02
1007#define MS_WDTR_CODE 0x03
1008#define MS_MDP_LEN 0x05
1009#define MS_MDP_CODE 0x00
1010
1011/*
1012 * Inquiry data structure and bitfield macros
1013 *
1014 * Only quantities of more than 1 bit are shifted, since the others are
1015 * just tested for true or false. C bitfields aren't portable between big
1016 * and little-endian platforms so they are not used.
1017 */
1018
1019#define ASC_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f)
1020#define ASC_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5)
1021#define ASC_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f)
1022#define ASC_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80)
1023#define ASC_INQ_ANSI_VER(inq) ((inq)->ver & 0x07)
1024#define ASC_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3)
1025#define ASC_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6)
1026#define ASC_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f)
1027#define ASC_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40)
1028#define ASC_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80)
1029#define ASC_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01)
1030#define ASC_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02)
1031#define ASC_INQ_LINK_CMD(inq) ((inq)->flags & 0x08)
1032#define ASC_INQ_SYNC(inq) ((inq)->flags & 0x10)
1033#define ASC_INQ_WIDE16(inq) ((inq)->flags & 0x20)
1034#define ASC_INQ_WIDE32(inq) ((inq)->flags & 0x40)
1035#define ASC_INQ_REL_ADDR(inq) ((inq)->flags & 0x80)
1036#define ASC_INQ_INFO_UNIT(inq) ((inq)->info & 0x01)
1037#define ASC_INQ_QUICK_ARB(inq) ((inq)->info & 0x02)
1038#define ASC_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2)
1039
1040typedef struct {
1041 uchar periph;
1042 uchar devtype;
1043 uchar ver;
1044 uchar byte3;
1045 uchar add_len;
1046 uchar res1;
1047 uchar res2;
1048 uchar flags;
1049 uchar vendor_id[8];
1050 uchar product_id[16];
1051 uchar product_rev_level[4];
1052} ASC_SCSI_INQUIRY;
1053
1054#define ASC_SG_LIST_PER_Q 7
1055#define QS_FREE 0x00
1056#define QS_READY 0x01
1057#define QS_DISC1 0x02
1058#define QS_DISC2 0x04
1059#define QS_BUSY 0x08
1060#define QS_ABORTED 0x40
1061#define QS_DONE 0x80
1062#define QC_NO_CALLBACK 0x01
1063#define QC_SG_SWAP_QUEUE 0x02
1064#define QC_SG_HEAD 0x04
1065#define QC_DATA_IN 0x08
1066#define QC_DATA_OUT 0x10
1067#define QC_URGENT 0x20
1068#define QC_MSG_OUT 0x40
1069#define QC_REQ_SENSE 0x80
1070#define QCSG_SG_XFER_LIST 0x02
1071#define QCSG_SG_XFER_MORE 0x04
1072#define QCSG_SG_XFER_END 0x08
1073#define QD_IN_PROGRESS 0x00
1074#define QD_NO_ERROR 0x01
1075#define QD_ABORTED_BY_HOST 0x02
1076#define QD_WITH_ERROR 0x04
1077#define QD_INVALID_REQUEST 0x80
1078#define QD_INVALID_HOST_NUM 0x81
1079#define QD_INVALID_DEVICE 0x82
1080#define QD_ERR_INTERNAL 0xFF
1081#define QHSTA_NO_ERROR 0x00
1082#define QHSTA_M_SEL_TIMEOUT 0x11
1083#define QHSTA_M_DATA_OVER_RUN 0x12
1084#define QHSTA_M_DATA_UNDER_RUN 0x12
1085#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
1086#define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
1087#define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1088#define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
1089#define QHSTA_D_HOST_ABORT_FAILED 0x23
1090#define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
1091#define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1092#define QHSTA_D_ASPI_NO_BUF_POOL 0x26
1093#define QHSTA_M_WTM_TIMEOUT 0x41
1094#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
1095#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
1096#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1097#define QHSTA_M_TARGET_STATUS_BUSY 0x45
1098#define QHSTA_M_BAD_TAG_CODE 0x46
1099#define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
1100#define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1101#define QHSTA_D_LRAM_CMP_ERROR 0x81
1102#define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1103#define ASC_FLAG_SCSIQ_REQ 0x01
1104#define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
1105#define ASC_FLAG_BIOS_ASYNC_IO 0x04
1106#define ASC_FLAG_SRB_LINEAR_ADDR 0x08
1107#define ASC_FLAG_WIN16 0x10
1108#define ASC_FLAG_WIN32 0x20
1109#define ASC_FLAG_ISA_OVER_16MB 0x40
1110#define ASC_FLAG_DOS_VM_CALLBACK 0x80
1111#define ASC_TAG_FLAG_EXTRA_BYTES 0x10
1112#define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
1113#define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
1114#define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1115#define ASC_SCSIQ_CPY_BEG 4
1116#define ASC_SCSIQ_SGHD_CPY_BEG 2
1117#define ASC_SCSIQ_B_FWD 0
1118#define ASC_SCSIQ_B_BWD 1
1119#define ASC_SCSIQ_B_STATUS 2
1120#define ASC_SCSIQ_B_QNO 3
1121#define ASC_SCSIQ_B_CNTL 4
1122#define ASC_SCSIQ_B_SG_QUEUE_CNT 5
1123#define ASC_SCSIQ_D_DATA_ADDR 8
1124#define ASC_SCSIQ_D_DATA_CNT 12
1125#define ASC_SCSIQ_B_SENSE_LEN 20
1126#define ASC_SCSIQ_DONE_INFO_BEG 22
1127#define ASC_SCSIQ_D_SRBPTR 22
1128#define ASC_SCSIQ_B_TARGET_IX 26
1129#define ASC_SCSIQ_B_CDB_LEN 28
1130#define ASC_SCSIQ_B_TAG_CODE 29
1131#define ASC_SCSIQ_W_VM_ID 30
1132#define ASC_SCSIQ_DONE_STATUS 32
1133#define ASC_SCSIQ_HOST_STATUS 33
1134#define ASC_SCSIQ_SCSI_STATUS 34
1135#define ASC_SCSIQ_CDB_BEG 36
1136#define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1137#define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
1138#define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
1139#define ASC_SCSIQ_B_SG_WK_QP 49
1140#define ASC_SCSIQ_B_SG_WK_IX 50
1141#define ASC_SCSIQ_W_ALT_DC1 52
1142#define ASC_SCSIQ_B_LIST_CNT 6
1143#define ASC_SCSIQ_B_CUR_LIST_CNT 7
1144#define ASC_SGQ_B_SG_CNTL 4
1145#define ASC_SGQ_B_SG_HEAD_QP 5
1146#define ASC_SGQ_B_SG_LIST_CNT 6
1147#define ASC_SGQ_B_SG_CUR_LIST_CNT 7
1148#define ASC_SGQ_LIST_BEG 8
1149#define ASC_DEF_SCSI1_QNG 4
1150#define ASC_MAX_SCSI1_QNG 4
1151#define ASC_DEF_SCSI2_QNG 16
1152#define ASC_MAX_SCSI2_QNG 32
1153#define ASC_TAG_CODE_MASK 0x23
1154#define ASC_STOP_REQ_RISC_STOP 0x01
1155#define ASC_STOP_ACK_RISC_STOP 0x03
1156#define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
1157#define ASC_STOP_CLEAN_UP_DISC_Q 0x20
1158#define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1159#define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1160#define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1161#define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
1162#define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
1163#define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
1164#define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1165#define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
1166
1167typedef struct asc_scsiq_1 {
1168 uchar status;
1169 uchar q_no;
1170 uchar cntl;
1171 uchar sg_queue_cnt;
1172 uchar target_id;
1173 uchar target_lun;
1174 ASC_PADDR data_addr;
1175 ASC_DCNT data_cnt;
1176 ASC_PADDR sense_addr;
1177 uchar sense_len;
1178 uchar extra_bytes;
1179} ASC_SCSIQ_1;
1180
1181typedef struct asc_scsiq_2 {
1182 ASC_VADDR srb_ptr;
1183 uchar target_ix;
1184 uchar flag;
1185 uchar cdb_len;
1186 uchar tag_code;
1187 ushort vm_id;
1188} ASC_SCSIQ_2;
1189
1190typedef struct asc_scsiq_3 {
1191 uchar done_stat;
1192 uchar host_stat;
1193 uchar scsi_stat;
1194 uchar scsi_msg;
1195} ASC_SCSIQ_3;
1196
1197typedef struct asc_scsiq_4 {
1198 uchar cdb[ASC_MAX_CDB_LEN];
1199 uchar y_first_sg_list_qp;
1200 uchar y_working_sg_qp;
1201 uchar y_working_sg_ix;
1202 uchar y_res;
1203 ushort x_req_count;
1204 ushort x_reconnect_rtn;
1205 ASC_PADDR x_saved_data_addr;
1206 ASC_DCNT x_saved_data_cnt;
1207} ASC_SCSIQ_4;
1208
1209typedef struct asc_q_done_info {
1210 ASC_SCSIQ_2 d2;
1211 ASC_SCSIQ_3 d3;
1212 uchar q_status;
1213 uchar q_no;
1214 uchar cntl;
1215 uchar sense_len;
1216 uchar extra_bytes;
1217 uchar res;
1218 ASC_DCNT remain_bytes;
1219} ASC_QDONE_INFO;
1220
1221typedef struct asc_sg_list {
1222 ASC_PADDR addr;
1223 ASC_DCNT bytes;
1224} ASC_SG_LIST;
1225
1226typedef struct asc_sg_head {
1227 ushort entry_cnt;
1228 ushort queue_cnt;
1229 ushort entry_to_copy;
1230 ushort res;
1231 ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1232} ASC_SG_HEAD;
1233
1234#define ASC_MIN_SG_LIST 2
1235
1236typedef struct asc_min_sg_head {
1237 ushort entry_cnt;
1238 ushort queue_cnt;
1239 ushort entry_to_copy;
1240 ushort res;
1241 ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
1242} ASC_MIN_SG_HEAD;
1243
1244#define QCX_SORT (0x0001)
1245#define QCX_COALEASE (0x0002)
1246
1247typedef struct asc_scsi_q {
1248 ASC_SCSIQ_1 q1;
1249 ASC_SCSIQ_2 q2;
1250 uchar *cdbptr;
1251 ASC_SG_HEAD *sg_head;
1252 ushort remain_sg_entry_cnt;
1253 ushort next_sg_index;
1254} ASC_SCSI_Q;
1255
1256typedef struct asc_scsi_req_q {
1257 ASC_SCSIQ_1 r1;
1258 ASC_SCSIQ_2 r2;
1259 uchar *cdbptr;
1260 ASC_SG_HEAD *sg_head;
1261 uchar *sense_ptr;
1262 ASC_SCSIQ_3 r3;
1263 uchar cdb[ASC_MAX_CDB_LEN];
1264 uchar sense[ASC_MIN_SENSE_LEN];
1265} ASC_SCSI_REQ_Q;
1266
1267typedef struct asc_scsi_bios_req_q {
1268 ASC_SCSIQ_1 r1;
1269 ASC_SCSIQ_2 r2;
1270 uchar *cdbptr;
1271 ASC_SG_HEAD *sg_head;
1272 uchar *sense_ptr;
1273 ASC_SCSIQ_3 r3;
1274 uchar cdb[ASC_MAX_CDB_LEN];
1275 uchar sense[ASC_MIN_SENSE_LEN];
1276} ASC_SCSI_BIOS_REQ_Q;
1277
1278typedef struct asc_risc_q {
1279 uchar fwd;
1280 uchar bwd;
1281 ASC_SCSIQ_1 i1;
1282 ASC_SCSIQ_2 i2;
1283 ASC_SCSIQ_3 i3;
1284 ASC_SCSIQ_4 i4;
1285} ASC_RISC_Q;
1286
1287typedef struct asc_sg_list_q {
1288 uchar seq_no;
1289 uchar q_no;
1290 uchar cntl;
1291 uchar sg_head_qp;
1292 uchar sg_list_cnt;
1293 uchar sg_cur_list_cnt;
1294} ASC_SG_LIST_Q;
1295
1296typedef struct asc_risc_sg_list_q {
1297 uchar fwd;
1298 uchar bwd;
1299 ASC_SG_LIST_Q sg;
1300 ASC_SG_LIST sg_list[7];
1301} ASC_RISC_SG_LIST_Q;
1302
1303#define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL
1304#define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024
1305#define ASCQ_ERR_NO_ERROR 0
1306#define ASCQ_ERR_IO_NOT_FOUND 1
1307#define ASCQ_ERR_LOCAL_MEM 2
1308#define ASCQ_ERR_CHKSUM 3
1309#define ASCQ_ERR_START_CHIP 4
1310#define ASCQ_ERR_INT_TARGET_ID 5
1311#define ASCQ_ERR_INT_LOCAL_MEM 6
1312#define ASCQ_ERR_HALT_RISC 7
1313#define ASCQ_ERR_GET_ASPI_ENTRY 8
1314#define ASCQ_ERR_CLOSE_ASPI 9
1315#define ASCQ_ERR_HOST_INQUIRY 0x0A
1316#define ASCQ_ERR_SAVED_SRB_BAD 0x0B
1317#define ASCQ_ERR_QCNTL_SG_LIST 0x0C
1318#define ASCQ_ERR_Q_STATUS 0x0D
1319#define ASCQ_ERR_WR_SCSIQ 0x0E
1320#define ASCQ_ERR_PC_ADDR 0x0F
1321#define ASCQ_ERR_SYN_OFFSET 0x10
1322#define ASCQ_ERR_SYN_XFER_TIME 0x11
1323#define ASCQ_ERR_LOCK_DMA 0x12
1324#define ASCQ_ERR_UNLOCK_DMA 0x13
1325#define ASCQ_ERR_VDS_CHK_INSTALL 0x14
1326#define ASCQ_ERR_MICRO_CODE_HALT 0x15
1327#define ASCQ_ERR_SET_LRAM_ADDR 0x16
1328#define ASCQ_ERR_CUR_QNG 0x17
1329#define ASCQ_ERR_SG_Q_LINKS 0x18
1330#define ASCQ_ERR_SCSIQ_PTR 0x19
1331#define ASCQ_ERR_ISR_RE_ENTRY 0x1A
1332#define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
1333#define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
1334#define ASCQ_ERR_SG_LIST_ODD_ADDRESS 0x1D
1335#define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1336#define ASCQ_ERR_SCSIQ_NULL_PTR 0x1F
1337#define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR 0x20
1338#define ASCQ_ERR_GET_NUM_OF_FREE_Q 0x21
1339#define ASCQ_ERR_SEND_SCSI_Q 0x22
1340#define ASCQ_ERR_HOST_REQ_RISC_HALT 0x23
1341#define ASCQ_ERR_RESET_SDTR 0x24
1342
1343/*
1344 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
1345 */
1346#define ASC_WARN_NO_ERROR 0x0000
1347#define ASC_WARN_IO_PORT_ROTATE 0x0001
1348#define ASC_WARN_EEPROM_CHKSUM 0x0002
1349#define ASC_WARN_IRQ_MODIFIED 0x0004
1350#define ASC_WARN_AUTO_CONFIG 0x0008
1351#define ASC_WARN_CMD_QNG_CONFLICT 0x0010
1352#define ASC_WARN_EEPROM_RECOVER 0x0020
1353#define ASC_WARN_CFG_MSW_RECOVER 0x0040
1354#define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1355
1356/*
1357 * Error code values are set in ASC_DVC_VAR 'err_code'.
1358 */
1359#define ASC_IERR_WRITE_EEPROM 0x0001
1360#define ASC_IERR_MCODE_CHKSUM 0x0002
1361#define ASC_IERR_SET_PC_ADDR 0x0004
1362#define ASC_IERR_START_STOP_CHIP 0x0008
1363#define ASC_IERR_IRQ_NO 0x0010
1364#define ASC_IERR_SET_IRQ_NO 0x0020
1365#define ASC_IERR_CHIP_VERSION 0x0040
1366#define ASC_IERR_SET_SCSI_ID 0x0080
1367#define ASC_IERR_GET_PHY_ADDR 0x0100
1368#define ASC_IERR_BAD_SIGNATURE 0x0200
1369#define ASC_IERR_NO_BUS_TYPE 0x0400
1370#define ASC_IERR_SCAM 0x0800
1371#define ASC_IERR_SET_SDTR 0x1000
1372#define ASC_IERR_RW_LRAM 0x8000
1373
1374#define ASC_DEF_IRQ_NO 10
1375#define ASC_MAX_IRQ_NO 15
1376#define ASC_MIN_IRQ_NO 10
1377#define ASC_MIN_REMAIN_Q (0x02)
1378#define ASC_DEF_MAX_TOTAL_QNG (0xF0)
1379#define ASC_MIN_TAG_Q_PER_DVC (0x04)
1380#define ASC_DEF_TAG_Q_PER_DVC (0x04)
1381#define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q
1382#define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1383#define ASC_MAX_TOTAL_QNG 240
1384#define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1385#define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
1386#define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
1387#define ASC_MAX_INRAM_TAG_QNG 16
1388#define ASC_IOADR_TABLE_MAX_IX 11
1389#define ASC_IOADR_GAP 0x10
1390#define ASC_SEARCH_IOP_GAP 0x10
1391#define ASC_MIN_IOP_ADDR (PortAddr)0x0100
1392#define ASC_MAX_IOP_ADDR (PortAddr)0x3F0
1393#define ASC_IOADR_1 (PortAddr)0x0110
1394#define ASC_IOADR_2 (PortAddr)0x0130
1395#define ASC_IOADR_3 (PortAddr)0x0150
1396#define ASC_IOADR_4 (PortAddr)0x0190
1397#define ASC_IOADR_5 (PortAddr)0x0210
1398#define ASC_IOADR_6 (PortAddr)0x0230
1399#define ASC_IOADR_7 (PortAddr)0x0250
1400#define ASC_IOADR_8 (PortAddr)0x0330
1401#define ASC_IOADR_DEF ASC_IOADR_8
1402#define ASC_LIB_SCSIQ_WK_SP 256
1403#define ASC_MAX_SYN_XFER_NO 16
1404#define ASC_SYN_MAX_OFFSET 0x0F
1405#define ASC_DEF_SDTR_OFFSET 0x0F
1406#define ASC_DEF_SDTR_INDEX 0x00
1407#define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
1408#define SYN_XFER_NS_0 25
1409#define SYN_XFER_NS_1 30
1410#define SYN_XFER_NS_2 35
1411#define SYN_XFER_NS_3 40
1412#define SYN_XFER_NS_4 50
1413#define SYN_XFER_NS_5 60
1414#define SYN_XFER_NS_6 70
1415#define SYN_XFER_NS_7 85
1416#define SYN_ULTRA_XFER_NS_0 12
1417#define SYN_ULTRA_XFER_NS_1 19
1418#define SYN_ULTRA_XFER_NS_2 25
1419#define SYN_ULTRA_XFER_NS_3 32
1420#define SYN_ULTRA_XFER_NS_4 38
1421#define SYN_ULTRA_XFER_NS_5 44
1422#define SYN_ULTRA_XFER_NS_6 50
1423#define SYN_ULTRA_XFER_NS_7 57
1424#define SYN_ULTRA_XFER_NS_8 63
1425#define SYN_ULTRA_XFER_NS_9 69
1426#define SYN_ULTRA_XFER_NS_10 75
1427#define SYN_ULTRA_XFER_NS_11 82
1428#define SYN_ULTRA_XFER_NS_12 88
1429#define SYN_ULTRA_XFER_NS_13 94
1430#define SYN_ULTRA_XFER_NS_14 100
1431#define SYN_ULTRA_XFER_NS_15 107
1432
1433typedef struct ext_msg {
1434 uchar msg_type;
1435 uchar msg_len;
1436 uchar msg_req;
1437 union {
1438 struct {
1439 uchar sdtr_xfer_period;
1440 uchar sdtr_req_ack_offset;
1441 } sdtr;
1442 struct {
1443 uchar wdtr_width;
1444 } wdtr;
1445 struct {
1446 uchar mdp_b3;
1447 uchar mdp_b2;
1448 uchar mdp_b1;
1449 uchar mdp_b0;
1450 } mdp;
1451 } u_ext_msg;
1452 uchar res;
1453} EXT_MSG;
1454
1455#define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
1456#define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
1457#define wdtr_width u_ext_msg.wdtr.wdtr_width
1458#define mdp_b3 u_ext_msg.mdp_b3
1459#define mdp_b2 u_ext_msg.mdp_b2
1460#define mdp_b1 u_ext_msg.mdp_b1
1461#define mdp_b0 u_ext_msg.mdp_b0
1462
1463typedef struct asc_dvc_cfg {
1464 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1465 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1466 ASC_SCSI_BIT_ID_TYPE disc_enable;
1467 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1468 uchar chip_scsi_id;
1469 uchar isa_dma_speed;
1470 uchar isa_dma_channel;
1471 uchar chip_version;
1472 ushort lib_serial_no;
1473 ushort lib_version;
1474 ushort mcode_date;
1475 ushort mcode_version;
1476 uchar max_tag_qng[ASC_MAX_TID + 1];
1477 uchar *overrun_buf;
1478 uchar sdtr_period_offset[ASC_MAX_TID + 1];
1479 ushort pci_slot_info;
1480 uchar adapter_info[6];
1481 struct device *dev;
1482} ASC_DVC_CFG;
1483
1484#define ASC_DEF_DVC_CNTL 0xFFFF
1485#define ASC_DEF_CHIP_SCSI_ID 7
1486#define ASC_DEF_ISA_DMA_SPEED 4
1487#define ASC_INIT_STATE_NULL 0x0000
1488#define ASC_INIT_STATE_BEG_GET_CFG 0x0001
1489#define ASC_INIT_STATE_END_GET_CFG 0x0002
1490#define ASC_INIT_STATE_BEG_SET_CFG 0x0004
1491#define ASC_INIT_STATE_END_SET_CFG 0x0008
1492#define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
1493#define ASC_INIT_STATE_END_LOAD_MC 0x0020
1494#define ASC_INIT_STATE_BEG_INQUIRY 0x0040
1495#define ASC_INIT_STATE_END_INQUIRY 0x0080
1496#define ASC_INIT_RESET_SCSI_DONE 0x0100
1497#define ASC_INIT_STATE_WITHOUT_EEP 0x8000
1da177e4
LT
1498#define ASC_BUG_FIX_IF_NOT_DWB 0x0001
1499#define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
1500#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1501#define ASC_MIN_TAGGED_CMD 7
1502#define ASC_MAX_SCSI_RESET_WAIT 30
1503
1504struct asc_dvc_var; /* Forward Declaration. */
1505
1506typedef void (* ASC_ISR_CALLBACK)(struct asc_dvc_var *, ASC_QDONE_INFO *);
1507typedef int (* ASC_EXE_CALLBACK)(struct asc_dvc_var *, ASC_SCSI_Q *);
1508
1509typedef struct asc_dvc_var {
1510 PortAddr iop_base;
1511 ushort err_code;
1512 ushort dvc_cntl;
1513 ushort bug_fix_cntl;
1514 ushort bus_type;
1515 ASC_ISR_CALLBACK isr_callback;
1516 ASC_EXE_CALLBACK exe_callback;
1517 ASC_SCSI_BIT_ID_TYPE init_sdtr;
1518 ASC_SCSI_BIT_ID_TYPE sdtr_done;
1519 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1520 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1521 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1522 ASC_SCSI_BIT_ID_TYPE start_motor;
1523 uchar scsi_reset_wait;
1524 uchar chip_no;
1525 char is_in_int;
1526 uchar max_total_qng;
1527 uchar cur_total_qng;
1528 uchar in_critical_cnt;
1529 uchar irq_no;
1530 uchar last_q_shortage;
1531 ushort init_state;
1532 uchar cur_dvc_qng[ASC_MAX_TID + 1];
1533 uchar max_dvc_qng[ASC_MAX_TID + 1];
1534 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
1535 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
1536 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1537 ASC_DVC_CFG *cfg;
1538 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1539 char redo_scam;
1540 ushort res2;
1541 uchar dos_int13_table[ASC_MAX_TID + 1];
1542 ASC_DCNT max_dma_count;
1543 ASC_SCSI_BIT_ID_TYPE no_scam;
1544 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1545 uchar max_sdtr_index;
1546 uchar host_init_sdtr_index;
1547 struct asc_board *drv_ptr;
1548 ASC_DCNT uc_break;
1549} ASC_DVC_VAR;
1550
1551typedef struct asc_dvc_inq_info {
1552 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1553} ASC_DVC_INQ_INFO;
1554
1555typedef struct asc_cap_info {
1556 ASC_DCNT lba;
1557 ASC_DCNT blk_size;
1558} ASC_CAP_INFO;
1559
1560typedef struct asc_cap_info_array {
1561 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1562} ASC_CAP_INFO_ARRAY;
1563
1564#define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
1565#define ASC_MCNTL_NULL_TARGET (ushort)0x0002
1566#define ASC_CNTL_INITIATOR (ushort)0x0001
1567#define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
1568#define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
1569#define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
1570#define ASC_CNTL_NO_SCAM (ushort)0x0010
1571#define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
1572#define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
1573#define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
1574#define ASC_CNTL_RESET_SCSI (ushort)0x0200
1575#define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
1576#define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
1577#define ASC_CNTL_SCSI_PARITY (ushort)0x1000
1578#define ASC_CNTL_BURST_MODE (ushort)0x2000
1579#define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1580#define ASC_EEP_DVC_CFG_BEG_VL 2
1581#define ASC_EEP_MAX_DVC_ADDR_VL 15
1582#define ASC_EEP_DVC_CFG_BEG 32
1583#define ASC_EEP_MAX_DVC_ADDR 45
1584#define ASC_EEP_DEFINED_WORDS 10
1585#define ASC_EEP_MAX_ADDR 63
1586#define ASC_EEP_RES_WORDS 0
1587#define ASC_EEP_MAX_RETRY 20
1588#define ASC_MAX_INIT_BUSY_RETRY 8
1589#define ASC_EEP_ISA_PNP_WSIZE 16
1590
1591/*
1592 * These macros keep the chip SCSI id and ISA DMA speed
1593 * bitfields in board order. C bitfields aren't portable
1594 * between big and little-endian platforms so they are
1595 * not used.
1596 */
1597
1598#define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
1599#define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
1600#define ASC_EEP_SET_CHIP_ID(cfg, sid) \
1601 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
1602#define ASC_EEP_SET_DMA_SPD(cfg, spd) \
1603 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
1604
1605typedef struct asceep_config {
1606 ushort cfg_lsw;
1607 ushort cfg_msw;
1608 uchar init_sdtr;
1609 uchar disc_enable;
1610 uchar use_cmd_qng;
1611 uchar start_motor;
1612 uchar max_total_qng;
1613 uchar max_tag_qng;
1614 uchar bios_scan;
1615 uchar power_up_wait;
1616 uchar no_scam;
1617 uchar id_speed; /* low order 4 bits is chip scsi id */
1618 /* high order 4 bits is isa dma speed */
1619 uchar dos_int13_table[ASC_MAX_TID + 1];
1620 uchar adapter_info[6];
1621 ushort cntl;
1622 ushort chksum;
1623} ASCEEP_CONFIG;
1624
1625#define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800
1626#define ASC_PCI_CFG_LSW_BURST_MODE 0x0080
1627#define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020
1628
1629#define ASC_EEP_CMD_READ 0x80
1630#define ASC_EEP_CMD_WRITE 0x40
1631#define ASC_EEP_CMD_WRITE_ABLE 0x30
1632#define ASC_EEP_CMD_WRITE_DISABLE 0x00
1633#define ASC_OVERRUN_BSIZE 0x00000048UL
1634#define ASC_CTRL_BREAK_ONCE 0x0001
1635#define ASC_CTRL_BREAK_STAY_IDLE 0x0002
1636#define ASCV_MSGOUT_BEG 0x0000
1637#define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1638#define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1639#define ASCV_BREAK_SAVED_CODE (ushort)0x0006
1640#define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
1641#define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
1642#define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
1643#define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
1644#define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
1645#define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
1646#define ASCV_BREAK_ADDR (ushort)0x0028
1647#define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
1648#define ASCV_BREAK_CONTROL (ushort)0x002C
1649#define ASCV_BREAK_HIT_COUNT (ushort)0x002E
1650
1651#define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
1652#define ASCV_MCODE_CHKSUM_W (ushort)0x0032
1653#define ASCV_MCODE_SIZE_W (ushort)0x0034
1654#define ASCV_STOP_CODE_B (ushort)0x0036
1655#define ASCV_DVC_ERR_CODE_B (ushort)0x0037
1656#define ASCV_OVERRUN_PADDR_D (ushort)0x0038
1657#define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
1658#define ASCV_HALTCODE_W (ushort)0x0040
1659#define ASCV_CHKSUM_W (ushort)0x0042
1660#define ASCV_MC_DATE_W (ushort)0x0044
1661#define ASCV_MC_VER_W (ushort)0x0046
1662#define ASCV_NEXTRDY_B (ushort)0x0048
1663#define ASCV_DONENEXT_B (ushort)0x0049
1664#define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1665#define ASCV_SCSIBUSY_B (ushort)0x004B
1666#define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
1667#define ASCV_CURCDB_B (ushort)0x004D
1668#define ASCV_RCLUN_B (ushort)0x004E
1669#define ASCV_BUSY_QHEAD_B (ushort)0x004F
1670#define ASCV_DISC1_QHEAD_B (ushort)0x0050
1671#define ASCV_DISC_ENABLE_B (ushort)0x0052
1672#define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1673#define ASCV_HOSTSCSI_ID_B (ushort)0x0055
1674#define ASCV_MCODE_CNTL_B (ushort)0x0056
1675#define ASCV_NULL_TARGET_B (ushort)0x0057
1676#define ASCV_FREE_Q_HEAD_W (ushort)0x0058
1677#define ASCV_DONE_Q_TAIL_W (ushort)0x005A
1678#define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
1679#define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
1680#define ASCV_HOST_FLAG_B (ushort)0x005D
1681#define ASCV_TOTAL_READY_Q_B (ushort)0x0064
1682#define ASCV_VER_SERIAL_B (ushort)0x0065
1683#define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1684#define ASCV_WTM_FLAG_B (ushort)0x0068
1685#define ASCV_RISC_FLAG_B (ushort)0x006A
1686#define ASCV_REQ_SG_LIST_QP (ushort)0x006B
1687#define ASC_HOST_FLAG_IN_ISR 0x01
1688#define ASC_HOST_FLAG_ACK_INT 0x02
1689#define ASC_RISC_FLAG_GEN_INT 0x01
1690#define ASC_RISC_FLAG_REQ_SG_LIST 0x02
1691#define IOP_CTRL (0x0F)
1692#define IOP_STATUS (0x0E)
1693#define IOP_INT_ACK IOP_STATUS
1694#define IOP_REG_IFC (0x0D)
1695#define IOP_SYN_OFFSET (0x0B)
1696#define IOP_EXTRA_CONTROL (0x0D)
1697#define IOP_REG_PC (0x0C)
1698#define IOP_RAM_ADDR (0x0A)
1699#define IOP_RAM_DATA (0x08)
1700#define IOP_EEP_DATA (0x06)
1701#define IOP_EEP_CMD (0x07)
1702#define IOP_VERSION (0x03)
1703#define IOP_CONFIG_HIGH (0x04)
1704#define IOP_CONFIG_LOW (0x02)
1705#define IOP_SIG_BYTE (0x01)
1706#define IOP_SIG_WORD (0x00)
1707#define IOP_REG_DC1 (0x0E)
1708#define IOP_REG_DC0 (0x0C)
1709#define IOP_REG_SB (0x0B)
1710#define IOP_REG_DA1 (0x0A)
1711#define IOP_REG_DA0 (0x08)
1712#define IOP_REG_SC (0x09)
1713#define IOP_DMA_SPEED (0x07)
1714#define IOP_REG_FLAG (0x07)
1715#define IOP_FIFO_H (0x06)
1716#define IOP_FIFO_L (0x04)
1717#define IOP_REG_ID (0x05)
1718#define IOP_REG_QP (0x03)
1719#define IOP_REG_IH (0x02)
1720#define IOP_REG_IX (0x01)
1721#define IOP_REG_AX (0x00)
1722#define IFC_REG_LOCK (0x00)
1723#define IFC_REG_UNLOCK (0x09)
1724#define IFC_WR_EN_FILTER (0x10)
1725#define IFC_RD_NO_EEPROM (0x10)
1726#define IFC_SLEW_RATE (0x20)
1727#define IFC_ACT_NEG (0x40)
1728#define IFC_INP_FILTER (0x80)
1729#define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
1730#define SC_SEL (uchar)(0x80)
1731#define SC_BSY (uchar)(0x40)
1732#define SC_ACK (uchar)(0x20)
1733#define SC_REQ (uchar)(0x10)
1734#define SC_ATN (uchar)(0x08)
1735#define SC_IO (uchar)(0x04)
1736#define SC_CD (uchar)(0x02)
1737#define SC_MSG (uchar)(0x01)
1738#define SEC_SCSI_CTL (uchar)(0x80)
1739#define SEC_ACTIVE_NEGATE (uchar)(0x40)
1740#define SEC_SLEW_RATE (uchar)(0x20)
1741#define SEC_ENABLE_FILTER (uchar)(0x10)
1742#define ASC_HALT_EXTMSG_IN (ushort)0x8000
1743#define ASC_HALT_CHK_CONDITION (ushort)0x8100
1744#define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1745#define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
1746#define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
1747#define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1748#define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1749#define ASC_MAX_QNO 0xF8
1750#define ASC_DATA_SEC_BEG (ushort)0x0080
1751#define ASC_DATA_SEC_END (ushort)0x0080
1752#define ASC_CODE_SEC_BEG (ushort)0x0080
1753#define ASC_CODE_SEC_END (ushort)0x0080
1754#define ASC_QADR_BEG (0x4000)
1755#define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
1756#define ASC_QADR_END (ushort)0x7FFF
1757#define ASC_QLAST_ADR (ushort)0x7FC0
1758#define ASC_QBLK_SIZE 0x40
1759#define ASC_BIOS_DATA_QBEG 0xF8
1760#define ASC_MIN_ACTIVE_QNO 0x01
1761#define ASC_QLINK_END 0xFF
1762#define ASC_EEPROM_WORDS 0x10
1763#define ASC_MAX_MGS_LEN 0x10
1764#define ASC_BIOS_ADDR_DEF 0xDC00
1765#define ASC_BIOS_SIZE 0x3800
1766#define ASC_BIOS_RAM_OFF 0x3800
1767#define ASC_BIOS_RAM_SIZE 0x800
1768#define ASC_BIOS_MIN_ADDR 0xC000
1769#define ASC_BIOS_MAX_ADDR 0xEC00
1770#define ASC_BIOS_BANK_SIZE 0x0400
1771#define ASC_MCODE_START_ADDR 0x0080
1772#define ASC_CFG0_HOST_INT_ON 0x0020
1773#define ASC_CFG0_BIOS_ON 0x0040
1774#define ASC_CFG0_VERA_BURST_ON 0x0080
1775#define ASC_CFG0_SCSI_PARITY_ON 0x0800
1776#define ASC_CFG1_SCSI_TARGET_ON 0x0080
1777#define ASC_CFG1_LRAM_8BITS_ON 0x0800
1778#define ASC_CFG_MSW_CLR_MASK 0x3080
1779#define CSW_TEST1 (ASC_CS_TYPE)0x8000
1780#define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
1781#define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
1782#define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
1783#define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
1784#define CSW_TEST2 (ASC_CS_TYPE)0x0400
1785#define CSW_TEST3 (ASC_CS_TYPE)0x0200
1786#define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
1787#define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
1788#define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
1789#define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
1790#define CSW_HALTED (ASC_CS_TYPE)0x0010
1791#define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1792#define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
1793#define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
1794#define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
1795#define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1796#define CIW_INT_ACK (ASC_CS_TYPE)0x0100
1797#define CIW_TEST1 (ASC_CS_TYPE)0x0200
1798#define CIW_TEST2 (ASC_CS_TYPE)0x0400
1799#define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
1800#define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
1801#define CC_CHIP_RESET (uchar)0x80
1802#define CC_SCSI_RESET (uchar)0x40
1803#define CC_HALT (uchar)0x20
1804#define CC_SINGLE_STEP (uchar)0x10
1805#define CC_DMA_ABLE (uchar)0x08
1806#define CC_TEST (uchar)0x04
1807#define CC_BANK_ONE (uchar)0x02
1808#define CC_DIAG (uchar)0x01
1809#define ASC_1000_ID0W 0x04C1
1810#define ASC_1000_ID0W_FIX 0x00C1
1811#define ASC_1000_ID1B 0x25
1812#define ASC_EISA_BIG_IOP_GAP (0x1C30-0x0C50)
1813#define ASC_EISA_SMALL_IOP_GAP (0x0020)
1814#define ASC_EISA_MIN_IOP_ADDR (0x0C30)
1815#define ASC_EISA_MAX_IOP_ADDR (0xFC50)
1816#define ASC_EISA_REV_IOP_MASK (0x0C83)
1817#define ASC_EISA_PID_IOP_MASK (0x0C80)
1818#define ASC_EISA_CFG_IOP_MASK (0x0C86)
1819#define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
1820#define ASC_EISA_ID_740 0x01745004UL
1821#define ASC_EISA_ID_750 0x01755004UL
1822#define INS_HALTINT (ushort)0x6281
1823#define INS_HALT (ushort)0x6280
1824#define INS_SINT (ushort)0x6200
1825#define INS_RFLAG_WTM (ushort)0x7380
1826#define ASC_MC_SAVE_CODE_WSIZE 0x500
1827#define ASC_MC_SAVE_DATA_WSIZE 0x40
1828
1829typedef struct asc_mc_saved {
1830 ushort data[ASC_MC_SAVE_DATA_WSIZE];
1831 ushort code[ASC_MC_SAVE_CODE_WSIZE];
1832} ASC_MC_SAVED;
1833
1834#define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1835#define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1836#define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1837#define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1838#define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1839#define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1840#define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
1841#define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
1842#define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1843#define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1844#define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1845#define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1846#define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1847#define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1848#define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1849#define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
1850#define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
1851#define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
1852#define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
1853#define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
1854#define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
1855#define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
1856#define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
1857#define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
1858#define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
1859#define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
1860#define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1861#define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1862#define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
1863#define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
1864#define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
1865#define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
1866#define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1867#define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
1868#define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
1869#define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
1870#define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
1871#define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
1872#define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
1873#define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
1874#define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1875#define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1876#define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
1877#define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
1878#define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
1879#define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
1880#define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
1881#define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
1882#define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
1883#define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
1884#define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
1885#define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
1886#define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
1887#define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
1888#define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
1889#define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
1890#define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
1891#define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
1892#define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
1893#define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
1894#define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
1895#define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
1896#define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
1897#define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
1898#define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
1899#define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
1900#define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
1901#define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
1902
1903STATIC int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1904STATIC int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1905STATIC void AscWaitEEPRead(void);
1906STATIC void AscWaitEEPWrite(void);
1907STATIC ushort AscReadEEPWord(PortAddr, uchar);
1908STATIC ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1909STATIC ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1910STATIC int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1911STATIC int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1912STATIC int AscStartChip(PortAddr);
1913STATIC int AscStopChip(PortAddr);
1914STATIC void AscSetChipIH(PortAddr, ushort);
1915STATIC int AscIsChipHalted(PortAddr);
1916STATIC void AscAckInterrupt(PortAddr);
1917STATIC void AscDisableInterrupt(PortAddr);
1918STATIC void AscEnableInterrupt(PortAddr);
1919STATIC void AscSetBank(PortAddr, uchar);
1920STATIC int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1921#ifdef CONFIG_ISA
1922STATIC ushort AscGetIsaDmaChannel(PortAddr);
1923STATIC ushort AscSetIsaDmaChannel(PortAddr, ushort);
1924STATIC uchar AscSetIsaDmaSpeed(PortAddr, uchar);
1925STATIC uchar AscGetIsaDmaSpeed(PortAddr);
1926#endif /* CONFIG_ISA */
1927STATIC uchar AscReadLramByte(PortAddr, ushort);
1928STATIC ushort AscReadLramWord(PortAddr, ushort);
1929#if CC_VERY_LONG_SG_LIST
1930STATIC ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1931#endif /* CC_VERY_LONG_SG_LIST */
1932STATIC void AscWriteLramWord(PortAddr, ushort, ushort);
1933STATIC void AscWriteLramByte(PortAddr, ushort, uchar);
1934STATIC ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
1935STATIC void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1936STATIC void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1937STATIC void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1938STATIC void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
1939STATIC ushort AscInitAscDvcVar(ASC_DVC_VAR *);
1940STATIC ushort AscInitFromEEP(ASC_DVC_VAR *);
1941STATIC ushort AscInitFromAscDvcVar(ASC_DVC_VAR *);
1942STATIC ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1943STATIC int AscTestExternalLram(ASC_DVC_VAR *);
1944STATIC uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1945STATIC uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1946STATIC void AscSetChipSDTR(PortAddr, uchar, uchar);
1947STATIC uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1948STATIC uchar AscAllocFreeQueue(PortAddr, uchar);
1949STATIC uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1950STATIC int AscHostReqRiscHalt(PortAddr);
1951STATIC int AscStopQueueExe(PortAddr);
1952STATIC int AscSendScsiQueue(ASC_DVC_VAR *,
1953 ASC_SCSI_Q * scsiq,
1954 uchar n_q_required);
1955STATIC int AscPutReadyQueue(ASC_DVC_VAR *,
1956 ASC_SCSI_Q *, uchar);
1957STATIC int AscPutReadySgListQueue(ASC_DVC_VAR *,
1958 ASC_SCSI_Q *, uchar);
1959STATIC int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1960STATIC int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1961STATIC ushort AscInitLram(ASC_DVC_VAR *);
1962STATIC ushort AscInitQLinkVar(ASC_DVC_VAR *);
1963STATIC int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1964STATIC int AscIsrChipHalted(ASC_DVC_VAR *);
1965STATIC uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1966 ASC_QDONE_INFO *, ASC_DCNT);
1967STATIC int AscIsrQDone(ASC_DVC_VAR *);
1968STATIC int AscCompareString(uchar *, uchar *, int);
1969#ifdef CONFIG_ISA
1970STATIC ushort AscGetEisaChipCfg(PortAddr);
1971STATIC ASC_DCNT AscGetEisaProductID(PortAddr);
1972STATIC PortAddr AscSearchIOPortAddrEISA(PortAddr);
1973STATIC PortAddr AscSearchIOPortAddr11(PortAddr);
1974STATIC PortAddr AscSearchIOPortAddr(PortAddr, ushort);
1975STATIC void AscSetISAPNPWaitForKey(void);
1976#endif /* CONFIG_ISA */
1977STATIC uchar AscGetChipScsiCtrl(PortAddr);
1978STATIC uchar AscSetChipScsiID(PortAddr, uchar);
1979STATIC uchar AscGetChipVersion(PortAddr, ushort);
1980STATIC ushort AscGetChipBusType(PortAddr);
1981STATIC ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
1982STATIC int AscFindSignature(PortAddr);
1983STATIC void AscToggleIRQAct(PortAddr);
1984STATIC uchar AscGetChipIRQ(PortAddr, ushort);
1985STATIC uchar AscSetChipIRQ(PortAddr, uchar, ushort);
1986STATIC ushort AscGetChipBiosAddress(PortAddr, ushort);
1987STATIC inline ulong DvcEnterCritical(void);
1988STATIC inline void DvcLeaveCritical(ulong);
1989#ifdef CONFIG_PCI
1990STATIC uchar DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort);
1991STATIC void DvcWritePCIConfigByte(ASC_DVC_VAR *,
1992 ushort, uchar);
1993#endif /* CONFIG_PCI */
1994STATIC ushort AscGetChipBiosAddress(PortAddr, ushort);
1995STATIC void DvcSleepMilliSecond(ASC_DCNT);
1996STATIC void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
1997STATIC void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1998STATIC void DvcGetQinfo(PortAddr, ushort, uchar *, int);
1999STATIC ushort AscInitGetConfig(ASC_DVC_VAR *);
2000STATIC ushort AscInitSetConfig(ASC_DVC_VAR *);
2001STATIC ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
2002STATIC void AscAsyncFix(ASC_DVC_VAR *, uchar,
2003 ASC_SCSI_INQUIRY *);
2004STATIC int AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
2005STATIC void AscInquiryHandling(ASC_DVC_VAR *,
2006 uchar, ASC_SCSI_INQUIRY *);
2007STATIC int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
2008STATIC int AscISR(ASC_DVC_VAR *);
2009STATIC uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar,
2010 uchar);
2011STATIC int AscSgListToQueue(int);
2012#ifdef CONFIG_ISA
2013STATIC void AscEnableIsaDma(uchar);
2014#endif /* CONFIG_ISA */
2015STATIC ASC_DCNT AscGetMaxDmaCount(ushort);
70c8d897 2016static const char *advansys_info(struct Scsi_Host *shp);
1da177e4
LT
2017
2018/*
2019 * --- Adv Library Constants and Macros
2020 */
2021
2022#define ADV_LIB_VERSION_MAJOR 5
2023#define ADV_LIB_VERSION_MINOR 14
2024
2025/*
2026 * Define Adv Library required special types.
2027 */
2028
2029/*
2030 * Portable Data Types
2031 *
2032 * Any instance where a 32-bit long or pointer type is assumed
2033 * for precision or HW defined structures, the following define
2034 * types must be used. In Linux the char, short, and int types
2035 * are all consistent at 8, 16, and 32 bits respectively. Pointers
2036 * and long types are 64 bits on Alpha and UltraSPARC.
2037 */
2038#define ADV_PADDR __u32 /* Physical address data type. */
2039#define ADV_VADDR __u32 /* Virtual address data type. */
2040#define ADV_DCNT __u32 /* Unsigned Data count type. */
2041#define ADV_SDCNT __s32 /* Signed Data count type. */
2042
2043/*
2044 * These macros are used to convert a virtual address to a
2045 * 32-bit value. This currently can be used on Linux Alpha
2046 * which uses 64-bit virtual address but a 32-bit bus address.
2047 * This is likely to break in the future, but doing this now
2048 * will give us time to change the HW and FW to handle 64-bit
2049 * addresses.
2050 */
2051#define ADV_VADDR_TO_U32 virt_to_bus
2052#define ADV_U32_TO_VADDR bus_to_virt
2053
4661e3ea 2054#define AdvPortAddr void __iomem * /* Virtual memory address size */
1da177e4
LT
2055
2056/*
2057 * Define Adv Library required memory access macros.
2058 */
2059#define ADV_MEM_READB(addr) readb(addr)
2060#define ADV_MEM_READW(addr) readw(addr)
2061#define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
2062#define ADV_MEM_WRITEW(addr, word) writew(word, addr)
2063#define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
2064
2065#define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
2066
2067/*
2068 * For wide boards a CDB length maximum of 16 bytes
2069 * is supported.
2070 */
2071#define ADV_MAX_CDB_LEN 16
2072
2073/*
2074 * Define total number of simultaneous maximum element scatter-gather
2075 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
2076 * maximum number of outstanding commands per wide host adapter. Each
2077 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
2078 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
2079 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
2080 * structures or 255 scatter-gather elements.
2081 *
2082 */
2083#define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
2084
2085/*
2086 * Define Adv Library required maximum number of scatter-gather
2087 * elements per request.
2088 */
2089#define ADV_MAX_SG_LIST 255
2090
2091/* Number of SG blocks needed. */
2092#define ADV_NUM_SG_BLOCK \
2093 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
2094
2095/* Total contiguous memory needed for SG blocks. */
2096#define ADV_SG_TOTAL_MEM_SIZE \
2097 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
2098
2099#define ADV_PAGE_SIZE PAGE_SIZE
2100
2101#define ADV_NUM_PAGE_CROSSING \
2102 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2103
1da177e4
LT
2104#define ADV_EEP_DVC_CFG_BEGIN (0x00)
2105#define ADV_EEP_DVC_CFG_END (0x15)
2106#define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
2107#define ADV_EEP_MAX_WORD_ADDR (0x1E)
2108
2109#define ADV_EEP_DELAY_MS 100
2110
2111#define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
2112#define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
2113/*
2114 * For the ASC3550 Bit 13 is Termination Polarity control bit.
2115 * For later ICs Bit 13 controls whether the CIS (Card Information
2116 * Service Section) is loaded from EEPROM.
2117 */
2118#define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
2119#define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
2120/*
2121 * ASC38C1600 Bit 11
2122 *
2123 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
2124 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
2125 * Function 0 will specify INT B.
2126 *
2127 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
2128 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
2129 * Function 1 will specify INT A.
2130 */
2131#define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
2132
2133typedef struct adveep_3550_config
2134{
2135 /* Word Offset, Description */
2136
2137 ushort cfg_lsw; /* 00 power up initialization */
2138 /* bit 13 set - Term Polarity Control */
2139 /* bit 14 set - BIOS Enable */
2140 /* bit 15 set - Big Endian Mode */
2141 ushort cfg_msw; /* 01 unused */
2142 ushort disc_enable; /* 02 disconnect enable */
2143 ushort wdtr_able; /* 03 Wide DTR able */
2144 ushort sdtr_able; /* 04 Synchronous DTR able */
2145 ushort start_motor; /* 05 send start up motor */
2146 ushort tagqng_able; /* 06 tag queuing able */
2147 ushort bios_scan; /* 07 BIOS device control */
2148 ushort scam_tolerant; /* 08 no scam */
2149
2150 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2151 uchar bios_boot_delay; /* power up wait */
2152
2153 uchar scsi_reset_delay; /* 10 reset delay */
2154 uchar bios_id_lun; /* first boot device scsi id & lun */
2155 /* high nibble is lun */
2156 /* low nibble is scsi id */
2157
2158 uchar termination; /* 11 0 - automatic */
2159 /* 1 - low off / high off */
2160 /* 2 - low off / high on */
2161 /* 3 - low on / high on */
2162 /* There is no low on / high off */
2163
2164 uchar reserved1; /* reserved byte (not used) */
2165
2166 ushort bios_ctrl; /* 12 BIOS control bits */
2167 /* bit 0 BIOS don't act as initiator. */
2168 /* bit 1 BIOS > 1 GB support */
2169 /* bit 2 BIOS > 2 Disk Support */
2170 /* bit 3 BIOS don't support removables */
2171 /* bit 4 BIOS support bootable CD */
2172 /* bit 5 BIOS scan enabled */
2173 /* bit 6 BIOS support multiple LUNs */
2174 /* bit 7 BIOS display of message */
2175 /* bit 8 SCAM disabled */
2176 /* bit 9 Reset SCSI bus during init. */
2177 /* bit 10 */
2178 /* bit 11 No verbose initialization. */
2179 /* bit 12 SCSI parity enabled */
2180 /* bit 13 */
2181 /* bit 14 */
2182 /* bit 15 */
2183 ushort ultra_able; /* 13 ULTRA speed able */
2184 ushort reserved2; /* 14 reserved */
2185 uchar max_host_qng; /* 15 maximum host queuing */
2186 uchar max_dvc_qng; /* maximum per device queuing */
2187 ushort dvc_cntl; /* 16 control bit for driver */
2188 ushort bug_fix; /* 17 control bit for bug fix */
2189 ushort serial_number_word1; /* 18 Board serial number word 1 */
2190 ushort serial_number_word2; /* 19 Board serial number word 2 */
2191 ushort serial_number_word3; /* 20 Board serial number word 3 */
2192 ushort check_sum; /* 21 EEP check sum */
2193 uchar oem_name[16]; /* 22 OEM name */
2194 ushort dvc_err_code; /* 30 last device driver error code */
2195 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2196 ushort adv_err_addr; /* 32 last uc error address */
2197 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2198 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2199 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2200 ushort num_of_err; /* 36 number of error */
2201} ADVEEP_3550_CONFIG;
2202
2203typedef struct adveep_38C0800_config
2204{
2205 /* Word Offset, Description */
2206
2207 ushort cfg_lsw; /* 00 power up initialization */
2208 /* bit 13 set - Load CIS */
2209 /* bit 14 set - BIOS Enable */
2210 /* bit 15 set - Big Endian Mode */
2211 ushort cfg_msw; /* 01 unused */
2212 ushort disc_enable; /* 02 disconnect enable */
2213 ushort wdtr_able; /* 03 Wide DTR able */
2214 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2215 ushort start_motor; /* 05 send start up motor */
2216 ushort tagqng_able; /* 06 tag queuing able */
2217 ushort bios_scan; /* 07 BIOS device control */
2218 ushort scam_tolerant; /* 08 no scam */
2219
2220 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2221 uchar bios_boot_delay; /* power up wait */
2222
2223 uchar scsi_reset_delay; /* 10 reset delay */
2224 uchar bios_id_lun; /* first boot device scsi id & lun */
2225 /* high nibble is lun */
2226 /* low nibble is scsi id */
2227
2228 uchar termination_se; /* 11 0 - automatic */
2229 /* 1 - low off / high off */
2230 /* 2 - low off / high on */
2231 /* 3 - low on / high on */
2232 /* There is no low on / high off */
2233
2234 uchar termination_lvd; /* 11 0 - automatic */
2235 /* 1 - low off / high off */
2236 /* 2 - low off / high on */
2237 /* 3 - low on / high on */
2238 /* There is no low on / high off */
2239
2240 ushort bios_ctrl; /* 12 BIOS control bits */
2241 /* bit 0 BIOS don't act as initiator. */
2242 /* bit 1 BIOS > 1 GB support */
2243 /* bit 2 BIOS > 2 Disk Support */
2244 /* bit 3 BIOS don't support removables */
2245 /* bit 4 BIOS support bootable CD */
2246 /* bit 5 BIOS scan enabled */
2247 /* bit 6 BIOS support multiple LUNs */
2248 /* bit 7 BIOS display of message */
2249 /* bit 8 SCAM disabled */
2250 /* bit 9 Reset SCSI bus during init. */
2251 /* bit 10 */
2252 /* bit 11 No verbose initialization. */
2253 /* bit 12 SCSI parity enabled */
2254 /* bit 13 */
2255 /* bit 14 */
2256 /* bit 15 */
2257 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2258 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2259 uchar max_host_qng; /* 15 maximum host queueing */
2260 uchar max_dvc_qng; /* maximum per device queuing */
2261 ushort dvc_cntl; /* 16 control bit for driver */
2262 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2263 ushort serial_number_word1; /* 18 Board serial number word 1 */
2264 ushort serial_number_word2; /* 19 Board serial number word 2 */
2265 ushort serial_number_word3; /* 20 Board serial number word 3 */
2266 ushort check_sum; /* 21 EEP check sum */
2267 uchar oem_name[16]; /* 22 OEM name */
2268 ushort dvc_err_code; /* 30 last device driver error code */
2269 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2270 ushort adv_err_addr; /* 32 last uc error address */
2271 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2272 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2273 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2274 ushort reserved36; /* 36 reserved */
2275 ushort reserved37; /* 37 reserved */
2276 ushort reserved38; /* 38 reserved */
2277 ushort reserved39; /* 39 reserved */
2278 ushort reserved40; /* 40 reserved */
2279 ushort reserved41; /* 41 reserved */
2280 ushort reserved42; /* 42 reserved */
2281 ushort reserved43; /* 43 reserved */
2282 ushort reserved44; /* 44 reserved */
2283 ushort reserved45; /* 45 reserved */
2284 ushort reserved46; /* 46 reserved */
2285 ushort reserved47; /* 47 reserved */
2286 ushort reserved48; /* 48 reserved */
2287 ushort reserved49; /* 49 reserved */
2288 ushort reserved50; /* 50 reserved */
2289 ushort reserved51; /* 51 reserved */
2290 ushort reserved52; /* 52 reserved */
2291 ushort reserved53; /* 53 reserved */
2292 ushort reserved54; /* 54 reserved */
2293 ushort reserved55; /* 55 reserved */
2294 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2295 ushort cisprt_msw; /* 57 CIS PTR MSW */
2296 ushort subsysvid; /* 58 SubSystem Vendor ID */
2297 ushort subsysid; /* 59 SubSystem ID */
2298 ushort reserved60; /* 60 reserved */
2299 ushort reserved61; /* 61 reserved */
2300 ushort reserved62; /* 62 reserved */
2301 ushort reserved63; /* 63 reserved */
2302} ADVEEP_38C0800_CONFIG;
2303
2304typedef struct adveep_38C1600_config
2305{
2306 /* Word Offset, Description */
2307
2308 ushort cfg_lsw; /* 00 power up initialization */
2309 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
2310 /* clear - Func. 0 INTA, Func. 1 INTB */
2311 /* bit 13 set - Load CIS */
2312 /* bit 14 set - BIOS Enable */
2313 /* bit 15 set - Big Endian Mode */
2314 ushort cfg_msw; /* 01 unused */
2315 ushort disc_enable; /* 02 disconnect enable */
2316 ushort wdtr_able; /* 03 Wide DTR able */
2317 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2318 ushort start_motor; /* 05 send start up motor */
2319 ushort tagqng_able; /* 06 tag queuing able */
2320 ushort bios_scan; /* 07 BIOS device control */
2321 ushort scam_tolerant; /* 08 no scam */
2322
2323 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2324 uchar bios_boot_delay; /* power up wait */
2325
2326 uchar scsi_reset_delay; /* 10 reset delay */
2327 uchar bios_id_lun; /* first boot device scsi id & lun */
2328 /* high nibble is lun */
2329 /* low nibble is scsi id */
2330
2331 uchar termination_se; /* 11 0 - automatic */
2332 /* 1 - low off / high off */
2333 /* 2 - low off / high on */
2334 /* 3 - low on / high on */
2335 /* There is no low on / high off */
2336
2337 uchar termination_lvd; /* 11 0 - automatic */
2338 /* 1 - low off / high off */
2339 /* 2 - low off / high on */
2340 /* 3 - low on / high on */
2341 /* There is no low on / high off */
2342
2343 ushort bios_ctrl; /* 12 BIOS control bits */
2344 /* bit 0 BIOS don't act as initiator. */
2345 /* bit 1 BIOS > 1 GB support */
2346 /* bit 2 BIOS > 2 Disk Support */
2347 /* bit 3 BIOS don't support removables */
2348 /* bit 4 BIOS support bootable CD */
2349 /* bit 5 BIOS scan enabled */
2350 /* bit 6 BIOS support multiple LUNs */
2351 /* bit 7 BIOS display of message */
2352 /* bit 8 SCAM disabled */
2353 /* bit 9 Reset SCSI bus during init. */
2354 /* bit 10 Basic Integrity Checking disabled */
2355 /* bit 11 No verbose initialization. */
2356 /* bit 12 SCSI parity enabled */
2357 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
2358 /* bit 14 */
2359 /* bit 15 */
2360 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2361 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2362 uchar max_host_qng; /* 15 maximum host queueing */
2363 uchar max_dvc_qng; /* maximum per device queuing */
2364 ushort dvc_cntl; /* 16 control bit for driver */
2365 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2366 ushort serial_number_word1; /* 18 Board serial number word 1 */
2367 ushort serial_number_word2; /* 19 Board serial number word 2 */
2368 ushort serial_number_word3; /* 20 Board serial number word 3 */
2369 ushort check_sum; /* 21 EEP check sum */
2370 uchar oem_name[16]; /* 22 OEM name */
2371 ushort dvc_err_code; /* 30 last device driver error code */
2372 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2373 ushort adv_err_addr; /* 32 last uc error address */
2374 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2375 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2376 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2377 ushort reserved36; /* 36 reserved */
2378 ushort reserved37; /* 37 reserved */
2379 ushort reserved38; /* 38 reserved */
2380 ushort reserved39; /* 39 reserved */
2381 ushort reserved40; /* 40 reserved */
2382 ushort reserved41; /* 41 reserved */
2383 ushort reserved42; /* 42 reserved */
2384 ushort reserved43; /* 43 reserved */
2385 ushort reserved44; /* 44 reserved */
2386 ushort reserved45; /* 45 reserved */
2387 ushort reserved46; /* 46 reserved */
2388 ushort reserved47; /* 47 reserved */
2389 ushort reserved48; /* 48 reserved */
2390 ushort reserved49; /* 49 reserved */
2391 ushort reserved50; /* 50 reserved */
2392 ushort reserved51; /* 51 reserved */
2393 ushort reserved52; /* 52 reserved */
2394 ushort reserved53; /* 53 reserved */
2395 ushort reserved54; /* 54 reserved */
2396 ushort reserved55; /* 55 reserved */
2397 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2398 ushort cisprt_msw; /* 57 CIS PTR MSW */
2399 ushort subsysvid; /* 58 SubSystem Vendor ID */
2400 ushort subsysid; /* 59 SubSystem ID */
2401 ushort reserved60; /* 60 reserved */
2402 ushort reserved61; /* 61 reserved */
2403 ushort reserved62; /* 62 reserved */
2404 ushort reserved63; /* 63 reserved */
2405} ADVEEP_38C1600_CONFIG;
2406
2407/*
2408 * EEPROM Commands
2409 */
2410#define ASC_EEP_CMD_DONE 0x0200
2411#define ASC_EEP_CMD_DONE_ERR 0x0001
2412
2413/* cfg_word */
2414#define EEP_CFG_WORD_BIG_ENDIAN 0x8000
2415
2416/* bios_ctrl */
2417#define BIOS_CTRL_BIOS 0x0001
2418#define BIOS_CTRL_EXTENDED_XLAT 0x0002
2419#define BIOS_CTRL_GT_2_DISK 0x0004
2420#define BIOS_CTRL_BIOS_REMOVABLE 0x0008
2421#define BIOS_CTRL_BOOTABLE_CD 0x0010
2422#define BIOS_CTRL_MULTIPLE_LUN 0x0040
2423#define BIOS_CTRL_DISPLAY_MSG 0x0080
2424#define BIOS_CTRL_NO_SCAM 0x0100
2425#define BIOS_CTRL_RESET_SCSI_BUS 0x0200
2426#define BIOS_CTRL_INIT_VERBOSE 0x0800
2427#define BIOS_CTRL_SCSI_PARITY 0x1000
2428#define BIOS_CTRL_AIPP_DIS 0x2000
2429
2430#define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
2431#define ADV_3550_IOLEN 0x40 /* I/O Port Range in bytes */
2432
2433#define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2434#define ADV_38C0800_IOLEN 0x100 /* I/O Port Range in bytes */
2435
2436/*
2437 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
2438 * a special 16K Adv Library and Microcode version. After the issue is
2439 * resolved, should restore 32K support.
2440 *
2441 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
2442 */
2443#define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2444#define ADV_38C1600_IOLEN 0x100 /* I/O Port Range 256 bytes */
2445#define ADV_38C1600_MEMLEN 0x1000 /* Memory Range 4KB bytes */
2446
2447/*
2448 * Byte I/O register address from base of 'iop_base'.
2449 */
2450#define IOPB_INTR_STATUS_REG 0x00
2451#define IOPB_CHIP_ID_1 0x01
2452#define IOPB_INTR_ENABLES 0x02
2453#define IOPB_CHIP_TYPE_REV 0x03
2454#define IOPB_RES_ADDR_4 0x04
2455#define IOPB_RES_ADDR_5 0x05
2456#define IOPB_RAM_DATA 0x06
2457#define IOPB_RES_ADDR_7 0x07
2458#define IOPB_FLAG_REG 0x08
2459#define IOPB_RES_ADDR_9 0x09
2460#define IOPB_RISC_CSR 0x0A
2461#define IOPB_RES_ADDR_B 0x0B
2462#define IOPB_RES_ADDR_C 0x0C
2463#define IOPB_RES_ADDR_D 0x0D
2464#define IOPB_SOFT_OVER_WR 0x0E
2465#define IOPB_RES_ADDR_F 0x0F
2466#define IOPB_MEM_CFG 0x10
2467#define IOPB_RES_ADDR_11 0x11
2468#define IOPB_GPIO_DATA 0x12
2469#define IOPB_RES_ADDR_13 0x13
2470#define IOPB_FLASH_PAGE 0x14
2471#define IOPB_RES_ADDR_15 0x15
2472#define IOPB_GPIO_CNTL 0x16
2473#define IOPB_RES_ADDR_17 0x17
2474#define IOPB_FLASH_DATA 0x18
2475#define IOPB_RES_ADDR_19 0x19
2476#define IOPB_RES_ADDR_1A 0x1A
2477#define IOPB_RES_ADDR_1B 0x1B
2478#define IOPB_RES_ADDR_1C 0x1C
2479#define IOPB_RES_ADDR_1D 0x1D
2480#define IOPB_RES_ADDR_1E 0x1E
2481#define IOPB_RES_ADDR_1F 0x1F
2482#define IOPB_DMA_CFG0 0x20
2483#define IOPB_DMA_CFG1 0x21
2484#define IOPB_TICKLE 0x22
2485#define IOPB_DMA_REG_WR 0x23
2486#define IOPB_SDMA_STATUS 0x24
2487#define IOPB_SCSI_BYTE_CNT 0x25
2488#define IOPB_HOST_BYTE_CNT 0x26
2489#define IOPB_BYTE_LEFT_TO_XFER 0x27
2490#define IOPB_BYTE_TO_XFER_0 0x28
2491#define IOPB_BYTE_TO_XFER_1 0x29
2492#define IOPB_BYTE_TO_XFER_2 0x2A
2493#define IOPB_BYTE_TO_XFER_3 0x2B
2494#define IOPB_ACC_GRP 0x2C
2495#define IOPB_RES_ADDR_2D 0x2D
2496#define IOPB_DEV_ID 0x2E
2497#define IOPB_RES_ADDR_2F 0x2F
2498#define IOPB_SCSI_DATA 0x30
2499#define IOPB_RES_ADDR_31 0x31
2500#define IOPB_RES_ADDR_32 0x32
2501#define IOPB_SCSI_DATA_HSHK 0x33
2502#define IOPB_SCSI_CTRL 0x34
2503#define IOPB_RES_ADDR_35 0x35
2504#define IOPB_RES_ADDR_36 0x36
2505#define IOPB_RES_ADDR_37 0x37
2506#define IOPB_RAM_BIST 0x38
2507#define IOPB_PLL_TEST 0x39
2508#define IOPB_PCI_INT_CFG 0x3A
2509#define IOPB_RES_ADDR_3B 0x3B
2510#define IOPB_RFIFO_CNT 0x3C
2511#define IOPB_RES_ADDR_3D 0x3D
2512#define IOPB_RES_ADDR_3E 0x3E
2513#define IOPB_RES_ADDR_3F 0x3F
2514
2515/*
2516 * Word I/O register address from base of 'iop_base'.
2517 */
2518#define IOPW_CHIP_ID_0 0x00 /* CID0 */
2519#define IOPW_CTRL_REG 0x02 /* CC */
2520#define IOPW_RAM_ADDR 0x04 /* LA */
2521#define IOPW_RAM_DATA 0x06 /* LD */
2522#define IOPW_RES_ADDR_08 0x08
2523#define IOPW_RISC_CSR 0x0A /* CSR */
2524#define IOPW_SCSI_CFG0 0x0C /* CFG0 */
2525#define IOPW_SCSI_CFG1 0x0E /* CFG1 */
2526#define IOPW_RES_ADDR_10 0x10
2527#define IOPW_SEL_MASK 0x12 /* SM */
2528#define IOPW_RES_ADDR_14 0x14
2529#define IOPW_FLASH_ADDR 0x16 /* FA */
2530#define IOPW_RES_ADDR_18 0x18
2531#define IOPW_EE_CMD 0x1A /* EC */
2532#define IOPW_EE_DATA 0x1C /* ED */
2533#define IOPW_SFIFO_CNT 0x1E /* SFC */
2534#define IOPW_RES_ADDR_20 0x20
2535#define IOPW_Q_BASE 0x22 /* QB */
2536#define IOPW_QP 0x24 /* QP */
2537#define IOPW_IX 0x26 /* IX */
2538#define IOPW_SP 0x28 /* SP */
2539#define IOPW_PC 0x2A /* PC */
2540#define IOPW_RES_ADDR_2C 0x2C
2541#define IOPW_RES_ADDR_2E 0x2E
2542#define IOPW_SCSI_DATA 0x30 /* SD */
2543#define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
2544#define IOPW_SCSI_CTRL 0x34 /* SC */
2545#define IOPW_HSHK_CFG 0x36 /* HCFG */
2546#define IOPW_SXFR_STATUS 0x36 /* SXS */
2547#define IOPW_SXFR_CNTL 0x38 /* SXL */
2548#define IOPW_SXFR_CNTH 0x3A /* SXH */
2549#define IOPW_RES_ADDR_3C 0x3C
2550#define IOPW_RFIFO_DATA 0x3E /* RFD */
2551
2552/*
2553 * Doubleword I/O register address from base of 'iop_base'.
2554 */
2555#define IOPDW_RES_ADDR_0 0x00
2556#define IOPDW_RAM_DATA 0x04
2557#define IOPDW_RES_ADDR_8 0x08
2558#define IOPDW_RES_ADDR_C 0x0C
2559#define IOPDW_RES_ADDR_10 0x10
2560#define IOPDW_COMMA 0x14
2561#define IOPDW_COMMB 0x18
2562#define IOPDW_RES_ADDR_1C 0x1C
2563#define IOPDW_SDMA_ADDR0 0x20
2564#define IOPDW_SDMA_ADDR1 0x24
2565#define IOPDW_SDMA_COUNT 0x28
2566#define IOPDW_SDMA_ERROR 0x2C
2567#define IOPDW_RDMA_ADDR0 0x30
2568#define IOPDW_RDMA_ADDR1 0x34
2569#define IOPDW_RDMA_COUNT 0x38
2570#define IOPDW_RDMA_ERROR 0x3C
2571
2572#define ADV_CHIP_ID_BYTE 0x25
2573#define ADV_CHIP_ID_WORD 0x04C1
2574
2575#define ADV_SC_SCSI_BUS_RESET 0x2000
2576
2577#define ADV_INTR_ENABLE_HOST_INTR 0x01
2578#define ADV_INTR_ENABLE_SEL_INTR 0x02
2579#define ADV_INTR_ENABLE_DPR_INTR 0x04
2580#define ADV_INTR_ENABLE_RTA_INTR 0x08
2581#define ADV_INTR_ENABLE_RMA_INTR 0x10
2582#define ADV_INTR_ENABLE_RST_INTR 0x20
2583#define ADV_INTR_ENABLE_DPE_INTR 0x40
2584#define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
2585
2586#define ADV_INTR_STATUS_INTRA 0x01
2587#define ADV_INTR_STATUS_INTRB 0x02
2588#define ADV_INTR_STATUS_INTRC 0x04
2589
2590#define ADV_RISC_CSR_STOP (0x0000)
2591#define ADV_RISC_TEST_COND (0x2000)
2592#define ADV_RISC_CSR_RUN (0x4000)
2593#define ADV_RISC_CSR_SINGLE_STEP (0x8000)
2594
2595#define ADV_CTRL_REG_HOST_INTR 0x0100
2596#define ADV_CTRL_REG_SEL_INTR 0x0200
2597#define ADV_CTRL_REG_DPR_INTR 0x0400
2598#define ADV_CTRL_REG_RTA_INTR 0x0800
2599#define ADV_CTRL_REG_RMA_INTR 0x1000
2600#define ADV_CTRL_REG_RES_BIT14 0x2000
2601#define ADV_CTRL_REG_DPE_INTR 0x4000
2602#define ADV_CTRL_REG_POWER_DONE 0x8000
2603#define ADV_CTRL_REG_ANY_INTR 0xFF00
2604
2605#define ADV_CTRL_REG_CMD_RESET 0x00C6
2606#define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
2607#define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
2608#define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
2609#define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
2610
2611#define ADV_TICKLE_NOP 0x00
2612#define ADV_TICKLE_A 0x01
2613#define ADV_TICKLE_B 0x02
2614#define ADV_TICKLE_C 0x03
2615
2616#define ADV_SCSI_CTRL_RSTOUT 0x2000
2617
2618#define AdvIsIntPending(port) \
2619 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2620
2621/*
2622 * SCSI_CFG0 Register bit definitions
2623 */
2624#define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
2625#define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
2626#define EVEN_PARITY 0x1000 /* Select Even Parity */
2627#define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2628#define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
2629#define PRIM_MODE 0x0100 /* Primitive SCSI mode */
2630#define SCAM_EN 0x0080 /* Enable SCAM selection */
2631#define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2632#define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2633#define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
2634#define OUR_ID 0x000F /* SCSI ID */
2635
2636/*
2637 * SCSI_CFG1 Register bit definitions
2638 */
2639#define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
2640#define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2641#define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
2642#define FILTER_SEL 0x0C00 /* Filter Period Selection */
2643#define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
2644#define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
2645#define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
2646#define ACTIVE_DBL 0x0200 /* Disable Active Negation */
2647#define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
2648#define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
2649#define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
2650#define TERM_CTL 0x0030 /* External SCSI Termination Bits */
2651#define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
2652#define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
2653#define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
2654
2655/*
2656 * Addendum for ASC-38C0800 Chip
2657 *
2658 * The ASC-38C1600 Chip uses the same definitions except that the
2659 * bus mode override bits [12:10] have been moved to byte register
2660 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
2661 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
2662 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
2663 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
2664 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
2665 */
2666#define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
2667#define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
2668#define HVD 0x1000 /* HVD Device Detect */
2669#define LVD 0x0800 /* LVD Device Detect */
2670#define SE 0x0400 /* SE Device Detect */
2671#define TERM_LVD 0x00C0 /* LVD Termination Bits */
2672#define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
2673#define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
2674#define TERM_SE 0x0030 /* SE Termination Bits */
2675#define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
2676#define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
2677#define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
2678#define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
2679#define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
2680#define C_DET_SE 0x0003 /* SE Cable Detect Bits */
2681#define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
2682#define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
2683
2684
2685#define CABLE_ILLEGAL_A 0x7
2686 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
2687
2688#define CABLE_ILLEGAL_B 0xB
2689 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
2690
2691/*
2692 * MEM_CFG Register bit definitions
2693 */
2694#define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
2695#define FAST_EE_CLK 0x20 /* Diagnostic Bit */
2696#define RAM_SZ 0x1C /* Specify size of RAM to RISC */
2697#define RAM_SZ_2KB 0x00 /* 2 KB */
2698#define RAM_SZ_4KB 0x04 /* 4 KB */
2699#define RAM_SZ_8KB 0x08 /* 8 KB */
2700#define RAM_SZ_16KB 0x0C /* 16 KB */
2701#define RAM_SZ_32KB 0x10 /* 32 KB */
2702#define RAM_SZ_64KB 0x14 /* 64 KB */
2703
2704/*
2705 * DMA_CFG0 Register bit definitions
2706 *
2707 * This register is only accessible to the host.
2708 */
2709#define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
2710#define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
2711#define FIFO_THRESH_16B 0x00 /* 16 bytes */
2712#define FIFO_THRESH_32B 0x20 /* 32 bytes */
2713#define FIFO_THRESH_48B 0x30 /* 48 bytes */
2714#define FIFO_THRESH_64B 0x40 /* 64 bytes */
2715#define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
2716#define FIFO_THRESH_96B 0x60 /* 96 bytes */
2717#define FIFO_THRESH_112B 0x70 /* 112 bytes */
2718#define START_CTL 0x0C /* DMA start conditions */
2719#define START_CTL_TH 0x00 /* Wait threshold level (default) */
2720#define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
2721#define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
2722#define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
2723#define READ_CMD 0x03 /* Memory Read Method */
2724#define READ_CMD_MR 0x00 /* Memory Read */
2725#define READ_CMD_MRL 0x02 /* Memory Read Long */
2726#define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
2727
2728/*
2729 * ASC-38C0800 RAM BIST Register bit definitions
2730 */
2731#define RAM_TEST_MODE 0x80
2732#define PRE_TEST_MODE 0x40
2733#define NORMAL_MODE 0x00
2734#define RAM_TEST_DONE 0x10
2735#define RAM_TEST_STATUS 0x0F
2736#define RAM_TEST_HOST_ERROR 0x08
2737#define RAM_TEST_INTRAM_ERROR 0x04
2738#define RAM_TEST_RISC_ERROR 0x02
2739#define RAM_TEST_SCSI_ERROR 0x01
2740#define RAM_TEST_SUCCESS 0x00
2741#define PRE_TEST_VALUE 0x05
2742#define NORMAL_VALUE 0x00
2743
2744/*
2745 * ASC38C1600 Definitions
2746 *
2747 * IOPB_PCI_INT_CFG Bit Field Definitions
2748 */
2749
2750#define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
2751
2752/*
2753 * Bit 1 can be set to change the interrupt for the Function to operate in
2754 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
2755 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
2756 * mode, otherwise the operating mode is undefined.
2757 */
2758#define TOTEMPOLE 0x02
2759
2760/*
2761 * Bit 0 can be used to change the Int Pin for the Function. The value is
2762 * 0 by default for both Functions with Function 0 using INT A and Function
2763 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
2764 * INT A is used.
2765 *
2766 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
2767 * value specified in the PCI Configuration Space.
2768 */
2769#define INTAB 0x01
2770
2771/* a_advlib.h */
2772
2773/*
2774 * Adv Library Status Definitions
2775 */
2776#define ADV_TRUE 1
2777#define ADV_FALSE 0
2778#define ADV_NOERROR 1
2779#define ADV_SUCCESS 1
2780#define ADV_BUSY 0
2781#define ADV_ERROR (-1)
2782
2783
2784/*
2785 * ADV_DVC_VAR 'warn_code' values
2786 */
2787#define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
2788#define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
2789#define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
2790#define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */
2791#define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
2792
2793#define ADV_MAX_TID 15 /* max. target identifier */
2794#define ADV_MAX_LUN 7 /* max. logical unit number */
2795
2796/*
2797 * Error code values are set in ADV_DVC_VAR 'err_code'.
2798 */
2799#define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */
2800#define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
2801#define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */
2802#define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
2803#define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */
2804#define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
2805#define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */
2806#define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
2807#define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
2808#define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */
2809#define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */
2810#define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */
2811#define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */
2812#define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */
2813
2814/*
2815 * Fixed locations of microcode operating variables.
2816 */
2817#define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
2818#define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
2819#define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
2820#define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
2821#define ASC_MC_VERSION_NUM 0x003A /* microcode number */
2822#define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
2823#define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
2824#define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
2825#define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
2826#define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
2827#define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
2828#define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
2829#define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
2830#define ASC_MC_CHIP_TYPE 0x009A
2831#define ASC_MC_INTRB_CODE 0x009B
2832#define ASC_MC_WDTR_ABLE 0x009C
2833#define ASC_MC_SDTR_ABLE 0x009E
2834#define ASC_MC_TAGQNG_ABLE 0x00A0
2835#define ASC_MC_DISC_ENABLE 0x00A2
2836#define ASC_MC_IDLE_CMD_STATUS 0x00A4
2837#define ASC_MC_IDLE_CMD 0x00A6
2838#define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
2839#define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
2840#define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
2841#define ASC_MC_DEFAULT_MEM_CFG 0x00B0
2842#define ASC_MC_DEFAULT_SEL_MASK 0x00B2
2843#define ASC_MC_SDTR_DONE 0x00B6
2844#define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
2845#define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
2846#define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
2847#define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
2848#define ASC_MC_WDTR_DONE 0x0124
2849#define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
2850#define ASC_MC_ICQ 0x0160
2851#define ASC_MC_IRQ 0x0164
2852#define ASC_MC_PPR_ABLE 0x017A
2853
2854/*
2855 * BIOS LRAM variable absolute offsets.
2856 */
2857#define BIOS_CODESEG 0x54
2858#define BIOS_CODELEN 0x56
2859#define BIOS_SIGNATURE 0x58
2860#define BIOS_VERSION 0x5A
2861
2862/*
2863 * Microcode Control Flags
2864 *
2865 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2866 * and handled by the microcode.
2867 */
2868#define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
2869#define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
2870
2871/*
2872 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2873 */
2874#define HSHK_CFG_WIDE_XFR 0x8000
2875#define HSHK_CFG_RATE 0x0F00
2876#define HSHK_CFG_OFFSET 0x001F
2877
2878#define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
2879#define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
2880#define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
2881#define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
2882
2883#define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2884#define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
2885#define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2886#define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
2887#define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2888
2889#define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
2890#define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
2891#define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
2892#define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
2893#define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
2894/*
2895 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
2896 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
2897 */
2898#define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
2899#define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
2900
2901/*
2902 * All fields here are accessed by the board microcode and need to be
2903 * little-endian.
2904 */
2905typedef struct adv_carr_t
2906{
2907 ADV_VADDR carr_va; /* Carrier Virtual Address */
2908 ADV_PADDR carr_pa; /* Carrier Physical Address */
2909 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
2910 /*
2911 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
2912 *
2913 * next_vpa [3:1] Reserved Bits
2914 * next_vpa [0] Done Flag set in Response Queue.
2915 */
2916 ADV_VADDR next_vpa;
2917} ADV_CARR_T;
2918
2919/*
2920 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2921 */
2922#define ASC_NEXT_VPA_MASK 0xFFFFFFF0
2923
2924#define ASC_RQ_DONE 0x00000001
2925#define ASC_RQ_GOOD 0x00000002
2926#define ASC_CQ_STOPPER 0x00000000
2927
2928#define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2929
2930#define ADV_CARRIER_NUM_PAGE_CROSSING \
2931 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2932 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2933
2934#define ADV_CARRIER_BUFSIZE \
2935 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2936
2937/*
2938 * ASC_SCSI_REQ_Q 'a_flag' definitions
2939 *
2940 * The Adv Library should limit use to the lower nibble (4 bits) of
2941 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2942 */
2943#define ADV_POLL_REQUEST 0x01 /* poll for request completion */
2944#define ADV_SCSIQ_DONE 0x02 /* request done */
2945#define ADV_DONT_RETRY 0x08 /* don't do retry */
2946
2947#define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
2948#define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
2949#define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
2950
2951/*
2952 * Adapter temporary configuration structure
2953 *
2954 * This structure can be discarded after initialization. Don't add
2955 * fields here needed after initialization.
2956 *
2957 * Field naming convention:
2958 *
2959 * *_enable indicates the field enables or disables a feature. The
2960 * value of the field is never reset.
2961 */
2962typedef struct adv_dvc_cfg {
2963 ushort disc_enable; /* enable disconnection */
2964 uchar chip_version; /* chip version */
2965 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2966 ushort lib_version; /* Adv Library version number */
2967 ushort control_flag; /* Microcode Control Flag */
2968 ushort mcode_date; /* Microcode date */
2969 ushort mcode_version; /* Microcode version */
2970 ushort pci_slot_info; /* high byte device/function number */
2971 /* bits 7-3 device num., bits 2-0 function num. */
2972 /* low byte bus num. */
2973 ushort serial1; /* EEPROM serial number word 1 */
2974 ushort serial2; /* EEPROM serial number word 2 */
2975 ushort serial3; /* EEPROM serial number word 3 */
2976 struct device *dev; /* pointer to the pci dev structure for this board */
2977} ADV_DVC_CFG;
2978
2979struct adv_dvc_var;
2980struct adv_scsi_req_q;
2981
2982typedef void (* ADV_ISR_CALLBACK)
2983 (struct adv_dvc_var *, struct adv_scsi_req_q *);
2984
2985typedef void (* ADV_ASYNC_CALLBACK)
2986 (struct adv_dvc_var *, uchar);
2987
2988/*
2989 * Adapter operation variable structure.
2990 *
2991 * One structure is required per host adapter.
2992 *
2993 * Field naming convention:
2994 *
2995 * *_able indicates both whether a feature should be enabled or disabled
2996 * and whether a device isi capable of the feature. At initialization
2997 * this field may be set, but later if a device is found to be incapable
2998 * of the feature, the field is cleared.
2999 */
3000typedef struct adv_dvc_var {
3001 AdvPortAddr iop_base; /* I/O port address */
3002 ushort err_code; /* fatal error code */
3003 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
3004 ADV_ISR_CALLBACK isr_callback;
3005 ADV_ASYNC_CALLBACK async_callback;
3006 ushort wdtr_able; /* try WDTR for a device */
3007 ushort sdtr_able; /* try SDTR for a device */
3008 ushort ultra_able; /* try SDTR Ultra speed for a device */
3009 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
3010 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
3011 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
3012 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
3013 ushort tagqng_able; /* try tagged queuing with a device */
3014 ushort ppr_able; /* PPR message capable per TID bitmask. */
3015 uchar max_dvc_qng; /* maximum number of tagged commands per device */
3016 ushort start_motor; /* start motor command allowed */
3017 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
3018 uchar chip_no; /* should be assigned by caller */
3019 uchar max_host_qng; /* maximum number of Q'ed command allowed */
3020 uchar irq_no; /* IRQ number */
3021 ushort no_scam; /* scam_tolerant of EEPROM */
3022 struct asc_board *drv_ptr; /* driver pointer to private structure */
3023 uchar chip_scsi_id; /* chip SCSI target ID */
3024 uchar chip_type;
3025 uchar bist_err_code;
3026 ADV_CARR_T *carrier_buf;
3027 ADV_CARR_T *carr_freelist; /* Carrier free list. */
3028 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
3029 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
3030 ushort carr_pending_cnt; /* Count of pending carriers. */
3031 /*
3032 * Note: The following fields will not be used after initialization. The
3033 * driver may discard the buffer after initialization is done.
3034 */
3035 ADV_DVC_CFG *cfg; /* temporary configuration structure */
3036} ADV_DVC_VAR;
3037
3038#define NO_OF_SG_PER_BLOCK 15
3039
3040typedef struct asc_sg_block {
3041 uchar reserved1;
3042 uchar reserved2;
3043 uchar reserved3;
3044 uchar sg_cnt; /* Valid entries in block. */
3045 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
3046 struct {
3047 ADV_PADDR sg_addr; /* SG element address. */
3048 ADV_DCNT sg_count; /* SG element count. */
3049 } sg_list[NO_OF_SG_PER_BLOCK];
3050} ADV_SG_BLOCK;
3051
3052/*
3053 * ADV_SCSI_REQ_Q - microcode request structure
3054 *
3055 * All fields in this structure up to byte 60 are used by the microcode.
3056 * The microcode makes assumptions about the size and ordering of fields
3057 * in this structure. Do not change the structure definition here without
3058 * coordinating the change with the microcode.
3059 *
3060 * All fields accessed by microcode must be maintained in little_endian
3061 * order.
3062 */
3063typedef struct adv_scsi_req_q {
3064 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
3065 uchar target_cmd;
3066 uchar target_id; /* Device target identifier. */
3067 uchar target_lun; /* Device target logical unit number. */
3068 ADV_PADDR data_addr; /* Data buffer physical address. */
3069 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
3070 ADV_PADDR sense_addr;
3071 ADV_PADDR carr_pa;
3072 uchar mflag;
3073 uchar sense_len;
3074 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
3075 uchar scsi_cntl;
3076 uchar done_status; /* Completion status. */
3077 uchar scsi_status; /* SCSI status byte. */
3078 uchar host_status; /* Ucode host status. */
3079 uchar sg_working_ix;
3080 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
3081 ADV_PADDR sg_real_addr; /* SG list physical address. */
3082 ADV_PADDR scsiq_rptr;
3083 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
3084 ADV_VADDR scsiq_ptr;
3085 ADV_VADDR carr_va;
3086 /*
3087 * End of microcode structure - 60 bytes. The rest of the structure
3088 * is used by the Adv Library and ignored by the microcode.
3089 */
3090 ADV_VADDR srb_ptr;
3091 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
3092 char *vdata_addr; /* Data buffer virtual address. */
3093 uchar a_flag;
3094 uchar pad[2]; /* Pad out to a word boundary. */
3095} ADV_SCSI_REQ_Q;
3096
3097/*
3098 * Microcode idle loop commands
3099 */
3100#define IDLE_CMD_COMPLETED 0
3101#define IDLE_CMD_STOP_CHIP 0x0001
3102#define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
3103#define IDLE_CMD_SEND_INT 0x0004
3104#define IDLE_CMD_ABORT 0x0008
3105#define IDLE_CMD_DEVICE_RESET 0x0010
3106#define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
3107#define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
3108#define IDLE_CMD_SCSIREQ 0x0080
3109
3110#define IDLE_CMD_STATUS_SUCCESS 0x0001
3111#define IDLE_CMD_STATUS_FAILURE 0x0002
3112
3113/*
3114 * AdvSendIdleCmd() flag definitions.
3115 */
3116#define ADV_NOWAIT 0x01
3117
3118/*
3119 * Wait loop time out values.
3120 */
3121#define SCSI_WAIT_10_SEC 10UL /* 10 seconds */
3122#define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
3123#define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
3124#define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */
3125#define SCSI_MAX_RETRY 10 /* retry count */
3126
3127#define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
3128#define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
3129#define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
3130#define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
3131
3132
3133#define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
3134
3135/*
3136 * Device drivers must define the following functions.
3137 */
3138STATIC inline ulong DvcEnterCritical(void);
3139STATIC inline void DvcLeaveCritical(ulong);
3140STATIC void DvcSleepMilliSecond(ADV_DCNT);
3141STATIC uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
3142STATIC void DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
3143STATIC ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
3144 uchar *, ASC_SDCNT *, int);
3145STATIC void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
3146
3147/*
3148 * Adv Library functions available to drivers.
3149 */
3150STATIC int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3151STATIC int AdvISR(ADV_DVC_VAR *);
3152STATIC int AdvInitGetConfig(ADV_DVC_VAR *);
3153STATIC int AdvInitAsc3550Driver(ADV_DVC_VAR *);
3154STATIC int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
3155STATIC int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
3156STATIC int AdvResetChipAndSB(ADV_DVC_VAR *);
3157STATIC int AdvResetSB(ADV_DVC_VAR *asc_dvc);
3158
3159/*
3160 * Internal Adv Library functions.
3161 */
3162STATIC int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
3163STATIC void AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3164STATIC int AdvInitFrom3550EEP(ADV_DVC_VAR *);
3165STATIC int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
3166STATIC int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
3167STATIC ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3168STATIC void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3169STATIC ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3170STATIC void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3171STATIC ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3172STATIC void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3173STATIC void AdvWaitEEPCmd(AdvPortAddr);
3174STATIC ushort AdvReadEEPWord(AdvPortAddr, int);
3175
3176/*
3177 * PCI Bus Definitions
3178 */
3179#define AscPCICmdRegBits_BusMastering 0x0007
3180#define AscPCICmdRegBits_ParErrRespCtrl 0x0040
3181
3182/* Read byte from a register. */
3183#define AdvReadByteRegister(iop_base, reg_off) \
3184 (ADV_MEM_READB((iop_base) + (reg_off)))
3185
3186/* Write byte to a register. */
3187#define AdvWriteByteRegister(iop_base, reg_off, byte) \
3188 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3189
3190/* Read word (2 bytes) from a register. */
3191#define AdvReadWordRegister(iop_base, reg_off) \
3192 (ADV_MEM_READW((iop_base) + (reg_off)))
3193
3194/* Write word (2 bytes) to a register. */
3195#define AdvWriteWordRegister(iop_base, reg_off, word) \
3196 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
3197
3198/* Write dword (4 bytes) to a register. */
3199#define AdvWriteDWordRegister(iop_base, reg_off, dword) \
3200 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
3201
3202/* Read byte from LRAM. */
3203#define AdvReadByteLram(iop_base, addr, byte) \
3204do { \
3205 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3206 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3207} while (0)
3208
3209/* Write byte to LRAM. */
3210#define AdvWriteByteLram(iop_base, addr, byte) \
3211 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3212 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3213
3214/* Read word (2 bytes) from LRAM. */
3215#define AdvReadWordLram(iop_base, addr, word) \
3216do { \
3217 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3218 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3219} while (0)
3220
3221/* Write word (2 bytes) to LRAM. */
3222#define AdvWriteWordLram(iop_base, addr, word) \
3223 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3224 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3225
3226/* Write little-endian double word (4 bytes) to LRAM */
3227/* Because of unspecified C language ordering don't use auto-increment. */
3228#define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
3229 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3230 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3231 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3232 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3233 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3234 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3235
3236/* Read word (2 bytes) from LRAM assuming that the address is already set. */
3237#define AdvReadWordAutoIncLram(iop_base) \
3238 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3239
3240/* Write word (2 bytes) to LRAM assuming that the address is already set. */
3241#define AdvWriteWordAutoIncLram(iop_base, word) \
3242 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3243
3244
3245/*
3246 * Define macro to check for Condor signature.
3247 *
3248 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3249 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3250 */
3251#define AdvFindSignature(iop_base) \
3252 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3253 ADV_CHIP_ID_BYTE) && \
3254 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3255 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
3256
3257/*
3258 * Define macro to Return the version number of the chip at 'iop_base'.
3259 *
3260 * The second parameter 'bus_type' is currently unused.
3261 */
3262#define AdvGetChipVersion(iop_base, bus_type) \
3263 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3264
3265/*
3266 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3267 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3268 *
3269 * If the request has not yet been sent to the device it will simply be
3270 * aborted from RISC memory. If the request is disconnected it will be
3271 * aborted on reselection by sending an Abort Message to the target ID.
3272 *
3273 * Return value:
3274 * ADV_TRUE(1) - Queue was successfully aborted.
3275 * ADV_FALSE(0) - Queue was not found on the active queue list.
3276 */
3277#define AdvAbortQueue(asc_dvc, scsiq) \
3278 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3279 (ADV_DCNT) (scsiq))
3280
3281/*
3282 * Send a Bus Device Reset Message to the specified target ID.
3283 *
3284 * All outstanding commands will be purged if sending the
3285 * Bus Device Reset Message is successful.
3286 *
3287 * Return Value:
3288 * ADV_TRUE(1) - All requests on the target are purged.
3289 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3290 * are not purged.
3291 */
3292#define AdvResetDevice(asc_dvc, target_id) \
3293 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3294 (ADV_DCNT) (target_id))
3295
3296/*
3297 * SCSI Wide Type definition.
3298 */
3299#define ADV_SCSI_BIT_ID_TYPE ushort
3300
3301/*
3302 * AdvInitScsiTarget() 'cntl_flag' options.
3303 */
3304#define ADV_SCAN_LUN 0x01
3305#define ADV_CAPINFO_NOLUN 0x02
3306
3307/*
3308 * Convert target id to target id bit mask.
3309 */
3310#define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
3311
3312/*
3313 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3314 */
3315
3316#define QD_NO_STATUS 0x00 /* Request not completed yet. */
3317#define QD_NO_ERROR 0x01
3318#define QD_ABORTED_BY_HOST 0x02
3319#define QD_WITH_ERROR 0x04
3320
3321#define QHSTA_NO_ERROR 0x00
3322#define QHSTA_M_SEL_TIMEOUT 0x11
3323#define QHSTA_M_DATA_OVER_RUN 0x12
3324#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3325#define QHSTA_M_QUEUE_ABORTED 0x15
3326#define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
3327#define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
3328#define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
3329#define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
3330#define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
3331#define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
3332#define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
3333/* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
3334#define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
3335#define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
3336#define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
3337#define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
3338#define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
3339#define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
3340#define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
3341#define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
3342#define QHSTA_M_WTM_TIMEOUT 0x41
3343#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
3344#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
3345#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
3346#define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
3347#define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
3348#define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
3349
3350
3351/*
3352 * Default EEPROM Configuration structure defined in a_init.c.
3353 */
3354static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
3355static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
3356static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
3357
3358/*
3359 * DvcGetPhyAddr() flag arguments
3360 */
3361#define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
3362#define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
3363#define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
3364#define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
3365#define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
3366#define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
3367
3368/* Return the address that is aligned at the next doubleword >= to 'addr'. */
3369#define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
3370#define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
3371#define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
3372
3373/*
3374 * Total contiguous memory needed for driver SG blocks.
3375 *
3376 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3377 * number of scatter-gather elements the driver supports in a
3378 * single request.
3379 */
3380
3381#define ADV_SG_LIST_MAX_BYTE_SIZE \
3382 (sizeof(ADV_SG_BLOCK) * \
3383 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3384
3385/*
3386 * Inquiry data structure and bitfield macros
3387 *
3388 * Using bitfields to access the subchar data isn't portable across
3389 * endianness, so instead mask and shift. Only quantities of more
3390 * than 1 bit are shifted, since the others are just tested for true
3391 * or false.
3392 */
3393
3394#define ADV_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f)
3395#define ADV_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5)
3396#define ADV_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f)
3397#define ADV_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80)
3398#define ADV_INQ_ANSI_VER(inq) ((inq)->ver & 0x07)
3399#define ADV_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3)
3400#define ADV_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6)
3401#define ADV_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f)
3402#define ADV_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40)
3403#define ADV_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80)
3404#define ADV_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01)
3405#define ADV_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02)
3406#define ADV_INQ_LINK_CMD(inq) ((inq)->flags & 0x08)
3407#define ADV_INQ_SYNC(inq) ((inq)->flags & 0x10)
3408#define ADV_INQ_WIDE16(inq) ((inq)->flags & 0x20)
3409#define ADV_INQ_WIDE32(inq) ((inq)->flags & 0x40)
3410#define ADV_INQ_REL_ADDR(inq) ((inq)->flags & 0x80)
3411#define ADV_INQ_INFO_UNIT(inq) ((inq)->info & 0x01)
3412#define ADV_INQ_QUICK_ARB(inq) ((inq)->info & 0x02)
3413#define ADV_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2)
3414
3415typedef struct {
3416 uchar periph; /* peripheral device type [0:4] */
3417 /* peripheral qualifier [5:7] */
3418 uchar devtype; /* device type modifier (for SCSI I) [0:6] */
3419 /* RMB - removable medium bit [7] */
3420 uchar ver; /* ANSI approved version [0:2] */
3421 /* ECMA version [3:5] */
3422 /* ISO version [6:7] */
3423 uchar byte3; /* response data format [0:3] */
3424 /* 0 SCSI 1 */
3425 /* 1 CCS */
3426 /* 2 SCSI-2 */
3427 /* 3-F reserved */
3428 /* reserved [4:5] */
3429 /* terminate I/O process bit (see 5.6.22) [6] */
3430 /* asynch. event notification (processor) [7] */
3431 uchar add_len; /* additional length */
3432 uchar res1; /* reserved */
3433 uchar res2; /* reserved */
3434 uchar flags; /* soft reset implemented [0] */
3435 /* command queuing [1] */
3436 /* reserved [2] */
3437 /* linked command for this logical unit [3] */
3438 /* synchronous data transfer [4] */
3439 /* wide bus 16 bit data transfer [5] */
3440 /* wide bus 32 bit data transfer [6] */
3441 /* relative addressing mode [7] */
3442 uchar vendor_id[8]; /* vendor identification */
3443 uchar product_id[16]; /* product identification */
3444 uchar product_rev_level[4]; /* product revision level */
3445 uchar vendor_specific[20]; /* vendor specific */
3446 uchar info; /* information unit supported [0] */
3447 /* quick arbitrate supported [1] */
3448 /* clocking field [2:3] */
3449 /* reserved [4:7] */
3450 uchar res3; /* reserved */
3451} ADV_SCSI_INQUIRY; /* 58 bytes */
3452
3453
3454/*
3455 * --- Driver Constants and Macros
3456 */
3457
3458#define ASC_NUM_BOARD_SUPPORTED 16
3459#define ASC_NUM_IOPORT_PROBE 4
3460#define ASC_NUM_BUS 4
3461
3462/* Reference Scsi_Host hostdata */
3463#define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3464
3465/* asc_board_t flags */
3466#define ASC_HOST_IN_RESET 0x01
3467#define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
3468#define ASC_SELECT_QUEUE_DEPTHS 0x08
3469
3470#define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3471#define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD)
3472
3473#define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
3474
3475#define ASC_INFO_SIZE 128 /* advansys_info() line size */
3476
3477#ifdef CONFIG_PROC_FS
3478/* /proc/scsi/advansys/[0...] related definitions */
3479#define ASC_PRTBUF_SIZE 2048
3480#define ASC_PRTLINE_SIZE 160
3481
3482#define ASC_PRT_NEXT() \
3483 if (cp) { \
3484 totlen += len; \
3485 leftlen -= len; \
3486 if (leftlen == 0) { \
3487 return totlen; \
3488 } \
3489 cp += len; \
3490 }
3491#endif /* CONFIG_PROC_FS */
3492
3493/* Asc Library return codes */
3494#define ASC_TRUE 1
3495#define ASC_FALSE 0
3496#define ASC_NOERROR 1
3497#define ASC_BUSY 0
3498#define ASC_ERROR (-1)
3499
3500/* struct scsi_cmnd function return codes */
3501#define STATUS_BYTE(byte) (byte)
3502#define MSG_BYTE(byte) ((byte) << 8)
3503#define HOST_BYTE(byte) ((byte) << 16)
3504#define DRIVER_BYTE(byte) ((byte) << 24)
3505
3506/*
3507 * The following definitions and macros are OS independent interfaces to
3508 * the queue functions:
3509 * REQ - SCSI request structure
3510 * REQP - pointer to SCSI request structure
3511 * REQPTID(reqp) - reqp's target id
3512 * REQPNEXT(reqp) - reqp's next pointer
3513 * REQPNEXTP(reqp) - pointer to reqp's next pointer
3514 * REQPTIME(reqp) - reqp's time stamp value
3515 * REQTIMESTAMP() - system time stamp value
3516 */
3517typedef struct scsi_cmnd REQ, *REQP;
3518#define REQPNEXT(reqp) ((REQP) ((reqp)->host_scribble))
3519#define REQPNEXTP(reqp) ((REQP *) &((reqp)->host_scribble))
3520#define REQPTID(reqp) ((reqp)->device->id)
3521#define REQPTIME(reqp) ((reqp)->SCp.this_residual)
3522#define REQTIMESTAMP() (jiffies)
3523
3524#define REQTIMESTAT(function, ascq, reqp, tid) \
3525{ \
3526 /*
3527 * If the request time stamp is less than the system time stamp, then \
3528 * maybe the system time stamp wrapped. Set the request time to zero.\
3529 */ \
3530 if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3531 REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3532 } else { \
3533 /* Indicate an error occurred with the assertion. */ \
3534 ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3535 REQPTIME(reqp) = 0; \
3536 } \
3537 /* Handle first minimum time case without external initialization. */ \
3538 if (((ascq)->q_tot_cnt[tid] == 1) || \
3539 (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3540 (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3541 ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3542 (function), (tid), (ascq)->q_min_tim[tid]); \
3543 } \
3544 if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3545 (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3546 ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3547 (function), tid, (ascq)->q_max_tim[tid]); \
3548 } \
3549 (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3550 /* Reset the time stamp field. */ \
3551 REQPTIME(reqp) = 0; \
3552}
3553
3554/* asc_enqueue() flags */
3555#define ASC_FRONT 1
3556#define ASC_BACK 2
3557
3558/* asc_dequeue_list() argument */
3559#define ASC_TID_ALL (-1)
3560
3561/* Return non-zero, if the queue is empty. */
3562#define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0)
3563
3564#define PCI_MAX_SLOT 0x1F
3565#define PCI_MAX_BUS 0xFF
3566#define PCI_IOADDRESS_MASK 0xFFFE
1da177e4 3567#define ASC_PCI_DEVICE_ID_CNT 6 /* PCI Device ID count. */
1da177e4
LT
3568
3569#ifndef ADVANSYS_STATS
3570#define ASC_STATS(shp, counter)
3571#define ASC_STATS_ADD(shp, counter, count)
3572#else /* ADVANSYS_STATS */
3573#define ASC_STATS(shp, counter) \
3574 (ASC_BOARDP(shp)->asc_stats.counter++)
3575
3576#define ASC_STATS_ADD(shp, counter, count) \
3577 (ASC_BOARDP(shp)->asc_stats.counter += (count))
3578#endif /* ADVANSYS_STATS */
3579
3580#define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3581
3582/* If the result wraps when calculating tenths, return 0. */
3583#define ASC_TENTHS(num, den) \
3584 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3585 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3586
3587/*
3588 * Display a message to the console.
3589 */
3590#define ASC_PRINT(s) \
3591 { \
3592 printk("advansys: "); \
3593 printk(s); \
3594 }
3595
3596#define ASC_PRINT1(s, a1) \
3597 { \
3598 printk("advansys: "); \
3599 printk((s), (a1)); \
3600 }
3601
3602#define ASC_PRINT2(s, a1, a2) \
3603 { \
3604 printk("advansys: "); \
3605 printk((s), (a1), (a2)); \
3606 }
3607
3608#define ASC_PRINT3(s, a1, a2, a3) \
3609 { \
3610 printk("advansys: "); \
3611 printk((s), (a1), (a2), (a3)); \
3612 }
3613
3614#define ASC_PRINT4(s, a1, a2, a3, a4) \
3615 { \
3616 printk("advansys: "); \
3617 printk((s), (a1), (a2), (a3), (a4)); \
3618 }
3619
3620
3621#ifndef ADVANSYS_DEBUG
3622
3623#define ASC_DBG(lvl, s)
3624#define ASC_DBG1(lvl, s, a1)
3625#define ASC_DBG2(lvl, s, a1, a2)
3626#define ASC_DBG3(lvl, s, a1, a2, a3)
3627#define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3628#define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3629#define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3630#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3631#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3632#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3633#define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3634#define ASC_DBG_PRT_HEX(lvl, name, start, length)
3635#define ASC_DBG_PRT_CDB(lvl, cdb, len)
3636#define ASC_DBG_PRT_SENSE(lvl, sense, len)
3637#define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3638
3639#else /* ADVANSYS_DEBUG */
3640
3641/*
3642 * Debugging Message Levels:
3643 * 0: Errors Only
3644 * 1: High-Level Tracing
3645 * 2-N: Verbose Tracing
3646 */
3647
3648#define ASC_DBG(lvl, s) \
3649 { \
3650 if (asc_dbglvl >= (lvl)) { \
3651 printk(s); \
3652 } \
3653 }
3654
3655#define ASC_DBG1(lvl, s, a1) \
3656 { \
3657 if (asc_dbglvl >= (lvl)) { \
3658 printk((s), (a1)); \
3659 } \
3660 }
3661
3662#define ASC_DBG2(lvl, s, a1, a2) \
3663 { \
3664 if (asc_dbglvl >= (lvl)) { \
3665 printk((s), (a1), (a2)); \
3666 } \
3667 }
3668
3669#define ASC_DBG3(lvl, s, a1, a2, a3) \
3670 { \
3671 if (asc_dbglvl >= (lvl)) { \
3672 printk((s), (a1), (a2), (a3)); \
3673 } \
3674 }
3675
3676#define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3677 { \
3678 if (asc_dbglvl >= (lvl)) { \
3679 printk((s), (a1), (a2), (a3), (a4)); \
3680 } \
3681 }
3682
3683#define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3684 { \
3685 if (asc_dbglvl >= (lvl)) { \
3686 asc_prt_scsi_host(s); \
3687 } \
3688 }
3689
3690#define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3691 { \
3692 if (asc_dbglvl >= (lvl)) { \
3693 asc_prt_scsi_cmnd(s); \
3694 } \
3695 }
3696
3697#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3698 { \
3699 if (asc_dbglvl >= (lvl)) { \
3700 asc_prt_asc_scsi_q(scsiqp); \
3701 } \
3702 }
3703
3704#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3705 { \
3706 if (asc_dbglvl >= (lvl)) { \
3707 asc_prt_asc_qdone_info(qdone); \
3708 } \
3709 }
3710
3711#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3712 { \
3713 if (asc_dbglvl >= (lvl)) { \
3714 asc_prt_adv_scsi_req_q(scsiqp); \
3715 } \
3716 }
3717
3718#define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3719 { \
3720 if (asc_dbglvl >= (lvl)) { \
3721 asc_prt_hex((name), (start), (length)); \
3722 } \
3723 }
3724
3725#define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3726 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3727
3728#define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3729 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3730
3731#define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3732 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3733#endif /* ADVANSYS_DEBUG */
3734
3735#ifndef ADVANSYS_ASSERT
3736#define ASC_ASSERT(a)
3737#else /* ADVANSYS_ASSERT */
3738
3739#define ASC_ASSERT(a) \
3740 { \
3741 if (!(a)) { \
3742 printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3743 __FILE__, __LINE__); \
3744 } \
3745 }
3746
3747#endif /* ADVANSYS_ASSERT */
3748
3749
3750/*
3751 * --- Driver Structures
3752 */
3753
3754#ifdef ADVANSYS_STATS
3755
3756/* Per board statistics structure */
3757struct asc_stats {
3758 /* Driver Entrypoint Statistics */
3759 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
3760 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
3761 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
3762 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
3763 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
3764 ADV_DCNT done; /* # calls to request's scsi_done function */
3765 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
3766 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
3767 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
3768 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3769 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
3770 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
3771 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
3772 ADV_DCNT exe_unknown; /* # unknown returns. */
3773 /* Data Transfer Statistics */
3774 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
3775 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
3776 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
3777 ADV_DCNT sg_elem; /* # scatter-gather elements */
3778 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
3779};
3780#endif /* ADVANSYS_STATS */
3781
3782/*
3783 * Request queuing structure
3784 */
3785typedef struct asc_queue {
3786 ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */
3787 REQP q_first[ADV_MAX_TID+1]; /* first queued request */
3788 REQP q_last[ADV_MAX_TID+1]; /* last queued request */
3789#ifdef ADVANSYS_STATS
3790 short q_cur_cnt[ADV_MAX_TID+1]; /* current queue count */
3791 short q_max_cnt[ADV_MAX_TID+1]; /* maximum queue count */
3792 ADV_DCNT q_tot_cnt[ADV_MAX_TID+1]; /* total enqueue count */
3793 ADV_DCNT q_tot_tim[ADV_MAX_TID+1]; /* total time queued */
3794 ushort q_max_tim[ADV_MAX_TID+1]; /* maximum time queued */
3795 ushort q_min_tim[ADV_MAX_TID+1]; /* minimum time queued */
3796#endif /* ADVANSYS_STATS */
3797} asc_queue_t;
3798
3799/*
3800 * Adv Library Request Structures
3801 *
3802 * The following two structures are used to process Wide Board requests.
3803 *
3804 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
3805 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
3806 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
3807 * Mid-Level SCSI request structure.
3808 *
3809 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
3810 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
3811 * up to 255 scatter-gather elements may be used per request or
3812 * ADV_SCSI_REQ_Q.
3813 *
3814 * Both structures must be 32 byte aligned.
3815 */
3816typedef struct adv_sgblk {
3817 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
3818 uchar align[32]; /* Sgblock structure padding. */
3819 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
3820} adv_sgblk_t;
3821
3822typedef struct adv_req {
3823 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
3824 uchar align[32]; /* Request structure padding. */
3825 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
3826 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
3827 struct adv_req *next_reqp; /* Next Request Structure. */
3828} adv_req_t;
3829
3830/*
3831 * Structure allocated for each board.
3832 *
3833 * This structure is allocated by scsi_register() at the end
3834 * of the 'Scsi_Host' structure starting at the 'hostdata'
3835 * field. It is guaranteed to be allocated from DMA-able memory.
3836 */
3837typedef struct asc_board {
3838 int id; /* Board Id */
3839 uint flags; /* Board flags */
3840 union {
3841 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
3842 ADV_DVC_VAR adv_dvc_var; /* Wide board */
3843 } dvc_var;
3844 union {
3845 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
3846 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
3847 } dvc_cfg;
3848 ushort asc_n_io_port; /* Number I/O ports. */
3849 asc_queue_t active; /* Active command queue */
3850 asc_queue_t waiting; /* Waiting command queue */
3851 asc_queue_t done; /* Done command queue */
3852 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
3853 struct scsi_device *device[ADV_MAX_TID+1]; /* Mid-Level Scsi Device */
3854 ushort reqcnt[ADV_MAX_TID+1]; /* Starvation request count */
3855 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
3856 ushort queue_full_cnt[ADV_MAX_TID+1]; /* Queue full count */
3857 union {
3858 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
3859 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
3860 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
3861 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
3862 } eep_config;
3863 ulong last_reset; /* Saved last reset time */
3864 spinlock_t lock; /* Board spinlock */
3865#ifdef CONFIG_PROC_FS
3866 /* /proc/scsi/advansys/[0...] */
3867 char *prtbuf; /* /proc print buffer */
3868#endif /* CONFIG_PROC_FS */
3869#ifdef ADVANSYS_STATS
3870 struct asc_stats asc_stats; /* Board statistics */
3871#endif /* ADVANSYS_STATS */
3872 /*
3873 * The following fields are used only for Narrow Boards.
3874 */
3875 /* The following three structures must be in DMA-able memory. */
3876 ASC_SCSI_REQ_Q scsireqq;
3877 ASC_CAP_INFO cap_info;
3878 ASC_SCSI_INQUIRY inquiry;
3879 uchar sdtr_data[ASC_MAX_TID+1]; /* SDTR information */
3880 /*
3881 * The following fields are used only for Wide Boards.
3882 */
1e0dbafd 3883 void __iomem *ioremap_addr; /* I/O Memory remap address. */
1da177e4
LT
3884 ushort ioport; /* I/O Port address. */
3885 ADV_CARR_T *orig_carrp; /* ADV_CARR_T memory block. */
3886 adv_req_t *orig_reqp; /* adv_req_t memory block. */
3887 adv_req_t *adv_reqp; /* Request structures. */
3888 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
3889 ushort bios_signature; /* BIOS Signature. */
3890 ushort bios_version; /* BIOS Version. */
3891 ushort bios_codeseg; /* BIOS Code Segment. */
3892 ushort bios_codelen; /* BIOS Code Segment Length. */
3893} asc_board_t;
3894
3895/*
3896 * PCI configuration structures
3897 */
3898typedef struct _PCI_DATA_
3899{
3900 uchar type;
3901 uchar bus;
3902 uchar slot;
3903 uchar func;
3904 uchar offset;
3905} PCI_DATA;
3906
3907typedef struct _PCI_DEVICE_
3908{
3909 ushort vendorID;
3910 ushort deviceID;
3911 ushort slotNumber;
3912 ushort slotFound;
3913 uchar busNumber;
3914 uchar maxBusNumber;
3915 uchar devFunc;
3916 ushort startSlot;
3917 ushort endSlot;
3918 uchar bridge;
3919 uchar type;
3920} PCI_DEVICE;
3921
3922typedef struct _PCI_CONFIG_SPACE_
3923{
3924 ushort vendorID;
3925 ushort deviceID;
3926 ushort command;
3927 ushort status;
3928 uchar revision;
3929 uchar classCode[3];
3930 uchar cacheSize;
3931 uchar latencyTimer;
3932 uchar headerType;
3933 uchar bist;
3934 ADV_PADDR baseAddress[6];
3935 ushort reserved[4];
3936 ADV_PADDR optionRomAddr;
3937 ushort reserved2[4];
3938 uchar irqLine;
3939 uchar irqPin;
3940 uchar minGnt;
3941 uchar maxLatency;
3942} PCI_CONFIG_SPACE;
3943
3944
3945/*
3946 * --- Driver Data
3947 */
3948
3949/* Note: All driver global data should be initialized. */
3950
3951/* Number of boards detected in system. */
3952STATIC int asc_board_count = 0;
aa7677d4 3953STATIC struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { NULL };
1da177e4
LT
3954
3955/* Overrun buffer used by all narrow boards. */
3956STATIC uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
3957
3958/*
3959 * Global structures required to issue a command.
3960 */
3961STATIC ASC_SCSI_Q asc_scsi_q = { { 0 } };
3962STATIC ASC_SG_HEAD asc_sg_head = { 0 };
3963
3964/* List of supported bus types. */
3965STATIC ushort asc_bus[ASC_NUM_BUS] __initdata = {
3966 ASC_IS_ISA,
3967 ASC_IS_VL,
3968 ASC_IS_EISA,
3969 ASC_IS_PCI,
3970};
3971
1da177e4
LT
3972STATIC int asc_iopflag = ASC_FALSE;
3973STATIC int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
3974
3975#ifdef ADVANSYS_DEBUG
3976STATIC char *
3977asc_bus_name[ASC_NUM_BUS] = {
3978 "ASC_IS_ISA",
3979 "ASC_IS_VL",
3980 "ASC_IS_EISA",
3981 "ASC_IS_PCI",
3982};
3983
3984STATIC int asc_dbglvl = 3;
3985#endif /* ADVANSYS_DEBUG */
3986
3987/* Declaration for Asc Library internal data referenced by driver. */
3988STATIC PortAddr _asc_def_iop_base[];
3989
3990
3991/*
3992 * --- Driver Function Prototypes
3993 *
3994 * advansys.h contains function prototypes for functions global to Linux.
3995 */
3996
7d12e780 3997STATIC irqreturn_t advansys_interrupt(int, void *);
1da177e4
LT
3998STATIC int advansys_slave_configure(struct scsi_device *);
3999STATIC void asc_scsi_done_list(struct scsi_cmnd *);
4000STATIC int asc_execute_scsi_cmnd(struct scsi_cmnd *);
4001STATIC int asc_build_req(asc_board_t *, struct scsi_cmnd *);
4002STATIC int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
4003STATIC int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
4004STATIC void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
4005STATIC void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
4006STATIC void adv_async_callback(ADV_DVC_VAR *, uchar);
4007STATIC void asc_enqueue(asc_queue_t *, REQP, int);
4008STATIC REQP asc_dequeue(asc_queue_t *, int);
4009STATIC REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
4010STATIC int asc_rmqueue(asc_queue_t *, REQP);
4011STATIC void asc_execute_queue(asc_queue_t *);
4012#ifdef CONFIG_PROC_FS
4013STATIC int asc_proc_copy(off_t, off_t, char *, int , char *, int);
4014STATIC int asc_prt_board_devices(struct Scsi_Host *, char *, int);
4015STATIC int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
4016STATIC int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
4017STATIC int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
4018STATIC int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
4019STATIC int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
4020STATIC int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
4021STATIC int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
4022STATIC int asc_prt_line(char *, int, char *fmt, ...);
4023#endif /* CONFIG_PROC_FS */
4024
4025/* Declaration for Asc Library internal functions referenced by driver. */
4026STATIC int AscFindSignature(PortAddr);
4027STATIC ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
4028
4029/* Statistics function prototypes. */
4030#ifdef ADVANSYS_STATS
4031#ifdef CONFIG_PROC_FS
4032STATIC int asc_prt_board_stats(struct Scsi_Host *, char *, int);
4033STATIC int asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
4034#endif /* CONFIG_PROC_FS */
4035#endif /* ADVANSYS_STATS */
4036
4037/* Debug function prototypes. */
4038#ifdef ADVANSYS_DEBUG
4039STATIC void asc_prt_scsi_host(struct Scsi_Host *);
4040STATIC void asc_prt_scsi_cmnd(struct scsi_cmnd *);
4041STATIC void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
4042STATIC void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
4043STATIC void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
4044STATIC void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
4045STATIC void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
4046STATIC void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
4047STATIC void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
4048STATIC void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
4049STATIC void asc_prt_hex(char *f, uchar *, int);
4050#endif /* ADVANSYS_DEBUG */
4051
4052
1da177e4
LT
4053#ifdef CONFIG_PROC_FS
4054/*
4055 * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
4056 *
4057 * *buffer: I/O buffer
4058 * **start: if inout == FALSE pointer into buffer where user read should start
4059 * offset: current offset into a /proc/scsi/advansys/[0...] file
4060 * length: length of buffer
4061 * hostno: Scsi_Host host_no
4062 * inout: TRUE - user is writing; FALSE - user is reading
4063 *
4064 * Return the number of bytes read from or written to a
4065 * /proc/scsi/advansys/[0...] file.
4066 *
4067 * Note: This function uses the per board buffer 'prtbuf' which is
4068 * allocated when the board is initialized in advansys_detect(). The
4069 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
4070 * used to write to the buffer. The way asc_proc_copy() is written
4071 * if 'prtbuf' is too small it will not be overwritten. Instead the
4072 * user just won't get all the available statistics.
4073 */
70c8d897 4074static int
1da177e4
LT
4075advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
4076 off_t offset, int length, int inout)
4077{
4078 struct Scsi_Host *shp;
4079 asc_board_t *boardp;
4080 int i;
4081 char *cp;
4082 int cplen;
4083 int cnt;
4084 int totcnt;
4085 int leftlen;
4086 char *curbuf;
4087 off_t advoffset;
4088#ifdef ADVANSYS_STATS
4089 int tgt_id;
4090#endif /* ADVANSYS_STATS */
4091
4092 ASC_DBG(1, "advansys_proc_info: begin\n");
4093
4094 /*
4095 * User write not supported.
4096 */
4097 if (inout == TRUE) {
4098 return(-ENOSYS);
4099 }
4100
4101 /*
4102 * User read of /proc/scsi/advansys/[0...] file.
4103 */
4104
4105 /* Find the specified board. */
4106 for (i = 0; i < asc_board_count; i++) {
4107 if (asc_host[i]->host_no == shost->host_no) {
4108 break;
4109 }
4110 }
4111 if (i == asc_board_count) {
4112 return(-ENOENT);
4113 }
4114
4115 shp = asc_host[i];
4116 boardp = ASC_BOARDP(shp);
4117
4118 /* Copy read data starting at the beginning of the buffer. */
4119 *start = buffer;
4120 curbuf = buffer;
4121 advoffset = 0;
4122 totcnt = 0;
4123 leftlen = length;
4124
4125 /*
4126 * Get board configuration information.
4127 *
4128 * advansys_info() returns the board string from its own static buffer.
4129 */
4130 cp = (char *) advansys_info(shp);
4131 strcat(cp, "\n");
4132 cplen = strlen(cp);
4133 /* Copy board information. */
4134 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4135 totcnt += cnt;
4136 leftlen -= cnt;
4137 if (leftlen == 0) {
4138 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4139 return totcnt;
4140 }
4141 advoffset += cplen;
4142 curbuf += cnt;
4143
4144 /*
4145 * Display Wide Board BIOS Information.
4146 */
4147 if (ASC_WIDE_BOARD(boardp)) {
4148 cp = boardp->prtbuf;
4149 cplen = asc_prt_adv_bios(shp, cp, ASC_PRTBUF_SIZE);
4150 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4151 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4152 totcnt += cnt;
4153 leftlen -= cnt;
4154 if (leftlen == 0) {
4155 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4156 return totcnt;
4157 }
4158 advoffset += cplen;
4159 curbuf += cnt;
4160 }
4161
4162 /*
4163 * Display driver information for each device attached to the board.
4164 */
4165 cp = boardp->prtbuf;
4166 cplen = asc_prt_board_devices(shp, cp, ASC_PRTBUF_SIZE);
4167 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4168 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4169 totcnt += cnt;
4170 leftlen -= cnt;
4171 if (leftlen == 0) {
4172 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4173 return totcnt;
4174 }
4175 advoffset += cplen;
4176 curbuf += cnt;
4177
4178 /*
4179 * Display EEPROM configuration for the board.
4180 */
4181 cp = boardp->prtbuf;
4182 if (ASC_NARROW_BOARD(boardp)) {
4183 cplen = asc_prt_asc_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4184 } else {
4185 cplen = asc_prt_adv_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4186 }
4187 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4188 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4189 totcnt += cnt;
4190 leftlen -= cnt;
4191 if (leftlen == 0) {
4192 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4193 return totcnt;
4194 }
4195 advoffset += cplen;
4196 curbuf += cnt;
4197
4198 /*
4199 * Display driver configuration and information for the board.
4200 */
4201 cp = boardp->prtbuf;
4202 cplen = asc_prt_driver_conf(shp, cp, ASC_PRTBUF_SIZE);
4203 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4204 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4205 totcnt += cnt;
4206 leftlen -= cnt;
4207 if (leftlen == 0) {
4208 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4209 return totcnt;
4210 }
4211 advoffset += cplen;
4212 curbuf += cnt;
4213
4214#ifdef ADVANSYS_STATS
4215 /*
4216 * Display driver statistics for the board.
4217 */
4218 cp = boardp->prtbuf;
4219 cplen = asc_prt_board_stats(shp, cp, ASC_PRTBUF_SIZE);
4220 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4221 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4222 totcnt += cnt;
4223 leftlen -= cnt;
4224 if (leftlen == 0) {
4225 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4226 return totcnt;
4227 }
4228 advoffset += cplen;
4229 curbuf += cnt;
4230
4231 /*
4232 * Display driver statistics for each target.
4233 */
4234 for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
4235 cp = boardp->prtbuf;
4236 cplen = asc_prt_target_stats(shp, tgt_id, cp, ASC_PRTBUF_SIZE);
4237 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4238 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4239 totcnt += cnt;
4240 leftlen -= cnt;
4241 if (leftlen == 0) {
4242 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4243 return totcnt;
4244 }
4245 advoffset += cplen;
4246 curbuf += cnt;
4247 }
4248#endif /* ADVANSYS_STATS */
4249
4250 /*
4251 * Display Asc Library dynamic configuration information
4252 * for the board.
4253 */
4254 cp = boardp->prtbuf;
4255 if (ASC_NARROW_BOARD(boardp)) {
4256 cplen = asc_prt_asc_board_info(shp, cp, ASC_PRTBUF_SIZE);
4257 } else {
4258 cplen = asc_prt_adv_board_info(shp, cp, ASC_PRTBUF_SIZE);
4259 }
4260 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4261 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4262 totcnt += cnt;
4263 leftlen -= cnt;
4264 if (leftlen == 0) {
4265 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4266 return totcnt;
4267 }
4268 advoffset += cplen;
4269 curbuf += cnt;
4270
4271 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4272
4273 return totcnt;
4274}
4275#endif /* CONFIG_PROC_FS */
4276
4277/*
4278 * advansys_detect()
4279 *
4280 * Detect function for AdvanSys adapters.
4281 *
4282 * Argument is a pointer to the host driver's scsi_hosts entry.
4283 *
4284 * Return number of adapters found.
4285 *
4286 * Note: Because this function is called during system initialization
4287 * it must not call SCSI mid-level functions including scsi_malloc()
4288 * and scsi_free().
4289 */
70c8d897 4290static int __init
1da177e4
LT
4291advansys_detect(struct scsi_host_template *tpnt)
4292{
4293 static int detect_called = ASC_FALSE;
4294 int iop;
4295 int bus;
4296 struct Scsi_Host *shp = NULL;
4297 asc_board_t *boardp = NULL;
4298 ASC_DVC_VAR *asc_dvc_varp = NULL;
4299 ADV_DVC_VAR *adv_dvc_varp = NULL;
4300 adv_sgblk_t *sgp = NULL;
4301 int ioport = 0;
4302 int share_irq = FALSE;
4303 int iolen = 0;
4304 struct device *dev = NULL;
4305#ifdef CONFIG_PCI
4306 int pci_init_search = 0;
4307 struct pci_dev *pci_devicep[ASC_NUM_BOARD_SUPPORTED];
4308 int pci_card_cnt_max = 0;
4309 int pci_card_cnt = 0;
4310 struct pci_dev *pci_devp = NULL;
4311 int pci_device_id_cnt = 0;
4312 unsigned int pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
2672ea86
DJ
4313 PCI_DEVICE_ID_ASP_1200A,
4314 PCI_DEVICE_ID_ASP_ABP940,
4315 PCI_DEVICE_ID_ASP_ABP940U,
4316 PCI_DEVICE_ID_ASP_ABP940UW,
4317 PCI_DEVICE_ID_38C0800_REV1,
4318 PCI_DEVICE_ID_38C1600_REV1
1da177e4
LT
4319 };
4320 ADV_PADDR pci_memory_address;
4321#endif /* CONFIG_PCI */
4322 int warn_code, err_code;
4323 int ret;
4324
4325 if (detect_called == ASC_FALSE) {
4326 detect_called = ASC_TRUE;
4327 } else {
4328 printk("AdvanSys SCSI: advansys_detect() multiple calls ignored\n");
4329 return 0;
4330 }
4331
4332 ASC_DBG(1, "advansys_detect: begin\n");
4333
4334 asc_board_count = 0;
4335
4336 /*
4337 * If I/O port probing has been modified, then verify and
4338 * clean-up the 'asc_ioport' list.
4339 */
4340 if (asc_iopflag == ASC_TRUE) {
4341 for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
4342 ASC_DBG2(1, "advansys_detect: asc_ioport[%d] 0x%x\n",
4343 ioport, asc_ioport[ioport]);
4344 if (asc_ioport[ioport] != 0) {
4345 for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX; iop++) {
4346 if (_asc_def_iop_base[iop] == asc_ioport[ioport]) {
4347 break;
4348 }
4349 }
4350 if (iop == ASC_IOADR_TABLE_MAX_IX) {
4351 printk(
4352"AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
4353 asc_ioport[ioport]);
4354 asc_ioport[ioport] = 0;
4355 }
4356 }
4357 }
4358 ioport = 0;
4359 }
4360
4361 for (bus = 0; bus < ASC_NUM_BUS; bus++) {
4362
4363 ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
4364 bus, asc_bus_name[bus]);
4365 iop = 0;
4366
4367 while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) {
4368
4369 ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
4370 asc_board_count);
4371
4372 switch (asc_bus[bus]) {
4373 case ASC_IS_ISA:
4374 case ASC_IS_VL:
4375#ifdef CONFIG_ISA
4376 if (asc_iopflag == ASC_FALSE) {
4377 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4378 } else {
4379 /*
4380 * ISA and VL I/O port scanning has either been
4381 * eliminated or limited to selected ports on
4382 * the LILO command line, /etc/lilo.conf, or
4383 * by setting variables when the module was loaded.
4384 */
4385 ASC_DBG(1, "advansys_detect: I/O port scanning modified\n");
4386 ioport_try_again:
4387 iop = 0;
4388 for (; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
4389 if ((iop = asc_ioport[ioport]) != 0) {
4390 break;
4391 }
4392 }
4393 if (iop) {
4394 ASC_DBG1(1,
4395 "advansys_detect: probing I/O port 0x%x...\n",
4396 iop);
35d68483 4397 if (!request_region(iop, ASC_IOADR_GAP, "advansys")){
1da177e4
LT
4398 printk(
4399"AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop);
4400 /* Don't try this I/O port twice. */
4401 asc_ioport[ioport] = 0;
4402 goto ioport_try_again;
4403 } else if (AscFindSignature(iop) == ASC_FALSE) {
4404 printk(
4405"AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop);
4406 /* Don't try this I/O port twice. */
35d68483 4407 release_region(iop, ASC_IOADR_GAP);
1da177e4
LT
4408 asc_ioport[ioport] = 0;
4409 goto ioport_try_again;
4410 } else {
4411 /*
4412 * If this isn't an ISA board, then it must be
4413 * a VL board. If currently looking an ISA
4414 * board is being looked for then try for
4415 * another ISA board in 'asc_ioport'.
4416 */
4417 if (asc_bus[bus] == ASC_IS_ISA &&
4418 (AscGetChipVersion(iop, ASC_IS_ISA) &
4419 ASC_CHIP_VER_ISA_BIT) == 0) {
4420 /*
4421 * Don't clear 'asc_ioport[ioport]'. Try
4422 * this board again for VL. Increment
4423 * 'ioport' past this board.
4424 */
4425 ioport++;
35d68483 4426 release_region(iop, ASC_IOADR_GAP);
1da177e4
LT
4427 goto ioport_try_again;
4428 }
4429 }
4430 /*
4431 * This board appears good, don't try the I/O port
4432 * again by clearing its value. Increment 'ioport'
4433 * for the next iteration.
4434 */
4435 asc_ioport[ioport++] = 0;
4436 }
4437 }
4438#endif /* CONFIG_ISA */
4439 break;
4440
4441 case ASC_IS_EISA:
4442#ifdef CONFIG_ISA
4443 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4444#endif /* CONFIG_ISA */
4445 break;
4446
4447 case ASC_IS_PCI:
4448#ifdef CONFIG_PCI
4449 if (pci_init_search == 0) {
4450 int i, j;
4451
4452 pci_init_search = 1;
4453
4454 /* Find all PCI cards. */
4455 while (pci_device_id_cnt < ASC_PCI_DEVICE_ID_CNT) {
2672ea86 4456 if ((pci_devp = pci_find_device(PCI_VENDOR_ID_ASP,
1da177e4
LT
4457 pci_device_id[pci_device_id_cnt], pci_devp)) ==
4458 NULL) {
4459 pci_device_id_cnt++;
4460 } else {
4461 if (pci_enable_device(pci_devp) == 0) {
4462 pci_devicep[pci_card_cnt_max++] = pci_devp;
4463 }
4464 }
4465 }
4466
4467 /*
4468 * Sort PCI cards in ascending order by PCI Bus, Slot,
4469 * and Device Number.
4470 */
4471 for (i = 0; i < pci_card_cnt_max - 1; i++)
4472 {
4473 for (j = i + 1; j < pci_card_cnt_max; j++) {
4474 if ((pci_devicep[j]->bus->number <
4475 pci_devicep[i]->bus->number) ||
4476 ((pci_devicep[j]->bus->number ==
4477 pci_devicep[i]->bus->number) &&
4478 (pci_devicep[j]->devfn <
4479 pci_devicep[i]->devfn))) {
4480 pci_devp = pci_devicep[i];
4481 pci_devicep[i] = pci_devicep[j];
4482 pci_devicep[j] = pci_devp;
4483 }
4484 }
4485 }
4486
4487 pci_card_cnt = 0;
4488 } else {
4489 pci_card_cnt++;
4490 }
4491
4492 if (pci_card_cnt == pci_card_cnt_max) {
4493 iop = 0;
4494 } else {
4495 pci_devp = pci_devicep[pci_card_cnt];
4496
4497 ASC_DBG2(2,
4498 "advansys_detect: devfn %d, bus number %d\n",
4499 pci_devp->devfn, pci_devp->bus->number);
4500 iop = pci_resource_start(pci_devp, 0);
4501 ASC_DBG2(1,
4502 "advansys_detect: vendorID %X, deviceID %X\n",
4503 pci_devp->vendor, pci_devp->device);
4504 ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
4505 iop, pci_devp->irq);
4506 }
4507 if(pci_devp)
4508 dev = &pci_devp->dev;
4509
4510#endif /* CONFIG_PCI */
4511 break;
4512
4513 default:
4514 ASC_PRINT1("advansys_detect: unknown bus type: %d\n",
4515 asc_bus[bus]);
4516 break;
4517 }
4518 ASC_DBG1(1, "advansys_detect: iop 0x%x\n", iop);
4519
4520 /*
4521 * Adapter not found, try next bus type.
4522 */
4523 if (iop == 0) {
4524 break;
4525 }
4526
4527 /*
4528 * Adapter found.
4529 *
4530 * Register the adapter, get its configuration, and
4531 * initialize it.
4532 */
4533 ASC_DBG(2, "advansys_detect: scsi_register()\n");
4534 shp = scsi_register(tpnt, sizeof(asc_board_t));
4535
4536 if (shp == NULL) {
4537 continue;
4538 }
4539
1da177e4
LT
4540 /* Save a pointer to the Scsi_Host of each board found. */
4541 asc_host[asc_board_count++] = shp;
4542
4543 /* Initialize private per board data */
4544 boardp = ASC_BOARDP(shp);
4545 memset(boardp, 0, sizeof(asc_board_t));
4546 boardp->id = asc_board_count - 1;
4547
4548 /* Initialize spinlock. */
4549 spin_lock_init(&boardp->lock);
4550
4551 /*
4552 * Handle both narrow and wide boards.
4553 *
4554 * If a Wide board was detected, set the board structure
4555 * wide board flag. Set-up the board structure based on
4556 * the board type.
4557 */
4558#ifdef CONFIG_PCI
4559 if (asc_bus[bus] == ASC_IS_PCI &&
2672ea86
DJ
4560 (pci_devp->device == PCI_DEVICE_ID_ASP_ABP940UW ||
4561 pci_devp->device == PCI_DEVICE_ID_38C0800_REV1 ||
4562 pci_devp->device == PCI_DEVICE_ID_38C1600_REV1))
1da177e4
LT
4563 {
4564 boardp->flags |= ASC_IS_WIDE_BOARD;
4565 }
4566#endif /* CONFIG_PCI */
4567
4568 if (ASC_NARROW_BOARD(boardp)) {
4569 ASC_DBG(1, "advansys_detect: narrow board\n");
4570 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4571 asc_dvc_varp->bus_type = asc_bus[bus];
4572 asc_dvc_varp->drv_ptr = boardp;
4573 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
4574 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
4575 asc_dvc_varp->iop_base = iop;
4576 asc_dvc_varp->isr_callback = asc_isr_callback;
4577 } else {
4578 ASC_DBG(1, "advansys_detect: wide board\n");
4579 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4580 adv_dvc_varp->drv_ptr = boardp;
4581 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
4582 adv_dvc_varp->isr_callback = adv_isr_callback;
4583 adv_dvc_varp->async_callback = adv_async_callback;
4584#ifdef CONFIG_PCI
2672ea86 4585 if (pci_devp->device == PCI_DEVICE_ID_ASP_ABP940UW)
1da177e4
LT
4586 {
4587 ASC_DBG(1, "advansys_detect: ASC-3550\n");
4588 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
2672ea86 4589 } else if (pci_devp->device == PCI_DEVICE_ID_38C0800_REV1)
1da177e4
LT
4590 {
4591 ASC_DBG(1, "advansys_detect: ASC-38C0800\n");
4592 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
4593 } else
4594 {
4595 ASC_DBG(1, "advansys_detect: ASC-38C1600\n");
4596 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
4597 }
4598#endif /* CONFIG_PCI */
4599
4600 /*
4601 * Map the board's registers into virtual memory for
4602 * PCI slave access. Only memory accesses are used to
4603 * access the board's registers.
4604 *
4605 * Note: The PCI register base address is not always
4606 * page aligned, but the address passed to ioremap()
4607 * must be page aligned. It is guaranteed that the
4608 * PCI register base address will not cross a page
4609 * boundary.
4610 */
4611 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
4612 {
4613 iolen = ADV_3550_IOLEN;
4614 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
4615 {
4616 iolen = ADV_38C0800_IOLEN;
4617 } else
4618 {
4619 iolen = ADV_38C1600_IOLEN;
4620 }
4621#ifdef CONFIG_PCI
4622 pci_memory_address = pci_resource_start(pci_devp, 1);
4623 ASC_DBG1(1, "advansys_detect: pci_memory_address: 0x%lx\n",
4624 (ulong) pci_memory_address);
4625 if ((boardp->ioremap_addr =
4626 ioremap(pci_memory_address & PAGE_MASK,
4627 PAGE_SIZE)) == 0) {
4628 ASC_PRINT3(
4629"advansys_detect: board %d: ioremap(%x, %d) returned NULL\n",
4630 boardp->id, pci_memory_address, iolen);
4631 scsi_unregister(shp);
4632 asc_board_count--;
4633 continue;
4634 }
4635 ASC_DBG1(1, "advansys_detect: ioremap_addr: 0x%lx\n",
4636 (ulong) boardp->ioremap_addr);
4637 adv_dvc_varp->iop_base = (AdvPortAddr)
4638 (boardp->ioremap_addr +
4639 (pci_memory_address - (pci_memory_address & PAGE_MASK)));
4640 ASC_DBG1(1, "advansys_detect: iop_base: 0x%lx\n",
4641 adv_dvc_varp->iop_base);
4642#endif /* CONFIG_PCI */
4643
4644 /*
4645 * Even though it isn't used to access wide boards, other
4646 * than for the debug line below, save I/O Port address so
4647 * that it can be reported.
4648 */
4649 boardp->ioport = iop;
4650
4651 ASC_DBG2(1,
4652"advansys_detect: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
4653 (ushort) inp(iop + 1), (ushort) inpw(iop));
4654 }
4655
4656#ifdef CONFIG_PROC_FS
4657 /*
4658 * Allocate buffer for printing information from
4659 * /proc/scsi/advansys/[0...].
4660 */
4661 if ((boardp->prtbuf =
4662 kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) {
4663 ASC_PRINT3(
4664"advansys_detect: board %d: kmalloc(%d, %d) returned NULL\n",
4665 boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC);
4666 scsi_unregister(shp);
4667 asc_board_count--;
4668 continue;
4669 }
4670#endif /* CONFIG_PROC_FS */
4671
4672 if (ASC_NARROW_BOARD(boardp)) {
4673 asc_dvc_varp->cfg->dev = dev;
4674 /*
4675 * Set the board bus type and PCI IRQ before
4676 * calling AscInitGetConfig().
4677 */
4678 switch (asc_dvc_varp->bus_type) {
4679#ifdef CONFIG_ISA
4680 case ASC_IS_ISA:
4681 shp->unchecked_isa_dma = TRUE;
4682 share_irq = FALSE;
4683 break;
4684 case ASC_IS_VL:
4685 shp->unchecked_isa_dma = FALSE;
4686 share_irq = FALSE;
4687 break;
4688 case ASC_IS_EISA:
4689 shp->unchecked_isa_dma = FALSE;
4690 share_irq = TRUE;
4691 break;
4692#endif /* CONFIG_ISA */
4693#ifdef CONFIG_PCI
4694 case ASC_IS_PCI:
4695 shp->irq = asc_dvc_varp->irq_no = pci_devp->irq;
4696 asc_dvc_varp->cfg->pci_slot_info =
4697 ASC_PCI_MKID(pci_devp->bus->number,
4698 PCI_SLOT(pci_devp->devfn),
4699 PCI_FUNC(pci_devp->devfn));
4700 shp->unchecked_isa_dma = FALSE;
4701 share_irq = TRUE;
4702 break;
4703#endif /* CONFIG_PCI */
4704 default:
4705 ASC_PRINT2(
4706"advansys_detect: board %d: unknown adapter type: %d\n",
4707 boardp->id, asc_dvc_varp->bus_type);
4708 shp->unchecked_isa_dma = TRUE;
4709 share_irq = FALSE;
4710 break;
4711 }
4712 } else {
4713 adv_dvc_varp->cfg->dev = dev;
4714 /*
4715 * For Wide boards set PCI information before calling
4716 * AdvInitGetConfig().
4717 */
4718#ifdef CONFIG_PCI
4719 shp->irq = adv_dvc_varp->irq_no = pci_devp->irq;
4720 adv_dvc_varp->cfg->pci_slot_info =
4721 ASC_PCI_MKID(pci_devp->bus->number,
4722 PCI_SLOT(pci_devp->devfn),
4723 PCI_FUNC(pci_devp->devfn));
4724 shp->unchecked_isa_dma = FALSE;
4725 share_irq = TRUE;
4726#endif /* CONFIG_PCI */
4727 }
4728
4729 /*
4730 * Read the board configuration.
4731 */
4732 if (ASC_NARROW_BOARD(boardp)) {
4733 /*
4734 * NOTE: AscInitGetConfig() may change the board's
4735 * bus_type value. The asc_bus[bus] value should no
4736 * longer be used. If the bus_type field must be
4737 * referenced only use the bit-wise AND operator "&".
4738 */
4739 ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
4740 switch(ret = AscInitGetConfig(asc_dvc_varp)) {
4741 case 0: /* No error */
4742 break;
4743 case ASC_WARN_IO_PORT_ROTATE:
4744 ASC_PRINT1(
4745"AscInitGetConfig: board %d: I/O port address modified\n",
4746 boardp->id);
4747 break;
4748 case ASC_WARN_AUTO_CONFIG:
4749 ASC_PRINT1(
4750"AscInitGetConfig: board %d: I/O port increment switch enabled\n",
4751 boardp->id);
4752 break;
4753 case ASC_WARN_EEPROM_CHKSUM:
4754 ASC_PRINT1(
4755"AscInitGetConfig: board %d: EEPROM checksum error\n",
4756 boardp->id);
4757 break;
4758 case ASC_WARN_IRQ_MODIFIED:
4759 ASC_PRINT1(
4760"AscInitGetConfig: board %d: IRQ modified\n",
4761 boardp->id);
4762 break;
4763 case ASC_WARN_CMD_QNG_CONFLICT:
4764 ASC_PRINT1(
4765"AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
4766 boardp->id);
4767 break;
4768 default:
4769 ASC_PRINT2(
4770"AscInitGetConfig: board %d: unknown warning: 0x%x\n",
4771 boardp->id, ret);
4772 break;
4773 }
4774 if ((err_code = asc_dvc_varp->err_code) != 0) {
4775 ASC_PRINT3(
4776"AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
4777 boardp->id, asc_dvc_varp->init_state,
4778 asc_dvc_varp->err_code);
4779 }
4780 } else {
4781 ASC_DBG(2, "advansys_detect: AdvInitGetConfig()\n");
4782 if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
4783 ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n",
4784 boardp->id, ret);
4785 }
4786 if ((err_code = adv_dvc_varp->err_code) != 0) {
4787 ASC_PRINT2(
4788"AdvInitGetConfig: board %d error: err_code 0x%x\n",
4789 boardp->id, adv_dvc_varp->err_code);
4790 }
4791 }
4792
4793 if (err_code != 0) {
4794#ifdef CONFIG_PROC_FS
4795 kfree(boardp->prtbuf);
4796#endif /* CONFIG_PROC_FS */
4797 scsi_unregister(shp);
4798 asc_board_count--;
4799 continue;
4800 }
4801
4802 /*
4803 * Save the EEPROM configuration so that it can be displayed
4804 * from /proc/scsi/advansys/[0...].
4805 */
4806 if (ASC_NARROW_BOARD(boardp)) {
4807
4808 ASCEEP_CONFIG *ep;
4809
4810 /*
4811 * Set the adapter's target id bit in the 'init_tidmask' field.
4812 */
4813 boardp->init_tidmask |=
4814 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
4815
4816 /*
4817 * Save EEPROM settings for the board.
4818 */
4819 ep = &boardp->eep_config.asc_eep;
4820
4821 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
4822 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
4823 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
4824 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
4825 ep->start_motor = asc_dvc_varp->start_motor;
4826 ep->cntl = asc_dvc_varp->dvc_cntl;
4827 ep->no_scam = asc_dvc_varp->no_scam;
4828 ep->max_total_qng = asc_dvc_varp->max_total_qng;
4829 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
4830 /* 'max_tag_qng' is set to the same value for every device. */
4831 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
4832 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
4833 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
4834 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
4835 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
4836 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
4837 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
4838
4839 /*
4840 * Modify board configuration.
4841 */
4842 ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n");
4843 switch (ret = AscInitSetConfig(asc_dvc_varp)) {
4844 case 0: /* No error. */
4845 break;
4846 case ASC_WARN_IO_PORT_ROTATE:
4847 ASC_PRINT1(
4848"AscInitSetConfig: board %d: I/O port address modified\n",
4849 boardp->id);
4850 break;
4851 case ASC_WARN_AUTO_CONFIG:
4852 ASC_PRINT1(
4853"AscInitSetConfig: board %d: I/O port increment switch enabled\n",
4854 boardp->id);
4855 break;
4856 case ASC_WARN_EEPROM_CHKSUM:
4857 ASC_PRINT1(
4858"AscInitSetConfig: board %d: EEPROM checksum error\n",
4859 boardp->id);
4860 break;
4861 case ASC_WARN_IRQ_MODIFIED:
4862 ASC_PRINT1(
4863"AscInitSetConfig: board %d: IRQ modified\n",
4864 boardp->id);
4865 break;
4866 case ASC_WARN_CMD_QNG_CONFLICT:
4867 ASC_PRINT1(
4868"AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
4869 boardp->id);
4870 break;
4871 default:
4872 ASC_PRINT2(
4873"AscInitSetConfig: board %d: unknown warning: 0x%x\n",
4874 boardp->id, ret);
4875 break;
4876 }
4877 if (asc_dvc_varp->err_code != 0) {
4878 ASC_PRINT3(
4879"AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
4880 boardp->id, asc_dvc_varp->init_state,
4881 asc_dvc_varp->err_code);
4882#ifdef CONFIG_PROC_FS
4883 kfree(boardp->prtbuf);
4884#endif /* CONFIG_PROC_FS */
4885 scsi_unregister(shp);
4886 asc_board_count--;
4887 continue;
4888 }
4889
4890 /*
4891 * Finish initializing the 'Scsi_Host' structure.
4892 */
4893 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
4894 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
4895 shp->irq = asc_dvc_varp->irq_no;
4896 }
4897 } else {
4898 ADVEEP_3550_CONFIG *ep_3550;
4899 ADVEEP_38C0800_CONFIG *ep_38C0800;
4900 ADVEEP_38C1600_CONFIG *ep_38C1600;
4901
4902 /*
4903 * Save Wide EEP Configuration Information.
4904 */
4905 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
4906 {
4907 ep_3550 = &boardp->eep_config.adv_3550_eep;
4908
4909 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
4910 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
4911 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
4912 ep_3550->termination = adv_dvc_varp->cfg->termination;
4913 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
4914 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
4915 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
4916 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
4917 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
4918 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
4919 ep_3550->start_motor = adv_dvc_varp->start_motor;
4920 ep_3550->scsi_reset_delay = adv_dvc_varp->scsi_reset_wait;
4921 ep_3550->serial_number_word1 =
4922 adv_dvc_varp->cfg->serial1;
4923 ep_3550->serial_number_word2 =
4924 adv_dvc_varp->cfg->serial2;
4925 ep_3550->serial_number_word3 =
4926 adv_dvc_varp->cfg->serial3;
4927 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
4928 {
4929 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
4930
4931 ep_38C0800->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
4932 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
4933 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
4934 ep_38C0800->termination_lvd =
4935 adv_dvc_varp->cfg->termination;
4936 ep_38C0800->disc_enable = adv_dvc_varp->cfg->disc_enable;
4937 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
4938 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
4939 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
4940 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
4941 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
4942 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
4943 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
4944 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
4945 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
4946 ep_38C0800->scsi_reset_delay =
4947 adv_dvc_varp->scsi_reset_wait;
4948 ep_38C0800->serial_number_word1 =
4949 adv_dvc_varp->cfg->serial1;
4950 ep_38C0800->serial_number_word2 =
4951 adv_dvc_varp->cfg->serial2;
4952 ep_38C0800->serial_number_word3 =
4953 adv_dvc_varp->cfg->serial3;
4954 } else
4955 {
4956 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
4957
4958 ep_38C1600->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
4959 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
4960 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
4961 ep_38C1600->termination_lvd =
4962 adv_dvc_varp->cfg->termination;
4963 ep_38C1600->disc_enable = adv_dvc_varp->cfg->disc_enable;
4964 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
4965 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
4966 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
4967 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
4968 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
4969 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
4970 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
4971 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
4972 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
4973 ep_38C1600->scsi_reset_delay =
4974 adv_dvc_varp->scsi_reset_wait;
4975 ep_38C1600->serial_number_word1 =
4976 adv_dvc_varp->cfg->serial1;
4977 ep_38C1600->serial_number_word2 =
4978 adv_dvc_varp->cfg->serial2;
4979 ep_38C1600->serial_number_word3 =
4980 adv_dvc_varp->cfg->serial3;
4981 }
4982
4983 /*
4984 * Set the adapter's target id bit in the 'init_tidmask' field.
4985 */
4986 boardp->init_tidmask |=
4987 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
4988
4989 /*
4990 * Finish initializing the 'Scsi_Host' structure.
4991 */
4992 shp->irq = adv_dvc_varp->irq_no;
4993 }
4994
4995 /*
4996 * Channels are numbered beginning with 0. For AdvanSys one host
4997 * structure supports one channel. Multi-channel boards have a
4998 * separate host structure for each channel.
4999 */
5000 shp->max_channel = 0;
5001 if (ASC_NARROW_BOARD(boardp)) {
5002 shp->max_id = ASC_MAX_TID + 1;
5003 shp->max_lun = ASC_MAX_LUN + 1;
5004
5005 shp->io_port = asc_dvc_varp->iop_base;
5006 boardp->asc_n_io_port = ASC_IOADR_GAP;
5007 shp->this_id = asc_dvc_varp->cfg->chip_scsi_id;
5008
5009 /* Set maximum number of queues the adapter can handle. */
5010 shp->can_queue = asc_dvc_varp->max_total_qng;
5011 } else {
5012 shp->max_id = ADV_MAX_TID + 1;
5013 shp->max_lun = ADV_MAX_LUN + 1;
5014
5015 /*
5016 * Save the I/O Port address and length even though
5017 * I/O ports are not used to access Wide boards.
5018 * Instead the Wide boards are accessed with
5019 * PCI Memory Mapped I/O.
5020 */
5021 shp->io_port = iop;
5022 boardp->asc_n_io_port = iolen;
5023
5024 shp->this_id = adv_dvc_varp->chip_scsi_id;
5025
5026 /* Set maximum number of queues the adapter can handle. */
5027 shp->can_queue = adv_dvc_varp->max_host_qng;
5028 }
5029
5030 /*
5031 * 'n_io_port' currently is one byte.
5032 *
5033 * Set a value to 'n_io_port', but never referenced it because
5034 * it may be truncated.
5035 */
5036 shp->n_io_port = boardp->asc_n_io_port <= 255 ?
5037 boardp->asc_n_io_port : 255;
5038
5039 /*
5040 * Following v1.3.89, 'cmd_per_lun' is no longer needed
5041 * and should be set to zero.
5042 *
5043 * But because of a bug introduced in v1.3.89 if the driver is
5044 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
5045 * SCSI function 'allocate_device' will panic. To allow the driver
5046 * to work as a module in these kernels set 'cmd_per_lun' to 1.
5047 *
5048 * Note: This is wrong. cmd_per_lun should be set to the depth
5049 * you want on untagged devices always.
5050#ifdef MODULE
5051 */
5052 shp->cmd_per_lun = 1;
5053/* #else
5054 shp->cmd_per_lun = 0;
5055#endif */
5056
5057 /*
5058 * Set the maximum number of scatter-gather elements the
5059 * adapter can handle.
5060 */
5061 if (ASC_NARROW_BOARD(boardp)) {
5062 /*
5063 * Allow two commands with 'sg_tablesize' scatter-gather
5064 * elements to be executed simultaneously. This value is
5065 * the theoretical hardware limit. It may be decreased
5066 * below.
5067 */
5068 shp->sg_tablesize =
5069 (((asc_dvc_varp->max_total_qng - 2) / 2) *
5070 ASC_SG_LIST_PER_Q) + 1;
5071 } else {
5072 shp->sg_tablesize = ADV_MAX_SG_LIST;
5073 }
5074
5075 /*
5076 * The value of 'sg_tablesize' can not exceed the SCSI
5077 * mid-level driver definition of SG_ALL. SG_ALL also
5078 * must not be exceeded, because it is used to define the
5079 * size of the scatter-gather table in 'struct asc_sg_head'.
5080 */
5081 if (shp->sg_tablesize > SG_ALL) {
5082 shp->sg_tablesize = SG_ALL;
5083 }
5084
5085 ASC_DBG1(1, "advansys_detect: sg_tablesize: %d\n",
5086 shp->sg_tablesize);
5087
5088 /* BIOS start address. */
5089 if (ASC_NARROW_BOARD(boardp)) {
5090 shp->base =
5091 ((ulong) AscGetChipBiosAddress(
5092 asc_dvc_varp->iop_base,
5093 asc_dvc_varp->bus_type));
5094 } else {
5095 /*
5096 * Fill-in BIOS board variables. The Wide BIOS saves
5097 * information in LRAM that is used by the driver.
5098 */
5099 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_SIGNATURE,
5100 boardp->bios_signature);
5101 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_VERSION,
5102 boardp->bios_version);
5103 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODESEG,
5104 boardp->bios_codeseg);
5105 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODELEN,
5106 boardp->bios_codelen);
5107
5108 ASC_DBG2(1,
5109 "advansys_detect: bios_signature 0x%x, bios_version 0x%x\n",
5110 boardp->bios_signature, boardp->bios_version);
5111
5112 ASC_DBG2(1,
5113 "advansys_detect: bios_codeseg 0x%x, bios_codelen 0x%x\n",
5114 boardp->bios_codeseg, boardp->bios_codelen);
5115
5116 /*
5117 * If the BIOS saved a valid signature, then fill in
5118 * the BIOS code segment base address.
5119 */
5120 if (boardp->bios_signature == 0x55AA) {
5121 /*
5122 * Convert x86 realmode code segment to a linear
5123 * address by shifting left 4.
5124 */
5125 shp->base = ((ulong) boardp->bios_codeseg << 4);
5126 } else {
5127 shp->base = 0;
5128 }
5129 }
5130
5131 /*
5132 * Register Board Resources - I/O Port, DMA, IRQ
5133 */
5134
5135 /*
5136 * Register I/O port range.
5137 *
5138 * For Wide boards the I/O ports are not used to access
5139 * the board, but request the region anyway.
5140 *
5141 * 'shp->n_io_port' is not referenced, because it may be truncated.
5142 */
5143 ASC_DBG2(2,
5144 "advansys_detect: request_region port 0x%lx, len 0x%x\n",
5145 (ulong) shp->io_port, boardp->asc_n_io_port);
5146 if (request_region(shp->io_port, boardp->asc_n_io_port,
5147 "advansys") == NULL) {
5148 ASC_PRINT3(
5149"advansys_detect: board %d: request_region() failed, port 0x%lx, len 0x%x\n",
5150 boardp->id, (ulong) shp->io_port, boardp->asc_n_io_port);
5151#ifdef CONFIG_PROC_FS
5152 kfree(boardp->prtbuf);
5153#endif /* CONFIG_PROC_FS */
5154 scsi_unregister(shp);
5155 asc_board_count--;
5156 continue;
5157 }
5158
5159 /* Register DMA Channel for Narrow boards. */
5160 shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
5161#ifdef CONFIG_ISA
5162 if (ASC_NARROW_BOARD(boardp)) {
5163 /* Register DMA channel for ISA bus. */
5164 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5165 shp->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
5166 if ((ret =
5167 request_dma(shp->dma_channel, "advansys")) != 0) {
5168 ASC_PRINT3(
5169"advansys_detect: board %d: request_dma() %d failed %d\n",
5170 boardp->id, shp->dma_channel, ret);
5171 release_region(shp->io_port, boardp->asc_n_io_port);
5172#ifdef CONFIG_PROC_FS
5173 kfree(boardp->prtbuf);
5174#endif /* CONFIG_PROC_FS */
5175 scsi_unregister(shp);
5176 asc_board_count--;
5177 continue;
5178 }
5179 AscEnableIsaDma(shp->dma_channel);
5180 }
5181 }
5182#endif /* CONFIG_ISA */
5183
5184 /* Register IRQ Number. */
5185 ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
5186 /*
1d6f359a
TG
5187 * If request_irq() fails with the IRQF_DISABLED flag set,
5188 * then try again without the IRQF_DISABLED flag set. This
1da177e4 5189 * allows IRQ sharing to work even with other drivers that
1d6f359a 5190 * do not set the IRQF_DISABLED flag.
1da177e4 5191 *
1d6f359a 5192 * If IRQF_DISABLED is not set, then interrupts are enabled
1da177e4
LT
5193 * before the driver interrupt function is called.
5194 */
5195 if (((ret = request_irq(shp->irq, advansys_interrupt,
1d6f359a 5196 IRQF_DISABLED | (share_irq == TRUE ? IRQF_SHARED : 0),
1da177e4
LT
5197 "advansys", boardp)) != 0) &&
5198 ((ret = request_irq(shp->irq, advansys_interrupt,
1d6f359a 5199 (share_irq == TRUE ? IRQF_SHARED : 0),
1da177e4
LT
5200 "advansys", boardp)) != 0))
5201 {
5202 if (ret == -EBUSY) {
5203 ASC_PRINT2(
5204"advansys_detect: board %d: request_irq(): IRQ 0x%x already in use.\n",
5205 boardp->id, shp->irq);
5206 } else if (ret == -EINVAL) {
5207 ASC_PRINT2(
5208"advansys_detect: board %d: request_irq(): IRQ 0x%x not valid.\n",
5209 boardp->id, shp->irq);
5210 } else {
5211 ASC_PRINT3(
5212"advansys_detect: board %d: request_irq(): IRQ 0x%x failed with %d\n",
5213 boardp->id, shp->irq, ret);
5214 }
5215 release_region(shp->io_port, boardp->asc_n_io_port);
5216 iounmap(boardp->ioremap_addr);
5217 if (shp->dma_channel != NO_ISA_DMA) {
5218 free_dma(shp->dma_channel);
5219 }
5220#ifdef CONFIG_PROC_FS
5221 kfree(boardp->prtbuf);
5222#endif /* CONFIG_PROC_FS */
5223 scsi_unregister(shp);
5224 asc_board_count--;
5225 continue;
5226 }
5227
5228 /*
5229 * Initialize board RISC chip and enable interrupts.
5230 */
5231 if (ASC_NARROW_BOARD(boardp)) {
5232 ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n");
5233 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
5234 err_code = asc_dvc_varp->err_code;
5235
5236 if (warn_code || err_code) {
5237 ASC_PRINT4(
5238"advansys_detect: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
5239 boardp->id, asc_dvc_varp->init_state,
5240 warn_code, err_code);
5241 }
5242 } else {
5243 ADV_CARR_T *carrp;
5244 int req_cnt = 0;
5245 adv_req_t *reqp = NULL;
5246 int sg_cnt = 0;
5247
5248 /*
5249 * Allocate buffer carrier structures. The total size
5250 * is about 4 KB, so allocate all at once.
5251 */
5252 carrp =
5253 (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC);
5254 ASC_DBG1(1, "advansys_detect: carrp 0x%lx\n", (ulong) carrp);
5255
5256 if (carrp == NULL) {
5257 goto kmalloc_error;
5258 }
5259
5260 /*
5261 * Allocate up to 'max_host_qng' request structures for
5262 * the Wide board. The total size is about 16 KB, so
5263 * allocate all at once. If the allocation fails decrement
5264 * and try again.
5265 */
5266 for (req_cnt = adv_dvc_varp->max_host_qng;
5267 req_cnt > 0; req_cnt--) {
5268
5269 reqp = (adv_req_t *)
5270 kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC);
5271
5272 ASC_DBG3(1,
5273 "advansys_detect: reqp 0x%lx, req_cnt %d, bytes %lu\n",
5274 (ulong) reqp, req_cnt,
5275 (ulong) sizeof(adv_req_t) * req_cnt);
5276
5277 if (reqp != NULL) {
5278 break;
5279 }
5280 }
5281 if (reqp == NULL)
5282 {
5283 goto kmalloc_error;
5284 }
5285
5286 /*
5287 * Allocate up to ADV_TOT_SG_BLOCK request structures for
5288 * the Wide board. Each structure is about 136 bytes.
5289 */
5290 boardp->adv_sgblkp = NULL;
5291 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
5292
5293 sgp = (adv_sgblk_t *)
5294 kmalloc(sizeof(adv_sgblk_t), GFP_ATOMIC);
5295
5296 if (sgp == NULL) {
5297 break;
5298 }
5299
5300 sgp->next_sgblkp = boardp->adv_sgblkp;
5301 boardp->adv_sgblkp = sgp;
5302
5303 }
5304 ASC_DBG3(1,
5305 "advansys_detect: sg_cnt %d * %u = %u bytes\n",
5306 sg_cnt, sizeof(adv_sgblk_t),
5307 (unsigned) (sizeof(adv_sgblk_t) * sg_cnt));
5308
5309 /*
5310 * If no request structures or scatter-gather structures could
5311 * be allocated, then return an error. Otherwise continue with
5312 * initialization.
5313 */
5314 kmalloc_error:
5315 if (carrp == NULL)
5316 {
5317 ASC_PRINT1(
5318"advansys_detect: board %d error: failed to kmalloc() carrier buffer.\n",
5319 boardp->id);
5320 err_code = ADV_ERROR;
5321 } else if (reqp == NULL) {
5322 kfree(carrp);
5323 ASC_PRINT1(
5324"advansys_detect: board %d error: failed to kmalloc() adv_req_t buffer.\n",
5325 boardp->id);
5326 err_code = ADV_ERROR;
5327 } else if (boardp->adv_sgblkp == NULL) {
5328 kfree(carrp);
5329 kfree(reqp);
5330 ASC_PRINT1(
5331"advansys_detect: board %d error: failed to kmalloc() adv_sgblk_t buffers.\n",
5332 boardp->id);
5333 err_code = ADV_ERROR;
5334 } else {
5335
5336 /* Save carrier buffer pointer. */
5337 boardp->orig_carrp = carrp;
5338
5339 /*
5340 * Save original pointer for kfree() in case the
5341 * driver is built as a module and can be unloaded.
5342 */
5343 boardp->orig_reqp = reqp;
5344
5345 adv_dvc_varp->carrier_buf = carrp;
5346
5347 /*
5348 * Point 'adv_reqp' to the request structures and
5349 * link them together.
5350 */
5351 req_cnt--;
5352 reqp[req_cnt].next_reqp = NULL;
5353 for (; req_cnt > 0; req_cnt--) {
5354 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
5355 }
5356 boardp->adv_reqp = &reqp[0];
5357
5358 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5359 {
5360 ASC_DBG(2,
5361 "advansys_detect: AdvInitAsc3550Driver()\n");
5362 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
5363 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5364 ASC_DBG(2,
5365 "advansys_detect: AdvInitAsc38C0800Driver()\n");
5366 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
5367 } else {
5368 ASC_DBG(2,
5369 "advansys_detect: AdvInitAsc38C1600Driver()\n");
5370 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
5371 }
5372 err_code = adv_dvc_varp->err_code;
5373
5374 if (warn_code || err_code) {
5375 ASC_PRINT3(
5376"advansys_detect: board %d error: warn 0x%x, error 0x%x\n",
5377 boardp->id, warn_code, err_code);
5378 }
5379 }
5380 }
5381
5382 if (err_code != 0) {
5383 release_region(shp->io_port, boardp->asc_n_io_port);
5384 if (ASC_WIDE_BOARD(boardp)) {
5385 iounmap(boardp->ioremap_addr);
c9475cb0
JJ
5386 kfree(boardp->orig_carrp);
5387 boardp->orig_carrp = NULL;
1da177e4
LT
5388 if (boardp->orig_reqp) {
5389 kfree(boardp->orig_reqp);
5390 boardp->orig_reqp = boardp->adv_reqp = NULL;
5391 }
5392 while ((sgp = boardp->adv_sgblkp) != NULL)
5393 {
5394 boardp->adv_sgblkp = sgp->next_sgblkp;
5395 kfree(sgp);
5396 }
5397 }
5398 if (shp->dma_channel != NO_ISA_DMA) {
5399 free_dma(shp->dma_channel);
5400 }
5401#ifdef CONFIG_PROC_FS
5402 kfree(boardp->prtbuf);
5403#endif /* CONFIG_PROC_FS */
5404 free_irq(shp->irq, boardp);
5405 scsi_unregister(shp);
5406 asc_board_count--;
5407 continue;
5408 }
5409 ASC_DBG_PRT_SCSI_HOST(2, shp);
5410 }
5411 }
5412
5413 ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count);
5414 return asc_board_count;
5415}
5416
5417/*
5418 * advansys_release()
5419 *
5420 * Release resources allocated for a single AdvanSys adapter.
5421 */
70c8d897 5422static int
1da177e4
LT
5423advansys_release(struct Scsi_Host *shp)
5424{
5425 asc_board_t *boardp;
5426
5427 ASC_DBG(1, "advansys_release: begin\n");
5428 boardp = ASC_BOARDP(shp);
5429 free_irq(shp->irq, boardp);
5430 if (shp->dma_channel != NO_ISA_DMA) {
5431 ASC_DBG(1, "advansys_release: free_dma()\n");
5432 free_dma(shp->dma_channel);
5433 }
5434 release_region(shp->io_port, boardp->asc_n_io_port);
5435 if (ASC_WIDE_BOARD(boardp)) {
5436 adv_sgblk_t *sgp = NULL;
5437
5438 iounmap(boardp->ioremap_addr);
c9475cb0
JJ
5439 kfree(boardp->orig_carrp);
5440 boardp->orig_carrp = NULL;
1da177e4
LT
5441 if (boardp->orig_reqp) {
5442 kfree(boardp->orig_reqp);
5443 boardp->orig_reqp = boardp->adv_reqp = NULL;
5444 }
5445 while ((sgp = boardp->adv_sgblkp) != NULL)
5446 {
5447 boardp->adv_sgblkp = sgp->next_sgblkp;
5448 kfree(sgp);
5449 }
5450 }
5451#ifdef CONFIG_PROC_FS
5452 ASC_ASSERT(boardp->prtbuf != NULL);
5453 kfree(boardp->prtbuf);
5454#endif /* CONFIG_PROC_FS */
5455 scsi_unregister(shp);
5456 ASC_DBG(1, "advansys_release: end\n");
5457 return 0;
5458}
5459
5460/*
5461 * advansys_info()
5462 *
5463 * Return suitable for printing on the console with the argument
5464 * adapter's configuration information.
5465 *
5466 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
5467 * otherwise the static 'info' array will be overrun.
5468 */
70c8d897 5469static const char *
1da177e4
LT
5470advansys_info(struct Scsi_Host *shp)
5471{
5472 static char info[ASC_INFO_SIZE];
5473 asc_board_t *boardp;
5474 ASC_DVC_VAR *asc_dvc_varp;
5475 ADV_DVC_VAR *adv_dvc_varp;
5476 char *busname;
5477 int iolen;
5478 char *widename = NULL;
5479
5480 boardp = ASC_BOARDP(shp);
5481 if (ASC_NARROW_BOARD(boardp)) {
5482 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5483 ASC_DBG(1, "advansys_info: begin\n");
5484 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5485 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == ASC_IS_ISAPNP) {
5486 busname = "ISA PnP";
5487 } else {
5488 busname = "ISA";
5489 }
5490 /* Don't reference 'shp->n_io_port'; It may be truncated. */
5491 sprintf(info,
5492"AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
5493 ASC_VERSION, busname,
5494 (ulong) shp->io_port,
5495 (ulong) shp->io_port + boardp->asc_n_io_port - 1,
5496 shp->irq, shp->dma_channel);
5497 } else {
5498 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
5499 busname = "VL";
5500 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
5501 busname = "EISA";
5502 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
5503 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
5504 == ASC_IS_PCI_ULTRA) {
5505 busname = "PCI Ultra";
5506 } else {
5507 busname = "PCI";
5508 }
5509 } else {
5510 busname = "?";
5511 ASC_PRINT2( "advansys_info: board %d: unknown bus type %d\n",
5512 boardp->id, asc_dvc_varp->bus_type);
5513 }
5514 /* Don't reference 'shp->n_io_port'; It may be truncated. */
5515 sprintf(info,
5516 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
5517 ASC_VERSION, busname,
5518 (ulong) shp->io_port,
5519 (ulong) shp->io_port + boardp->asc_n_io_port - 1,
5520 shp->irq);
5521 }
5522 } else {
5523 /*
5524 * Wide Adapter Information
5525 *
5526 * Memory-mapped I/O is used instead of I/O space to access
5527 * the adapter, but display the I/O Port range. The Memory
5528 * I/O address is displayed through the driver /proc file.
5529 */
5530 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5531 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5532 {
5533 iolen = ADV_3550_IOLEN;
5534 widename = "Ultra-Wide";
5535 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
5536 {
5537 iolen = ADV_38C0800_IOLEN;
5538 widename = "Ultra2-Wide";
5539 } else
5540 {
5541 iolen = ADV_38C1600_IOLEN;
5542 widename = "Ultra3-Wide";
5543 }
5544 sprintf(info, "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
5545 ASC_VERSION,
5546 widename,
5547 (ulong) adv_dvc_varp->iop_base,
5548 (ulong) adv_dvc_varp->iop_base + iolen - 1,
5549 shp->irq);
5550 }
5551 ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
5552 ASC_DBG(1, "advansys_info: end\n");
5553 return info;
5554}
5555
5556/*
5557 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
5558 *
5559 * This function always returns 0. Command return status is saved
5560 * in the 'scp' result field.
5561 */
70c8d897 5562static int
1da177e4
LT
5563advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
5564{
5565 struct Scsi_Host *shp;
5566 asc_board_t *boardp;
5567 ulong flags;
5568 struct scsi_cmnd *done_scp;
5569
5570 shp = scp->device->host;
5571 boardp = ASC_BOARDP(shp);
5572 ASC_STATS(shp, queuecommand);
5573
5574 /* host_lock taken by mid-level prior to call but need to protect */
5575 /* against own ISR */
5576 spin_lock_irqsave(&boardp->lock, flags);
5577
5578 /*
5579 * Block new commands while handling a reset or abort request.
5580 */
5581 if (boardp->flags & ASC_HOST_IN_RESET) {
5582 ASC_DBG1(1,
5583 "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
5584 (ulong) scp);
5585 scp->result = HOST_BYTE(DID_RESET);
5586
5587 /*
5588 * Add blocked requests to the board's 'done' queue. The queued
5589 * requests will be completed at the end of the abort or reset
5590 * handling.
5591 */
5592 asc_enqueue(&boardp->done, scp, ASC_BACK);
5593 spin_unlock_irqrestore(&boardp->lock, flags);
5594 return 0;
5595 }
5596
5597 /*
5598 * Attempt to execute any waiting commands for the board.
5599 */
5600 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
5601 ASC_DBG(1,
5602 "advansys_queuecommand: before asc_execute_queue() waiting\n");
5603 asc_execute_queue(&boardp->waiting);
5604 }
5605
5606 /*
5607 * Save the function pointer to Linux mid-level 'done' function
5608 * and attempt to execute the command.
5609 *
5610 * If ASC_NOERROR is returned the request has been added to the
5611 * board's 'active' queue and will be completed by the interrupt
5612 * handler.
5613 *
5614 * If ASC_BUSY is returned add the request to the board's per
5615 * target waiting list. This is the first time the request has
5616 * been tried. Add it to the back of the waiting list. It will be
5617 * retried later.
5618 *
5619 * If an error occurred, the request will have been placed on the
5620 * board's 'done' queue and must be completed before returning.
5621 */
5622 scp->scsi_done = done;
5623 switch (asc_execute_scsi_cmnd(scp)) {
5624 case ASC_NOERROR:
5625 break;
5626 case ASC_BUSY:
5627 asc_enqueue(&boardp->waiting, scp, ASC_BACK);
5628 break;
5629 case ASC_ERROR:
5630 default:
5631 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
5632 /* Interrupts could be enabled here. */
5633 asc_scsi_done_list(done_scp);
5634 break;
5635 }
5636 spin_unlock_irqrestore(&boardp->lock, flags);
5637
5638 return 0;
5639}
5640
5641/*
5642 * advansys_reset()
5643 *
5644 * Reset the bus associated with the command 'scp'.
5645 *
5646 * This function runs its own thread. Interrupts must be blocked but
5647 * sleeping is allowed and no locking other than for host structures is
5648 * required. Returns SUCCESS or FAILED.
5649 */
70c8d897 5650static int
1da177e4
LT
5651advansys_reset(struct scsi_cmnd *scp)
5652{
5653 struct Scsi_Host *shp;
5654 asc_board_t *boardp;
5655 ASC_DVC_VAR *asc_dvc_varp;
5656 ADV_DVC_VAR *adv_dvc_varp;
5657 ulong flags;
5658 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
5659 struct scsi_cmnd *tscp, *new_last_scp;
5660 int status;
5661 int ret = SUCCESS;
5662
5663 ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong) scp);
5664
5665#ifdef ADVANSYS_STATS
5666 if (scp->device->host != NULL) {
5667 ASC_STATS(scp->device->host, reset);
5668 }
5669#endif /* ADVANSYS_STATS */
5670
5671 if ((shp = scp->device->host) == NULL) {
5672 scp->result = HOST_BYTE(DID_ERROR);
5673 return FAILED;
5674 }
5675
5676 boardp = ASC_BOARDP(shp);
5677
5678 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
5679 boardp->id);
5680 /*
5681 * Check for re-entrancy.
5682 */
5683 spin_lock_irqsave(&boardp->lock, flags);
5684 if (boardp->flags & ASC_HOST_IN_RESET) {
5685 spin_unlock_irqrestore(&boardp->lock, flags);
5686 return FAILED;
5687 }
5688 boardp->flags |= ASC_HOST_IN_RESET;
5689 spin_unlock_irqrestore(&boardp->lock, flags);
5690
5691 if (ASC_NARROW_BOARD(boardp)) {
5692 /*
5693 * Narrow Board
5694 */
5695 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5696
5697 /*
5698 * Reset the chip and SCSI bus.
5699 */
5700 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
5701 status = AscInitAsc1000Driver(asc_dvc_varp);
5702
5703 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
5704 if (asc_dvc_varp->err_code) {
5705 ASC_PRINT2(
5706 "advansys_reset: board %d: SCSI bus reset error: 0x%x\n",
5707 boardp->id, asc_dvc_varp->err_code);
5708 ret = FAILED;
5709 } else if (status) {
5710 ASC_PRINT2(
5711 "advansys_reset: board %d: SCSI bus reset warning: 0x%x\n",
5712 boardp->id, status);
5713 } else {
5714 ASC_PRINT1(
5715 "advansys_reset: board %d: SCSI bus reset successful.\n",
5716 boardp->id);
5717 }
5718
5719 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
5720 spin_lock_irqsave(&boardp->lock, flags);
5721
5722 } else {
5723 /*
5724 * Wide Board
5725 *
5726 * If the suggest reset bus flags are set, then reset the bus.
5727 * Otherwise only reset the device.
5728 */
5729 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5730
5731 /*
5732 * Reset the target's SCSI bus.
5733 */
5734 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
5735 switch (AdvResetChipAndSB(adv_dvc_varp)) {
5736 case ASC_TRUE:
5737 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset successful.\n",
5738 boardp->id);
5739 break;
5740 case ASC_FALSE:
5741 default:
5742 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset error.\n",
5743 boardp->id);
5744 ret = FAILED;
5745 break;
5746 }
5747 spin_lock_irqsave(&boardp->lock, flags);
5748 (void) AdvISR(adv_dvc_varp);
5749 }
5750 /* Board lock is held. */
5751
5752 /*
5753 * Dequeue all board 'done' requests. A pointer to the last request
5754 * is returned in 'last_scp'.
5755 */
5756 done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
5757
5758 /*
5759 * Dequeue all board 'active' requests for all devices and set
5760 * the request status to DID_RESET. A pointer to the last request
5761 * is returned in 'last_scp'.
5762 */
5763 if (done_scp == NULL) {
5764 done_scp = asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL);
5765 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
5766 tscp->result = HOST_BYTE(DID_RESET);
5767 }
5768 } else {
5769 /* Append to 'done_scp' at the end with 'last_scp'. */
5770 ASC_ASSERT(last_scp != NULL);
5771 last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
5772 &boardp->active, &new_last_scp, ASC_TID_ALL);
5773 if (new_last_scp != NULL) {
5774 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
5775 for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
5776 tscp->result = HOST_BYTE(DID_RESET);
5777 }
5778 last_scp = new_last_scp;
5779 }
5780 }
5781
5782 /*
5783 * Dequeue all 'waiting' requests and set the request status
5784 * to DID_RESET.
5785 */
5786 if (done_scp == NULL) {
5787 done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL);
5788 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
5789 tscp->result = HOST_BYTE(DID_RESET);
5790 }
5791 } else {
5792 /* Append to 'done_scp' at the end with 'last_scp'. */
5793 ASC_ASSERT(last_scp != NULL);
5794 last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
5795 &boardp->waiting, &new_last_scp, ASC_TID_ALL);
5796 if (new_last_scp != NULL) {
5797 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
5798 for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
5799 tscp->result = HOST_BYTE(DID_RESET);
5800 }
5801 last_scp = new_last_scp;
5802 }
5803 }
5804
5805 /* Save the time of the most recently completed reset. */
5806 boardp->last_reset = jiffies;
5807
5808 /* Clear reset flag. */
5809 boardp->flags &= ~ASC_HOST_IN_RESET;
5810 spin_unlock_irqrestore(&boardp->lock, flags);
5811
5812 /*
5813 * Complete all the 'done_scp' requests.
5814 */
5815 if (done_scp != NULL) {
5816 asc_scsi_done_list(done_scp);
5817 }
5818
5819 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
5820
5821 return ret;
5822}
5823
5824/*
5825 * advansys_biosparam()
5826 *
5827 * Translate disk drive geometry if the "BIOS greater than 1 GB"
5828 * support is enabled for a drive.
5829 *
5830 * ip (information pointer) is an int array with the following definition:
5831 * ip[0]: heads
5832 * ip[1]: sectors
5833 * ip[2]: cylinders
5834 */
70c8d897 5835static int
1da177e4
LT
5836advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
5837 sector_t capacity, int ip[])
5838{
5839 asc_board_t *boardp;
5840
5841 ASC_DBG(1, "advansys_biosparam: begin\n");
5842 ASC_STATS(sdev->host, biosparam);
5843 boardp = ASC_BOARDP(sdev->host);
5844 if (ASC_NARROW_BOARD(boardp)) {
5845 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
5846 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
5847 ip[0] = 255;
5848 ip[1] = 63;
5849 } else {
5850 ip[0] = 64;
5851 ip[1] = 32;
5852 }
5853 } else {
5854 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
5855 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
5856 ip[0] = 255;
5857 ip[1] = 63;
5858 } else {
5859 ip[0] = 64;
5860 ip[1] = 32;
5861 }
5862 }
5863 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
5864 ASC_DBG(1, "advansys_biosparam: end\n");
5865 return 0;
5866}
5867
1da177e4
LT
5868/*
5869 * --- Loadable Driver Support
5870 */
5871
5872static struct scsi_host_template driver_template = {
5873 .proc_name = "advansys",
5874#ifdef CONFIG_PROC_FS
5875 .proc_info = advansys_proc_info,
5876#endif
5877 .name = "advansys",
5878 .detect = advansys_detect,
5879 .release = advansys_release,
5880 .info = advansys_info,
5881 .queuecommand = advansys_queuecommand,
5882 .eh_bus_reset_handler = advansys_reset,
5883 .bios_param = advansys_biosparam,
5884 .slave_configure = advansys_slave_configure,
5885 /*
5886 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
5887 * must be set. The flag will be cleared in advansys_detect for non-ISA
5888 * adapters. Refer to the comment in scsi_module.c for more information.
5889 */
5890 .unchecked_isa_dma = 1,
5891 /*
5892 * All adapters controlled by this driver are capable of large
5893 * scatter-gather lists. According to the mid-level SCSI documentation
5894 * this obviates any performance gain provided by setting
5895 * 'use_clustering'. But empirically while CPU utilization is increased
5896 * by enabling clustering, I/O throughput increases as well.
5897 */
5898 .use_clustering = ENABLE_CLUSTERING,
5899};
5900#include "scsi_module.c"
5901
5902
5903/*
5904 * --- Miscellaneous Driver Functions
5905 */
5906
5907/*
5908 * First-level interrupt handler.
5909 *
5910 * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
5911 * all boards are currently checked for interrupts on each interrupt, 'dev_id'
5912 * is not referenced. 'dev_id' could be used to identify an interrupt passed
5913 * to the AdvanSys driver which is for a device sharing an interrupt with
5914 * an AdvanSys adapter.
5915 */
5916STATIC irqreturn_t
7d12e780 5917advansys_interrupt(int irq, void *dev_id)
1da177e4
LT
5918{
5919 ulong flags;
5920 int i;
5921 asc_board_t *boardp;
5922 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
5923 struct scsi_cmnd *new_last_scp;
5924 struct Scsi_Host *shp;
5925
5926 ASC_DBG(1, "advansys_interrupt: begin\n");
5927
5928 /*
5929 * Check for interrupts on all boards.
5930 * AscISR() will call asc_isr_callback().
5931 */
5932 for (i = 0; i < asc_board_count; i++) {
5933 shp = asc_host[i];
5934 boardp = ASC_BOARDP(shp);
5935 ASC_DBG2(2, "advansys_interrupt: i %d, boardp 0x%lx\n",
5936 i, (ulong) boardp);
5937 spin_lock_irqsave(&boardp->lock, flags);
5938 if (ASC_NARROW_BOARD(boardp)) {
5939 /*
5940 * Narrow Board
5941 */
5942 if (AscIsIntPending(shp->io_port)) {
5943 ASC_STATS(shp, interrupt);
5944 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
5945 AscISR(&boardp->dvc_var.asc_dvc_var);
5946 }
5947 } else {
5948 /*
5949 * Wide Board
5950 */
5951 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
5952 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
5953 ASC_STATS(shp, interrupt);
5954 }
5955 }
5956
5957 /*
5958 * Start waiting requests and create a list of completed requests.
5959 *
5960 * If a reset request is being performed for the board, the reset
5961 * handler will complete pending requests after it has completed.
5962 */
5963 if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
5964 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%lx, last_scp 0x%lx\n",
5965 (ulong) done_scp, (ulong) last_scp);
5966
5967 /* Start any waiting commands for the board. */
5968 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
5969 ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
5970 asc_execute_queue(&boardp->waiting);
5971 }
5972
5973 /*
5974 * Add to the list of requests that must be completed.
5975 *
5976 * 'done_scp' will always be NULL on the first iteration
5977 * of this loop. 'last_scp' is set at the same time as
5978 * 'done_scp'.
5979 */
5980 if (done_scp == NULL) {
5981 done_scp = asc_dequeue_list(&boardp->done, &last_scp,
5982 ASC_TID_ALL);
5983 } else {
5984 ASC_ASSERT(last_scp != NULL);
5985 last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
5986 &boardp->done, &new_last_scp, ASC_TID_ALL);
5987 if (new_last_scp != NULL) {
5988 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
5989 last_scp = new_last_scp;
5990 }
5991 }
5992 }
5993 spin_unlock_irqrestore(&boardp->lock, flags);
5994 }
5995
5996 /*
5997 * If interrupts were enabled on entry, then they
5998 * are now enabled here.
5999 *
6000 * Complete all requests on the done list.
6001 */
6002
6003 asc_scsi_done_list(done_scp);
6004
6005 ASC_DBG(1, "advansys_interrupt: end\n");
6006 return IRQ_HANDLED;
6007}
6008
6009/*
6010 * Set the number of commands to queue per device for the
6011 * specified host adapter.
6012 */
6013STATIC int
6014advansys_slave_configure(struct scsi_device *device)
6015{
6016 asc_board_t *boardp;
6017
6018 boardp = ASC_BOARDP(device->host);
6019 boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
6020 /*
6021 * Save a pointer to the device and set its initial/maximum
6022 * queue depth. Only save the pointer for a lun0 dev though.
6023 */
6024 if(device->lun == 0)
6025 boardp->device[device->id] = device;
6026 if(device->tagged_supported) {
6027 if (ASC_NARROW_BOARD(boardp)) {
6028 scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
6029 boardp->dvc_var.asc_dvc_var.max_dvc_qng[device->id]);
6030 } else {
6031 scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
6032 boardp->dvc_var.adv_dvc_var.max_dvc_qng);
6033 }
6034 } else {
6035 scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun);
6036 }
6037 ASC_DBG4(1, "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n",
6038 (ulong) device, (ulong) boardp, device->id, device->queue_depth);
6039 return 0;
6040}
6041
6042/*
6043 * Complete all requests on the singly linked list pointed
6044 * to by 'scp'.
6045 *
6046 * Interrupts can be enabled on entry.
6047 */
6048STATIC void
6049asc_scsi_done_list(struct scsi_cmnd *scp)
6050{
6051 struct scsi_cmnd *tscp;
6052
6053 ASC_DBG(2, "asc_scsi_done_list: begin\n");
6054 while (scp != NULL) {
6055 asc_board_t *boardp;
6056 struct device *dev;
6057
6058 ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong) scp);
6059 tscp = REQPNEXT(scp);
6060 scp->host_scribble = NULL;
6061
6062 boardp = ASC_BOARDP(scp->device->host);
6063
6064 if (ASC_NARROW_BOARD(boardp))
6065 dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
6066 else
6067 dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
6068
6069 if (scp->use_sg)
6070 dma_unmap_sg(dev, (struct scatterlist *)scp->request_buffer,
6071 scp->use_sg, scp->sc_data_direction);
6072 else if (scp->request_bufflen)
6073 dma_unmap_single(dev, scp->SCp.dma_handle,
6074 scp->request_bufflen, scp->sc_data_direction);
6075
6076 ASC_STATS(scp->device->host, done);
6077 ASC_ASSERT(scp->scsi_done != NULL);
6078
6079 scp->scsi_done(scp);
6080
6081 scp = tscp;
6082 }
6083 ASC_DBG(2, "asc_scsi_done_list: done\n");
6084 return;
6085}
6086
6087/*
6088 * Execute a single 'Scsi_Cmnd'.
6089 *
6090 * The function 'done' is called when the request has been completed.
6091 *
6092 * Scsi_Cmnd:
6093 *
6094 * host - board controlling device
6095 * device - device to send command
6096 * target - target of device
6097 * lun - lun of device
6098 * cmd_len - length of SCSI CDB
6099 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
6100 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
6101 *
6102 * if (use_sg == 0) {
6103 * request_buffer - buffer address for request
6104 * request_bufflen - length of request buffer
6105 * } else {
6106 * request_buffer - pointer to scatterlist structure
6107 * }
6108 *
6109 * sense_buffer - sense command buffer
6110 *
6111 * result (4 bytes of an int):
6112 * Byte Meaning
6113 * 0 SCSI Status Byte Code
6114 * 1 SCSI One Byte Message Code
6115 * 2 Host Error Code
6116 * 3 Mid-Level Error Code
6117 *
6118 * host driver fields:
6119 * SCp - Scsi_Pointer used for command processing status
6120 * scsi_done - used to save caller's done function
6121 * host_scribble - used for pointer to another struct scsi_cmnd
6122 *
6123 * If this function returns ASC_NOERROR the request has been enqueued
6124 * on the board's 'active' queue and will be completed from the
6125 * interrupt handler.
6126 *
6127 * If this function returns ASC_NOERROR the request has been enqueued
6128 * on the board's 'done' queue and must be completed by the caller.
6129 *
6130 * If ASC_BUSY is returned the request will be enqueued by the
6131 * caller on the target's waiting queue and re-tried later.
6132 */
6133STATIC int
6134asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
6135{
6136 asc_board_t *boardp;
6137 ASC_DVC_VAR *asc_dvc_varp;
6138 ADV_DVC_VAR *adv_dvc_varp;
6139 ADV_SCSI_REQ_Q *adv_scsiqp;
6140 struct scsi_device *device;
6141 int ret;
6142
6143 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
6144 (ulong) scp, (ulong) scp->scsi_done);
6145
6146 boardp = ASC_BOARDP(scp->device->host);
6147 device = boardp->device[scp->device->id];
6148
6149 if (ASC_NARROW_BOARD(boardp)) {
6150 /*
6151 * Build and execute Narrow Board request.
6152 */
6153
6154 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6155
6156 /*
6157 * Build Asc Library request structure using the
6158 * global structures 'asc_scsi_req' and 'asc_sg_head'.
6159 *
6160 * If an error is returned, then the request has been
6161 * queued on the board done queue. It will be completed
6162 * by the caller.
6163 *
6164 * asc_build_req() can not return ASC_BUSY.
6165 */
6166 if (asc_build_req(boardp, scp) == ASC_ERROR) {
6167 ASC_STATS(scp->device->host, build_error);
6168 return ASC_ERROR;
6169 }
6170
6171 /*
6172 * Execute the command. If there is no error, add the command
6173 * to the active queue.
6174 */
6175 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
6176 case ASC_NOERROR:
6177 ASC_STATS(scp->device->host, exe_noerror);
6178 /*
6179 * Increment monotonically increasing per device successful
6180 * request counter. Wrapping doesn't matter.
6181 */
6182 boardp->reqcnt[scp->device->id]++;
6183 asc_enqueue(&boardp->active, scp, ASC_BACK);
6184 ASC_DBG(1,
6185 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
6186 break;
6187 case ASC_BUSY:
6188 /*
6189 * Caller will enqueue request on the target's waiting queue
6190 * and retry later.
6191 */
6192 ASC_STATS(scp->device->host, exe_busy);
6193 break;
6194 case ASC_ERROR:
6195 ASC_PRINT2(
6196"asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
6197 boardp->id, asc_dvc_varp->err_code);
6198 ASC_STATS(scp->device->host, exe_error);
6199 scp->result = HOST_BYTE(DID_ERROR);
6200 asc_enqueue(&boardp->done, scp, ASC_BACK);
6201 break;
6202 default:
6203 ASC_PRINT2(
6204"asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
6205 boardp->id, asc_dvc_varp->err_code);
6206 ASC_STATS(scp->device->host, exe_unknown);
6207 scp->result = HOST_BYTE(DID_ERROR);
6208 asc_enqueue(&boardp->done, scp, ASC_BACK);
6209 break;
6210 }
6211 } else {
6212 /*
6213 * Build and execute Wide Board request.
6214 */
6215 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6216
6217 /*
6218 * Build and get a pointer to an Adv Library request structure.
6219 *
6220 * If the request is successfully built then send it below,
6221 * otherwise return with an error.
6222 */
6223 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
6224 case ASC_NOERROR:
6225 ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
6226 break;
6227 case ASC_BUSY:
6228 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
6229 /*
6230 * If busy is returned the request has not been enqueued.
6231 * It will be enqueued by the caller on the target's waiting
6232 * queue and retried later.
6233 *
6234 * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg'
6235 * count wide board busy conditions. They are updated in
6236 * adv_build_req and adv_get_sglist, respectively.
6237 */
6238 return ASC_BUSY;
6239 case ASC_ERROR:
6240 /*
6241 * If an error is returned, then the request has been
6242 * queued on the board done queue. It will be completed
6243 * by the caller.
6244 */
6245 default:
6246 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
6247 ASC_STATS(scp->device->host, build_error);
6248 return ASC_ERROR;
6249 }
6250
6251 /*
6252 * Execute the command. If there is no error, add the command
6253 * to the active queue.
6254 */
6255 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
6256 case ASC_NOERROR:
6257 ASC_STATS(scp->device->host, exe_noerror);
6258 /*
6259 * Increment monotonically increasing per device successful
6260 * request counter. Wrapping doesn't matter.
6261 */
6262 boardp->reqcnt[scp->device->id]++;
6263 asc_enqueue(&boardp->active, scp, ASC_BACK);
6264 ASC_DBG(1,
6265 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
6266 break;
6267 case ASC_BUSY:
6268 /*
6269 * Caller will enqueue request on the target's waiting queue
6270 * and retry later.
6271 */
6272 ASC_STATS(scp->device->host, exe_busy);
6273 break;
6274 case ASC_ERROR:
6275 ASC_PRINT2(
6276"asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
6277 boardp->id, adv_dvc_varp->err_code);
6278 ASC_STATS(scp->device->host, exe_error);
6279 scp->result = HOST_BYTE(DID_ERROR);
6280 asc_enqueue(&boardp->done, scp, ASC_BACK);
6281 break;
6282 default:
6283 ASC_PRINT2(
6284"asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
6285 boardp->id, adv_dvc_varp->err_code);
6286 ASC_STATS(scp->device->host, exe_unknown);
6287 scp->result = HOST_BYTE(DID_ERROR);
6288 asc_enqueue(&boardp->done, scp, ASC_BACK);
6289 break;
6290 }
6291 }
6292
6293 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
6294 return ret;
6295}
6296
6297/*
6298 * Build a request structure for the Asc Library (Narrow Board).
6299 *
6300 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
6301 * used to build the request.
6302 *
6303 * If an error occurs, then queue the request on the board done
6304 * queue and return ASC_ERROR.
6305 */
6306STATIC int
6307asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
6308{
6309 struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
6310
6311 /*
6312 * Mutually exclusive access is required to 'asc_scsi_q' and
6313 * 'asc_sg_head' until after the request is started.
6314 */
6315 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
6316
6317 /*
6318 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
6319 */
6320 asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
6321
6322 /*
6323 * Build the ASC_SCSI_Q request.
6324 *
6325 * For narrow boards a CDB length maximum of 12 bytes
6326 * is supported.
6327 */
6328 if (scp->cmd_len > ASC_MAX_CDB_LEN) {
6329 ASC_PRINT3(
6330"asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN %d\n",
6331 boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN);
6332 scp->result = HOST_BYTE(DID_ERROR);
6333 asc_enqueue(&boardp->done, scp, ASC_BACK);
6334 return ASC_ERROR;
6335 }
6336 asc_scsi_q.cdbptr = &scp->cmnd[0];
6337 asc_scsi_q.q2.cdb_len = scp->cmd_len;
6338 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
6339 asc_scsi_q.q1.target_lun = scp->device->lun;
6340 asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
6341 asc_scsi_q.q1.sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
6342 asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
6343
6344 /*
6345 * If there are any outstanding requests for the current target,
6346 * then every 255th request send an ORDERED request. This heuristic
6347 * tries to retain the benefit of request sorting while preventing
6348 * request starvation. 255 is the max number of tags or pending commands
6349 * a device may have outstanding.
6350 *
6351 * The request count is incremented below for every successfully
6352 * started request.
6353 *
6354 */
6355 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
6356 (boardp->reqcnt[scp->device->id] % 255) == 0) {
6357 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
6358 } else {
6359 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
6360 }
6361
6362 /*
6363 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
6364 * buffer command.
6365 */
6366 if (scp->use_sg == 0) {
6367 /*
6368 * CDB request of single contiguous buffer.
6369 */
6370 ASC_STATS(scp->device->host, cont_cnt);
6371 scp->SCp.dma_handle = scp->request_bufflen ?
6372 dma_map_single(dev, scp->request_buffer,
6373 scp->request_bufflen, scp->sc_data_direction) : 0;
6374 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
6375 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
6376 ASC_STATS_ADD(scp->device->host, cont_xfer,
6377 ASC_CEILING(scp->request_bufflen, 512));
6378 asc_scsi_q.q1.sg_queue_cnt = 0;
6379 asc_scsi_q.sg_head = NULL;
6380 } else {
6381 /*
6382 * CDB scatter-gather request list.
6383 */
6384 int sgcnt;
6385 int use_sg;
6386 struct scatterlist *slp;
6387
6388 slp = (struct scatterlist *)scp->request_buffer;
6389 use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
6390
6391 if (use_sg > scp->device->host->sg_tablesize) {
6392 ASC_PRINT3(
6393"asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
6394 boardp->id, use_sg, scp->device->host->sg_tablesize);
6395 dma_unmap_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
6396 scp->result = HOST_BYTE(DID_ERROR);
6397 asc_enqueue(&boardp->done, scp, ASC_BACK);
6398 return ASC_ERROR;
6399 }
6400
6401 ASC_STATS(scp->device->host, sg_cnt);
6402
6403 /*
6404 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
6405 * structure to point to it.
6406 */
6407 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
6408
6409 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
6410 asc_scsi_q.sg_head = &asc_sg_head;
6411 asc_scsi_q.q1.data_cnt = 0;
6412 asc_scsi_q.q1.data_addr = 0;
6413 /* This is a byte value, otherwise it would need to be swapped. */
6414 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
6415 ASC_STATS_ADD(scp->device->host, sg_elem, asc_sg_head.entry_cnt);
6416
6417 /*
6418 * Convert scatter-gather list into ASC_SG_HEAD list.
6419 */
6420 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
6421 asc_sg_head.sg_list[sgcnt].addr = cpu_to_le32(sg_dma_address(slp));
6422 asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(sg_dma_len(slp));
6423 ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512));
6424 }
6425 }
6426
6427 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
6428 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6429
6430 return ASC_NOERROR;
6431}
6432
6433/*
6434 * Build a request structure for the Adv Library (Wide Board).
6435 *
6436 * If an adv_req_t can not be allocated to issue the request,
6437 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
6438 *
6439 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
6440 * microcode for DMA addresses or math operations are byte swapped
6441 * to little-endian order.
6442 */
6443STATIC int
6444adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
6445 ADV_SCSI_REQ_Q **adv_scsiqpp)
6446{
6447 adv_req_t *reqp;
6448 ADV_SCSI_REQ_Q *scsiqp;
6449 int i;
6450 int ret;
6451 struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
6452
6453 /*
6454 * Allocate an adv_req_t structure from the board to execute
6455 * the command.
6456 */
6457 if (boardp->adv_reqp == NULL) {
6458 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
6459 ASC_STATS(scp->device->host, adv_build_noreq);
6460 return ASC_BUSY;
6461 } else {
6462 reqp = boardp->adv_reqp;
6463 boardp->adv_reqp = reqp->next_reqp;
6464 reqp->next_reqp = NULL;
6465 }
6466
6467 /*
6468 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
6469 */
6470 scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
6471
6472 /*
6473 * Initialize the structure.
6474 */
6475 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
6476
6477 /*
6478 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
6479 */
6480 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
6481
6482 /*
6483 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
6484 */
6485 reqp->cmndp = scp;
6486
6487 /*
6488 * Build the ADV_SCSI_REQ_Q request.
6489 */
6490
6491 /*
6492 * Set CDB length and copy it to the request structure.
6493 * For wide boards a CDB length maximum of 16 bytes
6494 * is supported.
6495 */
6496 if (scp->cmd_len > ADV_MAX_CDB_LEN) {
6497 ASC_PRINT3(
6498"adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n",
6499 boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
6500 scp->result = HOST_BYTE(DID_ERROR);
6501 asc_enqueue(&boardp->done, scp, ASC_BACK);
6502 return ASC_ERROR;
6503 }
6504 scsiqp->cdb_len = scp->cmd_len;
6505 /* Copy first 12 CDB bytes to cdb[]. */
6506 for (i = 0; i < scp->cmd_len && i < 12; i++) {
6507 scsiqp->cdb[i] = scp->cmnd[i];
6508 }
6509 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
6510 for (; i < scp->cmd_len; i++) {
6511 scsiqp->cdb16[i - 12] = scp->cmnd[i];
6512 }
6513
6514 scsiqp->target_id = scp->device->id;
6515 scsiqp->target_lun = scp->device->lun;
6516
6517 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
6518 scsiqp->sense_len = sizeof(scp->sense_buffer);
6519
6520 /*
6521 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
6522 * buffer command.
6523 */
6524
6525 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
6526 scsiqp->vdata_addr = scp->request_buffer;
6527 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
6528
6529 if (scp->use_sg == 0) {
6530 /*
6531 * CDB request of single contiguous buffer.
6532 */
6533 reqp->sgblkp = NULL;
6534 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
6535 if (scp->request_bufflen) {
6536 scsiqp->vdata_addr = scp->request_buffer;
6537 scp->SCp.dma_handle =
6538 dma_map_single(dev, scp->request_buffer,
6539 scp->request_bufflen, scp->sc_data_direction);
6540 } else {
aa7677d4 6541 scsiqp->vdata_addr = NULL;
1da177e4
LT
6542 scp->SCp.dma_handle = 0;
6543 }
6544 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
6545 scsiqp->sg_list_ptr = NULL;
6546 scsiqp->sg_real_addr = 0;
6547 ASC_STATS(scp->device->host, cont_cnt);
6548 ASC_STATS_ADD(scp->device->host, cont_xfer,
6549 ASC_CEILING(scp->request_bufflen, 512));
6550 } else {
6551 /*
6552 * CDB scatter-gather request list.
6553 */
6554 struct scatterlist *slp;
6555 int use_sg;
6556
6557 slp = (struct scatterlist *)scp->request_buffer;
6558 use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
6559
6560 if (use_sg > ADV_MAX_SG_LIST) {
6561 ASC_PRINT3(
6562"adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
6563 boardp->id, use_sg, scp->device->host->sg_tablesize);
6564 dma_unmap_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
6565 scp->result = HOST_BYTE(DID_ERROR);
6566 asc_enqueue(&boardp->done, scp, ASC_BACK);
6567
6568 /*
6569 * Free the 'adv_req_t' structure by adding it back to the
6570 * board free list.
6571 */
6572 reqp->next_reqp = boardp->adv_reqp;
6573 boardp->adv_reqp = reqp;
6574
6575 return ASC_ERROR;
6576 }
6577
6578 if ((ret = adv_get_sglist(boardp, reqp, scp, use_sg)) != ADV_SUCCESS) {
6579 /*
6580 * Free the adv_req_t structure by adding it back to the
6581 * board free list.
6582 */
6583 reqp->next_reqp = boardp->adv_reqp;
6584 boardp->adv_reqp = reqp;
6585
6586 return ret;
6587 }
6588
6589 ASC_STATS(scp->device->host, sg_cnt);
6590 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
6591 }
6592
6593 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
6594 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6595
6596 *adv_scsiqpp = scsiqp;
6597
6598 return ASC_NOERROR;
6599}
6600
6601/*
6602 * Build scatter-gather list for Adv Library (Wide Board).
6603 *
6604 * Additional ADV_SG_BLOCK structures will need to be allocated
6605 * if the total number of scatter-gather elements exceeds
6606 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
6607 * assumed to be physically contiguous.
6608 *
6609 * Return:
6610 * ADV_SUCCESS(1) - SG List successfully created
6611 * ADV_ERROR(-1) - SG List creation failed
6612 */
6613STATIC int
6614adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, int use_sg)
6615{
6616 adv_sgblk_t *sgblkp;
6617 ADV_SCSI_REQ_Q *scsiqp;
6618 struct scatterlist *slp;
6619 int sg_elem_cnt;
6620 ADV_SG_BLOCK *sg_block, *prev_sg_block;
6621 ADV_PADDR sg_block_paddr;
6622 int i;
6623
6624 scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
6625 slp = (struct scatterlist *) scp->request_buffer;
6626 sg_elem_cnt = use_sg;
6627 prev_sg_block = NULL;
6628 reqp->sgblkp = NULL;
6629
6630 do
6631 {
6632 /*
6633 * Allocate a 'adv_sgblk_t' structure from the board free
6634 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
6635 * (15) scatter-gather elements.
6636 */
6637 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
6638 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
6639 ASC_STATS(scp->device->host, adv_build_nosg);
6640
6641 /*
6642 * Allocation failed. Free 'adv_sgblk_t' structures already
6643 * allocated for the request.
6644 */
6645 while ((sgblkp = reqp->sgblkp) != NULL)
6646 {
6647 /* Remove 'sgblkp' from the request list. */
6648 reqp->sgblkp = sgblkp->next_sgblkp;
6649
6650 /* Add 'sgblkp' to the board free list. */
6651 sgblkp->next_sgblkp = boardp->adv_sgblkp;
6652 boardp->adv_sgblkp = sgblkp;
6653 }
6654 return ASC_BUSY;
6655 } else {
6656 /* Complete 'adv_sgblk_t' board allocation. */
6657 boardp->adv_sgblkp = sgblkp->next_sgblkp;
6658 sgblkp->next_sgblkp = NULL;
6659
6660 /*
6661 * Get 8 byte aligned virtual and physical addresses for
6662 * the allocated ADV_SG_BLOCK structure.
6663 */
6664 sg_block = (ADV_SG_BLOCK *) ADV_8BALIGN(&sgblkp->sg_block);
6665 sg_block_paddr = virt_to_bus(sg_block);
6666
6667 /*
6668 * Check if this is the first 'adv_sgblk_t' for the request.
6669 */
6670 if (reqp->sgblkp == NULL)
6671 {
6672 /* Request's first scatter-gather block. */
6673 reqp->sgblkp = sgblkp;
6674
6675 /*
6676 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
6677 * address pointers.
6678 */
6679 scsiqp->sg_list_ptr = sg_block;
6680 scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr);
6681 } else
6682 {
6683 /* Request's second or later scatter-gather block. */
6684 sgblkp->next_sgblkp = reqp->sgblkp;
6685 reqp->sgblkp = sgblkp;
6686
6687 /*
6688 * Point the previous ADV_SG_BLOCK structure to
6689 * the newly allocated ADV_SG_BLOCK structure.
6690 */
6691 ASC_ASSERT(prev_sg_block != NULL);
6692 prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr);
6693 }
6694 }
6695
6696 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
6697 {
6698 sg_block->sg_list[i].sg_addr = cpu_to_le32(sg_dma_address(slp));
6699 sg_block->sg_list[i].sg_count = cpu_to_le32(sg_dma_len(slp));
6700 ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512));
6701
6702 if (--sg_elem_cnt == 0)
6703 { /* Last ADV_SG_BLOCK and scatter-gather entry. */
6704 sg_block->sg_cnt = i + 1;
6705 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
6706 return ADV_SUCCESS;
6707 }
6708 slp++;
6709 }
6710 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
6711 prev_sg_block = sg_block;
6712 }
6713 while (1);
6714 /* NOTREACHED */
6715}
6716
6717/*
6718 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
6719 *
6720 * Interrupt callback function for the Narrow SCSI Asc Library.
6721 */
6722STATIC void
6723asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
6724{
6725 asc_board_t *boardp;
6726 struct scsi_cmnd *scp;
6727 struct Scsi_Host *shp;
6728 int i;
6729
6730 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
6731 (ulong) asc_dvc_varp, (ulong) qdonep);
6732 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
6733
6734 /*
6735 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
6736 * command that has been completed.
6737 */
6738 scp = (struct scsi_cmnd *) ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
6739 ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong) scp);
6740
6741 if (scp == NULL) {
6742 ASC_PRINT("asc_isr_callback: scp is NULL\n");
6743 return;
6744 }
6745 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
6746
6747 /*
6748 * If the request's host pointer is not valid, display a
6749 * message and return.
6750 */
6751 shp = scp->device->host;
6752 for (i = 0; i < asc_board_count; i++) {
6753 if (asc_host[i] == shp) {
6754 break;
6755 }
6756 }
6757 if (i == asc_board_count) {
6758 ASC_PRINT2(
6759 "asc_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
6760 (ulong) scp, (ulong) shp);
6761 return;
6762 }
6763
6764 ASC_STATS(shp, callback);
6765 ASC_DBG1(1, "asc_isr_callback: shp 0x%lx\n", (ulong) shp);
6766
6767 /*
6768 * If the request isn't found on the active queue, it may
6769 * have been removed to handle a reset request.
6770 * Display a message and return.
6771 */
6772 boardp = ASC_BOARDP(shp);
6773 ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
6774 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
6775 ASC_PRINT2(
6776 "asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
6777 boardp->id, (ulong) scp);
6778 return;
6779 }
6780
6781 /*
6782 * 'qdonep' contains the command's ending status.
6783 */
6784 switch (qdonep->d3.done_stat) {
6785 case QD_NO_ERROR:
6786 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
6787 scp->result = 0;
6788
6789 /*
6790 * If an INQUIRY command completed successfully, then call
6791 * the AscInquiryHandling() function to set-up the device.
6792 */
6793 if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 &&
6794 (scp->request_bufflen - qdonep->remain_bytes) >= 8)
6795 {
6796 AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7,
6797 (ASC_SCSI_INQUIRY *) scp->request_buffer);
6798 }
6799
6800 /*
6801 * Check for an underrun condition.
6802 *
6803 * If there was no error and an underrun condition, then
6804 * then return the number of underrun bytes.
6805 */
6806 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
6807 qdonep->remain_bytes <= scp->request_bufflen) {
6808 ASC_DBG1(1, "asc_isr_callback: underrun condition %u bytes\n",
6809 (unsigned) qdonep->remain_bytes);
6810 scp->resid = qdonep->remain_bytes;
6811 }
6812 break;
6813
6814 case QD_WITH_ERROR:
6815 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
6816 switch (qdonep->d3.host_stat) {
6817 case QHSTA_NO_ERROR:
6818 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
6819 ASC_DBG(2, "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
6820 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
6821 sizeof(scp->sense_buffer));
6822 /*
6823 * Note: The 'status_byte()' macro used by target drivers
6824 * defined in scsi.h shifts the status byte returned by
6825 * host drivers right by 1 bit. This is why target drivers
6826 * also use right shifted status byte definitions. For
6827 * instance target drivers use CHECK_CONDITION, defined to
6828 * 0x1, instead of the SCSI defined check condition value
6829 * of 0x2. Host drivers are supposed to return the status
6830 * byte as it is defined by SCSI.
6831 */
6832 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
6833 STATUS_BYTE(qdonep->d3.scsi_stat);
6834 } else {
6835 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
6836 }
6837 break;
6838
6839 default:
6840 /* QHSTA error occurred */
6841 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
6842 qdonep->d3.host_stat);
6843 scp->result = HOST_BYTE(DID_BAD_TARGET);
6844 break;
6845 }
6846 break;
6847
6848 case QD_ABORTED_BY_HOST:
6849 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
6850 scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.scsi_msg) |
6851 STATUS_BYTE(qdonep->d3.scsi_stat);
6852 break;
6853
6854 default:
6855 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n", qdonep->d3.done_stat);
6856 scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
6857 STATUS_BYTE(qdonep->d3.scsi_stat);
6858 break;
6859 }
6860
6861 /*
6862 * If the 'init_tidmask' bit isn't already set for the target and the
6863 * current request finished normally, then set the bit for the target
6864 * to indicate that a device is present.
6865 */
6866 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
6867 qdonep->d3.done_stat == QD_NO_ERROR &&
6868 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
6869 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
6870 }
6871
6872 /*
6873 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
6874 * function, add the command to the end of the board's done queue.
6875 * The done function for the command will be called from
6876 * advansys_interrupt().
6877 */
6878 asc_enqueue(&boardp->done, scp, ASC_BACK);
6879
6880 return;
6881}
6882
6883/*
6884 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
6885 *
6886 * Callback function for the Wide SCSI Adv Library.
6887 */
6888STATIC void
6889adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
6890{
6891 asc_board_t *boardp;
6892 adv_req_t *reqp;
6893 adv_sgblk_t *sgblkp;
6894 struct scsi_cmnd *scp;
6895 struct Scsi_Host *shp;
6896 int i;
6897 ADV_DCNT resid_cnt;
6898
6899
6900 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
6901 (ulong) adv_dvc_varp, (ulong) scsiqp);
6902 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
6903
6904 /*
6905 * Get the adv_req_t structure for the command that has been
6906 * completed. The adv_req_t structure actually contains the
6907 * completed ADV_SCSI_REQ_Q structure.
6908 */
6909 reqp = (adv_req_t *) ADV_U32_TO_VADDR(scsiqp->srb_ptr);
6910 ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong) reqp);
6911 if (reqp == NULL) {
6912 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
6913 return;
6914 }
6915
6916 /*
6917 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
6918 * command that has been completed.
6919 *
6920 * Note: The adv_req_t request structure and adv_sgblk_t structure,
6921 * if any, are dropped, because a board structure pointer can not be
6922 * determined.
6923 */
6924 scp = reqp->cmndp;
6925 ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong) scp);
6926 if (scp == NULL) {
6927 ASC_PRINT("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
6928 return;
6929 }
6930 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
6931
6932 /*
6933 * If the request's host pointer is not valid, display a message
6934 * and return.
6935 */
6936 shp = scp->device->host;
6937 for (i = 0; i < asc_board_count; i++) {
6938 if (asc_host[i] == shp) {
6939 break;
6940 }
6941 }
6942 /*
6943 * Note: If the host structure is not found, the adv_req_t request
6944 * structure and adv_sgblk_t structure, if any, is dropped.
6945 */
6946 if (i == asc_board_count) {
6947 ASC_PRINT2(
6948 "adv_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
6949 (ulong) scp, (ulong) shp);
6950 return;
6951 }
6952
6953 ASC_STATS(shp, callback);
6954 ASC_DBG1(1, "adv_isr_callback: shp 0x%lx\n", (ulong) shp);
6955
6956 /*
6957 * If the request isn't found on the active queue, it may have been
6958 * removed to handle a reset request. Display a message and return.
6959 *
6960 * Note: Because the structure may still be in use don't attempt
6961 * to free the adv_req_t and adv_sgblk_t, if any, structures.
6962 */
6963 boardp = ASC_BOARDP(shp);
6964 ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
6965 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
6966 ASC_PRINT2(
6967 "adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
6968 boardp->id, (ulong) scp);
6969 return;
6970 }
6971
6972 /*
6973 * 'done_status' contains the command's ending status.
6974 */
6975 switch (scsiqp->done_status) {
6976 case QD_NO_ERROR:
6977 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
6978 scp->result = 0;
6979
6980 /*
6981 * Check for an underrun condition.
6982 *
6983 * If there was no error and an underrun condition, then
6984 * then return the number of underrun bytes.
6985 */
6986 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
6987 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
6988 resid_cnt <= scp->request_bufflen) {
6989 ASC_DBG1(1, "adv_isr_callback: underrun condition %lu bytes\n",
6990 (ulong) resid_cnt);
6991 scp->resid = resid_cnt;
6992 }
6993 break;
6994
6995 case QD_WITH_ERROR:
6996 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
6997 switch (scsiqp->host_status) {
6998 case QHSTA_NO_ERROR:
6999 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
7000 ASC_DBG(2, "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
7001 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
7002 sizeof(scp->sense_buffer));
7003 /*
7004 * Note: The 'status_byte()' macro used by target drivers
7005 * defined in scsi.h shifts the status byte returned by
7006 * host drivers right by 1 bit. This is why target drivers
7007 * also use right shifted status byte definitions. For
7008 * instance target drivers use CHECK_CONDITION, defined to
7009 * 0x1, instead of the SCSI defined check condition value
7010 * of 0x2. Host drivers are supposed to return the status
7011 * byte as it is defined by SCSI.
7012 */
7013 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
7014 STATUS_BYTE(scsiqp->scsi_status);
7015 } else {
7016 scp->result = STATUS_BYTE(scsiqp->scsi_status);
7017 }
7018 break;
7019
7020 default:
7021 /* Some other QHSTA error occurred. */
7022 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
7023 scsiqp->host_status);
7024 scp->result = HOST_BYTE(DID_BAD_TARGET);
7025 break;
7026 }
7027 break;
7028
7029 case QD_ABORTED_BY_HOST:
7030 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
7031 scp->result = HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
7032 break;
7033
7034 default:
7035 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n", scsiqp->done_status);
7036 scp->result = HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
7037 break;
7038 }
7039
7040 /*
7041 * If the 'init_tidmask' bit isn't already set for the target and the
7042 * current request finished normally, then set the bit for the target
7043 * to indicate that a device is present.
7044 */
7045 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
7046 scsiqp->done_status == QD_NO_ERROR &&
7047 scsiqp->host_status == QHSTA_NO_ERROR) {
7048 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
7049 }
7050
7051 /*
7052 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
7053 * function, add the command to the end of the board's done queue.
7054 * The done function for the command will be called from
7055 * advansys_interrupt().
7056 */
7057 asc_enqueue(&boardp->done, scp, ASC_BACK);
7058
7059 /*
7060 * Free all 'adv_sgblk_t' structures allocated for the request.
7061 */
7062 while ((sgblkp = reqp->sgblkp) != NULL)
7063 {
7064 /* Remove 'sgblkp' from the request list. */
7065 reqp->sgblkp = sgblkp->next_sgblkp;
7066
7067 /* Add 'sgblkp' to the board free list. */
7068 sgblkp->next_sgblkp = boardp->adv_sgblkp;
7069 boardp->adv_sgblkp = sgblkp;
7070 }
7071
7072 /*
7073 * Free the adv_req_t structure used with the command by adding
7074 * it back to the board free list.
7075 */
7076 reqp->next_reqp = boardp->adv_reqp;
7077 boardp->adv_reqp = reqp;
7078
7079 ASC_DBG(1, "adv_isr_callback: done\n");
7080
7081 return;
7082}
7083
7084/*
7085 * adv_async_callback() - Adv Library asynchronous event callback function.
7086 */
7087STATIC void
7088adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
7089{
7090 switch (code)
7091 {
7092 case ADV_ASYNC_SCSI_BUS_RESET_DET:
7093 /*
7094 * The firmware detected a SCSI Bus reset.
7095 */
7096 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
7097 break;
7098
7099 case ADV_ASYNC_RDMA_FAILURE:
7100 /*
7101 * Handle RDMA failure by resetting the SCSI Bus and
7102 * possibly the chip if it is unresponsive. Log the error
7103 * with a unique code.
7104 */
7105 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
7106 AdvResetChipAndSB(adv_dvc_varp);
7107 break;
7108
7109 case ADV_HOST_SCSI_BUS_RESET:
7110 /*
7111 * Host generated SCSI bus reset occurred.
7112 */
7113 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
7114 break;
7115
7116 default:
7117 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
7118 break;
7119 }
7120}
7121
7122/*
7123 * Add a 'REQP' to the end of specified queue. Set 'tidmask'
7124 * to indicate a command is queued for the device.
7125 *
7126 * 'flag' may be either ASC_FRONT or ASC_BACK.
7127 *
7128 * 'REQPNEXT(reqp)' returns reqp's next pointer.
7129 */
7130STATIC void
7131asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
7132{
7133 int tid;
7134
7135 ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
7136 (ulong) ascq, (ulong) reqp, flag);
7137 ASC_ASSERT(reqp != NULL);
7138 ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
7139 tid = REQPTID(reqp);
7140 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7141 if (flag == ASC_FRONT) {
7142 reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
7143 ascq->q_first[tid] = reqp;
7144 /* If the queue was empty, set the last pointer. */
7145 if (ascq->q_last[tid] == NULL) {
7146 ascq->q_last[tid] = reqp;
7147 }
7148 } else { /* ASC_BACK */
7149 if (ascq->q_last[tid] != NULL) {
7150 ascq->q_last[tid]->host_scribble = (unsigned char *)reqp;
7151 }
7152 ascq->q_last[tid] = reqp;
7153 reqp->host_scribble = NULL;
7154 /* If the queue was empty, set the first pointer. */
7155 if (ascq->q_first[tid] == NULL) {
7156 ascq->q_first[tid] = reqp;
7157 }
7158 }
7159 /* The queue has at least one entry, set its bit. */
7160 ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
7161#ifdef ADVANSYS_STATS
7162 /* Maintain request queue statistics. */
7163 ascq->q_tot_cnt[tid]++;
7164 ascq->q_cur_cnt[tid]++;
7165 if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
7166 ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
7167 ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
7168 tid, ascq->q_max_cnt[tid]);
7169 }
7170 REQPTIME(reqp) = REQTIMESTAMP();
7171#endif /* ADVANSYS_STATS */
7172 ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong) reqp);
7173 return;
7174}
7175
7176/*
7177 * Return first queued 'REQP' on the specified queue for
7178 * the specified target device. Clear the 'tidmask' bit for
7179 * the device if no more commands are left queued for it.
7180 *
7181 * 'REQPNEXT(reqp)' returns reqp's next pointer.
7182 */
7183STATIC REQP
7184asc_dequeue(asc_queue_t *ascq, int tid)
7185{
7186 REQP reqp;
7187
7188 ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong) ascq, tid);
7189 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7190 if ((reqp = ascq->q_first[tid]) != NULL) {
7191 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
7192 ascq->q_first[tid] = REQPNEXT(reqp);
7193 /* If the queue is empty, clear its bit and the last pointer. */
7194 if (ascq->q_first[tid] == NULL) {
7195 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7196 ASC_ASSERT(ascq->q_last[tid] == reqp);
7197 ascq->q_last[tid] = NULL;
7198 }
7199#ifdef ADVANSYS_STATS
7200 /* Maintain request queue statistics. */
7201 ascq->q_cur_cnt[tid]--;
7202 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
7203 REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
7204#endif /* ADVANSYS_STATS */
7205 }
7206 ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong) reqp);
7207 return reqp;
7208}
7209
7210/*
7211 * Return a pointer to a singly linked list of all the requests queued
7212 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
7213 *
7214 * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
7215 * the last request returned in the singly linked list.
7216 *
7217 * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
7218 * then all queued requests are concatenated into one list and
7219 * returned.
7220 *
7221 * Note: If 'lastpp' is used to append a new list to the end of
7222 * an old list, only change the old list last pointer if '*lastpp'
7223 * (or the function return value) is not NULL, i.e. use a temporary
7224 * variable for 'lastpp' and check its value after the function return
7225 * before assigning it to the list last pointer.
7226 *
7227 * Unfortunately collecting queuing time statistics adds overhead to
7228 * the function that isn't inherent to the function's algorithm.
7229 */
7230STATIC REQP
7231asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
7232{
7233 REQP firstp, lastp;
7234 int i;
7235
7236 ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong) ascq, tid);
7237 ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
7238
7239 /*
7240 * If 'tid' is not ASC_TID_ALL, return requests only for
7241 * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
7242 * requests for all tids.
7243 */
7244 if (tid != ASC_TID_ALL) {
7245 /* Return all requests for the specified 'tid'. */
7246 if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
7247 /* List is empty; Set first and last return pointers to NULL. */
7248 firstp = lastp = NULL;
7249 } else {
7250 firstp = ascq->q_first[tid];
7251 lastp = ascq->q_last[tid];
7252 ascq->q_first[tid] = ascq->q_last[tid] = NULL;
7253 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7254#ifdef ADVANSYS_STATS
7255 {
7256 REQP reqp;
7257 ascq->q_cur_cnt[tid] = 0;
7258 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
7259 REQTIMESTAT("asc_dequeue_list", ascq, reqp, tid);
7260 }
7261 }
7262#endif /* ADVANSYS_STATS */
7263 }
7264 } else {
7265 /* Return all requests for all tids. */
7266 firstp = lastp = NULL;
7267 for (i = 0; i <= ADV_MAX_TID; i++) {
7268 if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
7269 if (firstp == NULL) {
7270 firstp = ascq->q_first[i];
7271 lastp = ascq->q_last[i];
7272 } else {
7273 ASC_ASSERT(lastp != NULL);
7274 lastp->host_scribble = (unsigned char *)ascq->q_first[i];
7275 lastp = ascq->q_last[i];
7276 }
7277 ascq->q_first[i] = ascq->q_last[i] = NULL;
7278 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7279#ifdef ADVANSYS_STATS
7280 ascq->q_cur_cnt[i] = 0;
7281#endif /* ADVANSYS_STATS */
7282 }
7283 }
7284#ifdef ADVANSYS_STATS
7285 {
7286 REQP reqp;
7287 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
7288 REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->device->id);
7289 }
7290 }
7291#endif /* ADVANSYS_STATS */
7292 }
7293 if (lastpp) {
7294 *lastpp = lastp;
7295 }
7296 ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong) firstp);
7297 return firstp;
7298}
7299
7300/*
7301 * Remove the specified 'REQP' from the specified queue for
7302 * the specified target device. Clear the 'tidmask' bit for the
7303 * device if no more commands are left queued for it.
7304 *
7305 * 'REQPNEXT(reqp)' returns reqp's the next pointer.
7306 *
7307 * Return ASC_TRUE if the command was found and removed,
7308 * otherwise return ASC_FALSE.
7309 */
7310STATIC int
7311asc_rmqueue(asc_queue_t *ascq, REQP reqp)
7312{
7313 REQP currp, prevp;
7314 int tid;
7315 int ret = ASC_FALSE;
7316
7317 ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
7318 (ulong) ascq, (ulong) reqp);
7319 ASC_ASSERT(reqp != NULL);
7320
7321 tid = REQPTID(reqp);
7322 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7323
7324 /*
7325 * Handle the common case of 'reqp' being the first
7326 * entry on the queue.
7327 */
7328 if (reqp == ascq->q_first[tid]) {
7329 ret = ASC_TRUE;
7330 ascq->q_first[tid] = REQPNEXT(reqp);
7331 /* If the queue is now empty, clear its bit and the last pointer. */
7332 if (ascq->q_first[tid] == NULL) {
7333 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7334 ASC_ASSERT(ascq->q_last[tid] == reqp);
7335 ascq->q_last[tid] = NULL;
7336 }
7337 } else if (ascq->q_first[tid] != NULL) {
7338 ASC_ASSERT(ascq->q_last[tid] != NULL);
7339 /*
7340 * Because the case of 'reqp' being the first entry has been
7341 * handled above and it is known the queue is not empty, if
7342 * 'reqp' is found on the queue it is guaranteed the queue will
7343 * not become empty and that 'q_first[tid]' will not be changed.
7344 *
7345 * Set 'prevp' to the first entry, 'currp' to the second entry,
7346 * and search for 'reqp'.
7347 */
7348 for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
7349 currp; prevp = currp, currp = REQPNEXT(currp)) {
7350 if (currp == reqp) {
7351 ret = ASC_TRUE;
7352 prevp->host_scribble = (unsigned char *)REQPNEXT(currp);
7353 reqp->host_scribble = NULL;
7354 if (ascq->q_last[tid] == reqp) {
7355 ascq->q_last[tid] = prevp;
7356 }
7357 break;
7358 }
7359 }
7360 }
7361#ifdef ADVANSYS_STATS
7362 /* Maintain request queue statistics. */
7363 if (ret == ASC_TRUE) {
7364 ascq->q_cur_cnt[tid]--;
7365 REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
7366 }
7367 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
7368#endif /* ADVANSYS_STATS */
7369 ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong) reqp, ret);
7370 return ret;
7371}
7372
7373/*
7374 * Execute as many queued requests as possible for the specified queue.
7375 *
7376 * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd.
7377 */
7378STATIC void
7379asc_execute_queue(asc_queue_t *ascq)
7380{
7381 ADV_SCSI_BIT_ID_TYPE scan_tidmask;
7382 REQP reqp;
7383 int i;
7384
7385 ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong) ascq);
7386 /*
7387 * Execute queued commands for devices attached to
7388 * the current board in round-robin fashion.
7389 */
7390 scan_tidmask = ascq->q_tidmask;
7391 do {
7392 for (i = 0; i <= ADV_MAX_TID; i++) {
7393 if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
7394 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
7395 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7396 } else if (asc_execute_scsi_cmnd((struct scsi_cmnd *) reqp)
7397 == ASC_BUSY) {
7398 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7399 /*
7400 * The request returned ASC_BUSY. Enqueue at the front of
7401 * target's waiting list to maintain correct ordering.
7402 */
7403 asc_enqueue(ascq, reqp, ASC_FRONT);
7404 }
7405 }
7406 }
7407 } while (scan_tidmask);
7408 return;
7409}
7410
7411#ifdef CONFIG_PROC_FS
7412/*
7413 * asc_prt_board_devices()
7414 *
7415 * Print driver information for devices attached to the board.
7416 *
7417 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7418 * cf. asc_prt_line().
7419 *
7420 * Return the number of characters copied into 'cp'. No more than
7421 * 'cplen' characters will be copied to 'cp'.
7422 */
7423STATIC int
7424asc_prt_board_devices(struct Scsi_Host *shp, char *cp, int cplen)
7425{
7426 asc_board_t *boardp;
7427 int leftlen;
7428 int totlen;
7429 int len;
7430 int chip_scsi_id;
7431 int i;
7432
7433 boardp = ASC_BOARDP(shp);
7434 leftlen = cplen;
7435 totlen = len = 0;
7436
7437 len = asc_prt_line(cp, leftlen,
7438"\nDevice Information for AdvanSys SCSI Host %d:\n", shp->host_no);
7439 ASC_PRT_NEXT();
7440
7441 if (ASC_NARROW_BOARD(boardp)) {
7442 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7443 } else {
7444 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7445 }
7446
7447 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
7448 ASC_PRT_NEXT();
7449 for (i = 0; i <= ADV_MAX_TID; i++) {
7450 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
7451 len = asc_prt_line(cp, leftlen, " %X,", i);
7452 ASC_PRT_NEXT();
7453 }
7454 }
7455 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
7456 ASC_PRT_NEXT();
7457
7458 return totlen;
7459}
7460
7461/*
7462 * Display Wide Board BIOS Information.
7463 */
7464STATIC int
7465asc_prt_adv_bios(struct Scsi_Host *shp, char *cp, int cplen)
7466{
7467 asc_board_t *boardp;
7468 int leftlen;
7469 int totlen;
7470 int len;
7471 ushort major, minor, letter;
7472
7473 boardp = ASC_BOARDP(shp);
7474 leftlen = cplen;
7475 totlen = len = 0;
7476
7477 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
7478 ASC_PRT_NEXT();
7479
7480 /*
7481 * If the BIOS saved a valid signature, then fill in
7482 * the BIOS code segment base address.
7483 */
7484 if (boardp->bios_signature != 0x55AA) {
7485 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
7486 ASC_PRT_NEXT();
7487 len = asc_prt_line(cp, leftlen,
7488"BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
7489 ASC_PRT_NEXT();
7490 len = asc_prt_line(cp, leftlen,
7491"can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
7492 ASC_PRT_NEXT();
7493 } else {
7494 major = (boardp->bios_version >> 12) & 0xF;
7495 minor = (boardp->bios_version >> 8) & 0xF;
7496 letter = (boardp->bios_version & 0xFF);
7497
7498 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
7499 major, minor, letter >= 26 ? '?' : letter + 'A');
7500 ASC_PRT_NEXT();
7501
7502 /*
7503 * Current available ROM BIOS release is 3.1I for UW
7504 * and 3.2I for U2W. This code doesn't differentiate
7505 * UW and U2W boards.
7506 */
7507 if (major < 3 || (major <= 3 && minor < 1) ||
7508 (major <= 3 && minor <= 1 && letter < ('I'- 'A'))) {
7509 len = asc_prt_line(cp, leftlen,
7510"Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
7511 ASC_PRT_NEXT();
7512 len = asc_prt_line(cp, leftlen,
7513"ftp://ftp.connectcom.net/pub\n");
7514 ASC_PRT_NEXT();
7515 }
7516 }
7517
7518 return totlen;
7519}
7520
7521/*
7522 * Add serial number to information bar if signature AAh
7523 * is found in at bit 15-9 (7 bits) of word 1.
7524 *
7525 * Serial Number consists fo 12 alpha-numeric digits.
7526 *
7527 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
7528 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
7529 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
7530 * 5 - Product revision (A-J) Word0: " "
7531 *
7532 * Signature Word1: 15-9 (7 bits)
7533 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
7534 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
7535 *
7536 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
7537 *
7538 * Note 1: Only production cards will have a serial number.
7539 *
7540 * Note 2: Signature is most significant 7 bits (0xFE).
7541 *
7542 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
7543 */
7544STATIC int
7545asc_get_eeprom_string(ushort *serialnum, uchar *cp)
7546{
7547 ushort w, num;
7548
7549 if ((serialnum[1] & 0xFE00) != ((ushort) 0xAA << 8)) {
7550 return ASC_FALSE;
7551 } else {
7552 /*
7553 * First word - 6 digits.
7554 */
7555 w = serialnum[0];
7556
7557 /* Product type - 1st digit. */
7558 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
7559 /* Product type is P=Prototype */
7560 *cp += 0x8;
7561 }
7562 cp++;
7563
7564 /* Manufacturing location - 2nd digit. */
7565 *cp++ = 'A' + ((w & 0x1C00) >> 10);
7566
7567 /* Product ID - 3rd, 4th digits. */
7568 num = w & 0x3FF;
7569 *cp++ = '0' + (num / 100);
7570 num %= 100;
7571 *cp++ = '0' + (num / 10);
7572
7573 /* Product revision - 5th digit. */
7574 *cp++ = 'A' + (num % 10);
7575
7576 /*
7577 * Second word
7578 */
7579 w = serialnum[1];
7580
7581 /*
7582 * Year - 6th digit.
7583 *
7584 * If bit 15 of third word is set, then the
7585 * last digit of the year is greater than 7.
7586 */
7587 if (serialnum[2] & 0x8000) {
7588 *cp++ = '8' + ((w & 0x1C0) >> 6);
7589 } else {
7590 *cp++ = '0' + ((w & 0x1C0) >> 6);
7591 }
7592
7593 /* Week of year - 7th, 8th digits. */
7594 num = w & 0x003F;
7595 *cp++ = '0' + num / 10;
7596 num %= 10;
7597 *cp++ = '0' + num;
7598
7599 /*
7600 * Third word
7601 */
7602 w = serialnum[2] & 0x7FFF;
7603
7604 /* Serial number - 9th digit. */
7605 *cp++ = 'A' + (w / 1000);
7606
7607 /* 10th, 11th, 12th digits. */
7608 num = w % 1000;
7609 *cp++ = '0' + num / 100;
7610 num %= 100;
7611 *cp++ = '0' + num / 10;
7612 num %= 10;
7613 *cp++ = '0' + num;
7614
7615 *cp = '\0'; /* Null Terminate the string. */
7616 return ASC_TRUE;
7617 }
7618}
7619
7620/*
7621 * asc_prt_asc_board_eeprom()
7622 *
7623 * Print board EEPROM configuration.
7624 *
7625 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7626 * cf. asc_prt_line().
7627 *
7628 * Return the number of characters copied into 'cp'. No more than
7629 * 'cplen' characters will be copied to 'cp'.
7630 */
7631STATIC int
7632asc_prt_asc_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
7633{
7634 asc_board_t *boardp;
7635 ASC_DVC_VAR *asc_dvc_varp;
7636 int leftlen;
7637 int totlen;
7638 int len;
7639 ASCEEP_CONFIG *ep;
7640 int i;
7641#ifdef CONFIG_ISA
7642 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
7643#endif /* CONFIG_ISA */
7644 uchar serialstr[13];
7645
7646 boardp = ASC_BOARDP(shp);
7647 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
7648 ep = &boardp->eep_config.asc_eep;
7649
7650 leftlen = cplen;
7651 totlen = len = 0;
7652
7653 len = asc_prt_line(cp, leftlen,
7654"\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
7655 ASC_PRT_NEXT();
7656
7657 if (asc_get_eeprom_string((ushort *) &ep->adapter_info[0], serialstr) ==
7658 ASC_TRUE) {
7659 len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
7660 ASC_PRT_NEXT();
7661 } else {
7662 if (ep->adapter_info[5] == 0xBB) {
7663 len = asc_prt_line(cp, leftlen,
7664 " Default Settings Used for EEPROM-less Adapter.\n");
7665 ASC_PRT_NEXT();
7666 } else {
7667 len = asc_prt_line(cp, leftlen,
7668 " Serial Number Signature Not Present.\n");
7669 ASC_PRT_NEXT();
7670 }
7671 }
7672
7673 len = asc_prt_line(cp, leftlen,
7674" Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7675 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng, ep->max_tag_qng);
7676 ASC_PRT_NEXT();
7677
7678 len = asc_prt_line(cp, leftlen,
7679" cntl 0x%x, no_scam 0x%x\n",
7680 ep->cntl, ep->no_scam);
7681 ASC_PRT_NEXT();
7682
7683 len = asc_prt_line(cp, leftlen,
7684" Target ID: ");
7685 ASC_PRT_NEXT();
7686 for (i = 0; i <= ASC_MAX_TID; i++) {
7687 len = asc_prt_line(cp, leftlen, " %d", i);
7688 ASC_PRT_NEXT();
7689 }
7690 len = asc_prt_line(cp, leftlen, "\n");
7691 ASC_PRT_NEXT();
7692
7693 len = asc_prt_line(cp, leftlen,
7694" Disconnects: ");
7695 ASC_PRT_NEXT();
7696 for (i = 0; i <= ASC_MAX_TID; i++) {
7697 len = asc_prt_line(cp, leftlen, " %c",
7698 (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7699 ASC_PRT_NEXT();
7700 }
7701 len = asc_prt_line(cp, leftlen, "\n");
7702 ASC_PRT_NEXT();
7703
7704 len = asc_prt_line(cp, leftlen,
7705" Command Queuing: ");
7706 ASC_PRT_NEXT();
7707 for (i = 0; i <= ASC_MAX_TID; i++) {
7708 len = asc_prt_line(cp, leftlen, " %c",
7709 (ep->use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7710 ASC_PRT_NEXT();
7711 }
7712 len = asc_prt_line(cp, leftlen, "\n");
7713 ASC_PRT_NEXT();
7714
7715 len = asc_prt_line(cp, leftlen,
7716" Start Motor: ");
7717 ASC_PRT_NEXT();
7718 for (i = 0; i <= ASC_MAX_TID; i++) {
7719 len = asc_prt_line(cp, leftlen, " %c",
7720 (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7721 ASC_PRT_NEXT();
7722 }
7723 len = asc_prt_line(cp, leftlen, "\n");
7724 ASC_PRT_NEXT();
7725
7726 len = asc_prt_line(cp, leftlen,
7727" Synchronous Transfer:");
7728 ASC_PRT_NEXT();
7729 for (i = 0; i <= ASC_MAX_TID; i++) {
7730 len = asc_prt_line(cp, leftlen, " %c",
7731 (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7732 ASC_PRT_NEXT();
7733 }
7734 len = asc_prt_line(cp, leftlen, "\n");
7735 ASC_PRT_NEXT();
7736
7737#ifdef CONFIG_ISA
7738 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
7739 len = asc_prt_line(cp, leftlen,
7740" Host ISA DMA speed: %d MB/S\n",
7741 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
7742 ASC_PRT_NEXT();
7743 }
7744#endif /* CONFIG_ISA */
7745
7746 return totlen;
7747}
7748
7749/*
7750 * asc_prt_adv_board_eeprom()
7751 *
7752 * Print board EEPROM configuration.
7753 *
7754 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7755 * cf. asc_prt_line().
7756 *
7757 * Return the number of characters copied into 'cp'. No more than
7758 * 'cplen' characters will be copied to 'cp'.
7759 */
7760STATIC int
7761asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
7762{
7763 asc_board_t *boardp;
7764 ADV_DVC_VAR *adv_dvc_varp;
7765 int leftlen;
7766 int totlen;
7767 int len;
7768 int i;
7769 char *termstr;
7770 uchar serialstr[13];
7771 ADVEEP_3550_CONFIG *ep_3550 = NULL;
7772 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
7773 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
7774 ushort word;
7775 ushort *wordp;
7776 ushort sdtr_speed = 0;
7777
7778 boardp = ASC_BOARDP(shp);
7779 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
7780 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7781 {
7782 ep_3550 = &boardp->eep_config.adv_3550_eep;
7783 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7784 {
7785 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
7786 } else
7787 {
7788 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
7789 }
7790
7791 leftlen = cplen;
7792 totlen = len = 0;
7793
7794 len = asc_prt_line(cp, leftlen,
7795"\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
7796 ASC_PRT_NEXT();
7797
7798 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7799 {
7800 wordp = &ep_3550->serial_number_word1;
7801 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7802 {
7803 wordp = &ep_38C0800->serial_number_word1;
7804 } else
7805 {
7806 wordp = &ep_38C1600->serial_number_word1;
7807 }
7808
7809 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
7810 len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
7811 ASC_PRT_NEXT();
7812 } else {
7813 len = asc_prt_line(cp, leftlen,
7814 " Serial Number Signature Not Present.\n");
7815 ASC_PRT_NEXT();
7816 }
7817
7818 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7819 {
7820 len = asc_prt_line(cp, leftlen,
7821" Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7822 ep_3550->adapter_scsi_id, ep_3550->max_host_qng,
7823 ep_3550->max_dvc_qng);
7824 ASC_PRT_NEXT();
7825 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7826 {
7827 len = asc_prt_line(cp, leftlen,
7828" Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7829 ep_38C0800->adapter_scsi_id, ep_38C0800->max_host_qng,
7830 ep_38C0800->max_dvc_qng);
7831 ASC_PRT_NEXT();
7832 } else
7833 {
7834 len = asc_prt_line(cp, leftlen,
7835" Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7836 ep_38C1600->adapter_scsi_id, ep_38C1600->max_host_qng,
7837 ep_38C1600->max_dvc_qng);
7838 ASC_PRT_NEXT();
7839 }
7840 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7841 {
7842 word = ep_3550->termination;
7843 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7844 {
7845 word = ep_38C0800->termination_lvd;
7846 } else
7847 {
7848 word = ep_38C1600->termination_lvd;
7849 }
7850 switch (word) {
7851 case 1:
7852 termstr = "Low Off/High Off";
7853 break;
7854 case 2:
7855 termstr = "Low Off/High On";
7856 break;
7857 case 3:
7858 termstr = "Low On/High On";
7859 break;
7860 default:
7861 case 0:
7862 termstr = "Automatic";
7863 break;
7864 }
7865
7866 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7867 {
7868 len = asc_prt_line(cp, leftlen,
7869" termination: %u (%s), bios_ctrl: 0x%x\n",
7870 ep_3550->termination, termstr, ep_3550->bios_ctrl);
7871 ASC_PRT_NEXT();
7872 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7873 {
7874 len = asc_prt_line(cp, leftlen,
7875" termination: %u (%s), bios_ctrl: 0x%x\n",
7876 ep_38C0800->termination_lvd, termstr, ep_38C0800->bios_ctrl);
7877 ASC_PRT_NEXT();
7878 } else
7879 {
7880 len = asc_prt_line(cp, leftlen,
7881" termination: %u (%s), bios_ctrl: 0x%x\n",
7882 ep_38C1600->termination_lvd, termstr, ep_38C1600->bios_ctrl);
7883 ASC_PRT_NEXT();
7884 }
7885
7886 len = asc_prt_line(cp, leftlen,
7887" Target ID: ");
7888 ASC_PRT_NEXT();
7889 for (i = 0; i <= ADV_MAX_TID; i++) {
7890 len = asc_prt_line(cp, leftlen, " %X", i);
7891 ASC_PRT_NEXT();
7892 }
7893 len = asc_prt_line(cp, leftlen, "\n");
7894 ASC_PRT_NEXT();
7895
7896 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7897 {
7898 word = ep_3550->disc_enable;
7899 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7900 {
7901 word = ep_38C0800->disc_enable;
7902 } else
7903 {
7904 word = ep_38C1600->disc_enable;
7905 }
7906 len = asc_prt_line(cp, leftlen,
7907" Disconnects: ");
7908 ASC_PRT_NEXT();
7909 for (i = 0; i <= ADV_MAX_TID; i++) {
7910 len = asc_prt_line(cp, leftlen, " %c",
7911 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7912 ASC_PRT_NEXT();
7913 }
7914 len = asc_prt_line(cp, leftlen, "\n");
7915 ASC_PRT_NEXT();
7916
7917 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7918 {
7919 word = ep_3550->tagqng_able;
7920 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7921 {
7922 word = ep_38C0800->tagqng_able;
7923 } else
7924 {
7925 word = ep_38C1600->tagqng_able;
7926 }
7927 len = asc_prt_line(cp, leftlen,
7928" Command Queuing: ");
7929 ASC_PRT_NEXT();
7930 for (i = 0; i <= ADV_MAX_TID; i++) {
7931 len = asc_prt_line(cp, leftlen, " %c",
7932 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7933 ASC_PRT_NEXT();
7934 }
7935 len = asc_prt_line(cp, leftlen, "\n");
7936 ASC_PRT_NEXT();
7937
7938 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7939 {
7940 word = ep_3550->start_motor;
7941 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7942 {
7943 word = ep_38C0800->start_motor;
7944 } else
7945 {
7946 word = ep_38C1600->start_motor;
7947 }
7948 len = asc_prt_line(cp, leftlen,
7949" Start Motor: ");
7950 ASC_PRT_NEXT();
7951 for (i = 0; i <= ADV_MAX_TID; i++) {
7952 len = asc_prt_line(cp, leftlen, " %c",
7953 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7954 ASC_PRT_NEXT();
7955 }
7956 len = asc_prt_line(cp, leftlen, "\n");
7957 ASC_PRT_NEXT();
7958
7959 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7960 {
7961 len = asc_prt_line(cp, leftlen,
7962" Synchronous Transfer:");
7963 ASC_PRT_NEXT();
7964 for (i = 0; i <= ADV_MAX_TID; i++) {
7965 len = asc_prt_line(cp, leftlen, " %c",
7966 (ep_3550->sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7967 ASC_PRT_NEXT();
7968 }
7969 len = asc_prt_line(cp, leftlen, "\n");
7970 ASC_PRT_NEXT();
7971 }
7972
7973 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7974 {
7975 len = asc_prt_line(cp, leftlen,
7976" Ultra Transfer: ");
7977 ASC_PRT_NEXT();
7978 for (i = 0; i <= ADV_MAX_TID; i++) {
7979 len = asc_prt_line(cp, leftlen, " %c",
7980 (ep_3550->ultra_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7981 ASC_PRT_NEXT();
7982 }
7983 len = asc_prt_line(cp, leftlen, "\n");
7984 ASC_PRT_NEXT();
7985 }
7986
7987 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7988 {
7989 word = ep_3550->wdtr_able;
7990 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7991 {
7992 word = ep_38C0800->wdtr_able;
7993 } else
7994 {
7995 word = ep_38C1600->wdtr_able;
7996 }
7997 len = asc_prt_line(cp, leftlen,
7998" Wide Transfer: ");
7999 ASC_PRT_NEXT();
8000 for (i = 0; i <= ADV_MAX_TID; i++) {
8001 len = asc_prt_line(cp, leftlen, " %c",
8002 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8003 ASC_PRT_NEXT();
8004 }
8005 len = asc_prt_line(cp, leftlen, "\n");
8006 ASC_PRT_NEXT();
8007
8008 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
8009 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600)
8010 {
8011 len = asc_prt_line(cp, leftlen,
8012" Synchronous Transfer Speed (Mhz):\n ");
8013 ASC_PRT_NEXT();
8014 for (i = 0; i <= ADV_MAX_TID; i++) {
8015 char *speed_str;
8016
8017 if (i == 0)
8018 {
8019 sdtr_speed = adv_dvc_varp->sdtr_speed1;
8020 } else if (i == 4)
8021 {
8022 sdtr_speed = adv_dvc_varp->sdtr_speed2;
8023 } else if (i == 8)
8024 {
8025 sdtr_speed = adv_dvc_varp->sdtr_speed3;
8026 } else if (i == 12)
8027 {
8028 sdtr_speed = adv_dvc_varp->sdtr_speed4;
8029 }
8030 switch (sdtr_speed & ADV_MAX_TID)
8031 {
8032 case 0: speed_str = "Off"; break;
8033 case 1: speed_str = " 5"; break;
8034 case 2: speed_str = " 10"; break;
8035 case 3: speed_str = " 20"; break;
8036 case 4: speed_str = " 40"; break;
8037 case 5: speed_str = " 80"; break;
8038 default: speed_str = "Unk"; break;
8039 }
8040 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
8041 ASC_PRT_NEXT();
8042 if (i == 7)
8043 {
8044 len = asc_prt_line(cp, leftlen, "\n ");
8045 ASC_PRT_NEXT();
8046 }
8047 sdtr_speed >>= 4;
8048 }
8049 len = asc_prt_line(cp, leftlen, "\n");
8050 ASC_PRT_NEXT();
8051 }
8052
8053 return totlen;
8054}
8055
8056/*
8057 * asc_prt_driver_conf()
8058 *
8059 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8060 * cf. asc_prt_line().
8061 *
8062 * Return the number of characters copied into 'cp'. No more than
8063 * 'cplen' characters will be copied to 'cp'.
8064 */
8065STATIC int
8066asc_prt_driver_conf(struct Scsi_Host *shp, char *cp, int cplen)
8067{
8068 asc_board_t *boardp;
8069 int leftlen;
8070 int totlen;
8071 int len;
8072 int chip_scsi_id;
8073
8074 boardp = ASC_BOARDP(shp);
8075
8076 leftlen = cplen;
8077 totlen = len = 0;
8078
8079 len = asc_prt_line(cp, leftlen,
8080"\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
8081 shp->host_no);
8082 ASC_PRT_NEXT();
8083
8084 len = asc_prt_line(cp, leftlen,
8085" host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
8086 shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun,
8087 shp->max_channel);
8088 ASC_PRT_NEXT();
8089
8090 len = asc_prt_line(cp, leftlen,
8091" unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
8092 shp->unique_id, shp->can_queue, shp->this_id, shp->sg_tablesize,
8093 shp->cmd_per_lun);
8094 ASC_PRT_NEXT();
8095
8096 len = asc_prt_line(cp, leftlen,
8097" unchecked_isa_dma %d, use_clustering %d\n",
8098 shp->unchecked_isa_dma, shp->use_clustering);
8099 ASC_PRT_NEXT();
8100
8101 len = asc_prt_line(cp, leftlen,
8102" flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
8103 boardp->flags, boardp->last_reset, jiffies, boardp->asc_n_io_port);
8104 ASC_PRT_NEXT();
8105
8106 /* 'shp->n_io_port' may be truncated because it is only one byte. */
8107 len = asc_prt_line(cp, leftlen,
8108" io_port 0x%x, n_io_port 0x%x\n",
8109 shp->io_port, shp->n_io_port);
8110 ASC_PRT_NEXT();
8111
8112 if (ASC_NARROW_BOARD(boardp)) {
8113 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
8114 } else {
8115 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
8116 }
8117
8118 return totlen;
8119}
8120
8121/*
8122 * asc_prt_asc_board_info()
8123 *
8124 * Print dynamic board configuration information.
8125 *
8126 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8127 * cf. asc_prt_line().
8128 *
8129 * Return the number of characters copied into 'cp'. No more than
8130 * 'cplen' characters will be copied to 'cp'.
8131 */
8132STATIC int
8133asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8134{
8135 asc_board_t *boardp;
8136 int chip_scsi_id;
8137 int leftlen;
8138 int totlen;
8139 int len;
8140 ASC_DVC_VAR *v;
8141 ASC_DVC_CFG *c;
8142 int i;
8143 int renegotiate = 0;
8144
8145 boardp = ASC_BOARDP(shp);
8146 v = &boardp->dvc_var.asc_dvc_var;
8147 c = &boardp->dvc_cfg.asc_dvc_cfg;
8148 chip_scsi_id = c->chip_scsi_id;
8149
8150 leftlen = cplen;
8151 totlen = len = 0;
8152
8153 len = asc_prt_line(cp, leftlen,
8154"\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8155 shp->host_no);
8156 ASC_PRT_NEXT();
8157
8158 len = asc_prt_line(cp, leftlen,
8159" chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
8160 c->chip_version, c->lib_version, c->lib_serial_no, c->mcode_date);
8161 ASC_PRT_NEXT();
8162
8163 len = asc_prt_line(cp, leftlen,
8164" mcode_version 0x%x, err_code %u\n",
8165 c->mcode_version, v->err_code);
8166 ASC_PRT_NEXT();
8167
8168 /* Current number of commands waiting for the host. */
8169 len = asc_prt_line(cp, leftlen,
8170" Total Command Pending: %d\n", v->cur_total_qng);
8171 ASC_PRT_NEXT();
8172
8173 len = asc_prt_line(cp, leftlen,
8174" Command Queuing:");
8175 ASC_PRT_NEXT();
8176 for (i = 0; i <= ASC_MAX_TID; i++) {
8177 if ((chip_scsi_id == i) ||
8178 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8179 continue;
8180 }
8181 len = asc_prt_line(cp, leftlen, " %X:%c",
8182 i, (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8183 ASC_PRT_NEXT();
8184 }
8185 len = asc_prt_line(cp, leftlen, "\n");
8186 ASC_PRT_NEXT();
8187
8188 /* Current number of commands waiting for a device. */
8189 len = asc_prt_line(cp, leftlen,
8190" Command Queue Pending:");
8191 ASC_PRT_NEXT();
8192 for (i = 0; i <= ASC_MAX_TID; i++) {
8193 if ((chip_scsi_id == i) ||
8194 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8195 continue;
8196 }
8197 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
8198 ASC_PRT_NEXT();
8199 }
8200 len = asc_prt_line(cp, leftlen, "\n");
8201 ASC_PRT_NEXT();
8202
8203 /* Current limit on number of commands that can be sent to a device. */
8204 len = asc_prt_line(cp, leftlen,
8205" Command Queue Limit:");
8206 ASC_PRT_NEXT();
8207 for (i = 0; i <= ASC_MAX_TID; i++) {
8208 if ((chip_scsi_id == i) ||
8209 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8210 continue;
8211 }
8212 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
8213 ASC_PRT_NEXT();
8214 }
8215 len = asc_prt_line(cp, leftlen, "\n");
8216 ASC_PRT_NEXT();
8217
8218 /* Indicate whether the device has returned queue full status. */
8219 len = asc_prt_line(cp, leftlen,
8220" Command Queue Full:");
8221 ASC_PRT_NEXT();
8222 for (i = 0; i <= ASC_MAX_TID; i++) {
8223 if ((chip_scsi_id == i) ||
8224 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8225 continue;
8226 }
8227 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
8228 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
8229 i, boardp->queue_full_cnt[i]);
8230 } else {
8231 len = asc_prt_line(cp, leftlen, " %X:N", i);
8232 }
8233 ASC_PRT_NEXT();
8234 }
8235 len = asc_prt_line(cp, leftlen, "\n");
8236 ASC_PRT_NEXT();
8237
8238 len = asc_prt_line(cp, leftlen,
8239" Synchronous Transfer:");
8240 ASC_PRT_NEXT();
8241 for (i = 0; i <= ASC_MAX_TID; i++) {
8242 if ((chip_scsi_id == i) ||
8243 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8244 continue;
8245 }
8246 len = asc_prt_line(cp, leftlen, " %X:%c",
8247 i, (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8248 ASC_PRT_NEXT();
8249 }
8250 len = asc_prt_line(cp, leftlen, "\n");
8251 ASC_PRT_NEXT();
8252
8253 for (i = 0; i <= ASC_MAX_TID; i++) {
8254 uchar syn_period_ix;
8255
8256 if ((chip_scsi_id == i) ||
8257 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
8258 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
8259 continue;
8260 }
8261
8262 len = asc_prt_line(cp, leftlen, " %X:", i);
8263 ASC_PRT_NEXT();
8264
8265 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0)
8266 {
8267 len = asc_prt_line(cp, leftlen, " Asynchronous");
8268 ASC_PRT_NEXT();
8269 } else
8270 {
8271 syn_period_ix =
8272 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1);
8273
8274 len = asc_prt_line(cp, leftlen,
8275 " Transfer Period Factor: %d (%d.%d Mhz),",
8276 v->sdtr_period_tbl[syn_period_ix],
8277 250 / v->sdtr_period_tbl[syn_period_ix],
8278 ASC_TENTHS(250, v->sdtr_period_tbl[syn_period_ix]));
8279 ASC_PRT_NEXT();
8280
8281 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
8282 boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET);
8283 ASC_PRT_NEXT();
8284 }
8285
8286 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8287 len = asc_prt_line(cp, leftlen, "*\n");
8288 renegotiate = 1;
8289 } else
8290 {
8291 len = asc_prt_line(cp, leftlen, "\n");
8292 }
8293 ASC_PRT_NEXT();
8294 }
8295
8296 if (renegotiate)
8297 {
8298 len = asc_prt_line(cp, leftlen,
8299 " * = Re-negotiation pending before next command.\n");
8300 ASC_PRT_NEXT();
8301 }
8302
8303 return totlen;
8304}
8305
8306/*
8307 * asc_prt_adv_board_info()
8308 *
8309 * Print dynamic board configuration information.
8310 *
8311 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8312 * cf. asc_prt_line().
8313 *
8314 * Return the number of characters copied into 'cp'. No more than
8315 * 'cplen' characters will be copied to 'cp'.
8316 */
8317STATIC int
8318asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8319{
8320 asc_board_t *boardp;
8321 int leftlen;
8322 int totlen;
8323 int len;
8324 int i;
8325 ADV_DVC_VAR *v;
8326 ADV_DVC_CFG *c;
8327 AdvPortAddr iop_base;
8328 ushort chip_scsi_id;
8329 ushort lramword;
8330 uchar lrambyte;
8331 ushort tagqng_able;
8332 ushort sdtr_able, wdtr_able;
8333 ushort wdtr_done, sdtr_done;
8334 ushort period = 0;
8335 int renegotiate = 0;
8336
8337 boardp = ASC_BOARDP(shp);
8338 v = &boardp->dvc_var.adv_dvc_var;
8339 c = &boardp->dvc_cfg.adv_dvc_cfg;
8340 iop_base = v->iop_base;
8341 chip_scsi_id = v->chip_scsi_id;
8342
8343 leftlen = cplen;
8344 totlen = len = 0;
8345
8346 len = asc_prt_line(cp, leftlen,
8347"\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8348 shp->host_no);
8349 ASC_PRT_NEXT();
8350
8351 len = asc_prt_line(cp, leftlen,
8352" iop_base 0x%lx, cable_detect: %X, err_code %u\n",
8353 v->iop_base,
8354 AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1) & CABLE_DETECT,
8355 v->err_code);
8356 ASC_PRT_NEXT();
8357
8358 len = asc_prt_line(cp, leftlen,
8359" chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
8360 c->chip_version, c->lib_version, c->mcode_date, c->mcode_version);
8361 ASC_PRT_NEXT();
8362
8363 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8364 len = asc_prt_line(cp, leftlen,
8365" Queuing Enabled:");
8366 ASC_PRT_NEXT();
8367 for (i = 0; i <= ADV_MAX_TID; i++) {
8368 if ((chip_scsi_id == i) ||
8369 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8370 continue;
8371 }
8372
8373 len = asc_prt_line(cp, leftlen, " %X:%c",
8374 i, (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8375 ASC_PRT_NEXT();
8376 }
8377 len = asc_prt_line(cp, leftlen, "\n");
8378 ASC_PRT_NEXT();
8379
8380 len = asc_prt_line(cp, leftlen,
8381" Queue Limit:");
8382 ASC_PRT_NEXT();
8383 for (i = 0; i <= ADV_MAX_TID; i++) {
8384 if ((chip_scsi_id == i) ||
8385 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8386 continue;
8387 }
8388
8389 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, lrambyte);
8390
8391 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
8392 ASC_PRT_NEXT();
8393 }
8394 len = asc_prt_line(cp, leftlen, "\n");
8395 ASC_PRT_NEXT();
8396
8397 len = asc_prt_line(cp, leftlen,
8398" Command Pending:");
8399 ASC_PRT_NEXT();
8400 for (i = 0; i <= ADV_MAX_TID; i++) {
8401 if ((chip_scsi_id == i) ||
8402 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8403 continue;
8404 }
8405
8406 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, lrambyte);
8407
8408 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
8409 ASC_PRT_NEXT();
8410 }
8411 len = asc_prt_line(cp, leftlen, "\n");
8412 ASC_PRT_NEXT();
8413
8414 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8415 len = asc_prt_line(cp, leftlen,
8416" Wide Enabled:");
8417 ASC_PRT_NEXT();
8418 for (i = 0; i <= ADV_MAX_TID; i++) {
8419 if ((chip_scsi_id == i) ||
8420 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8421 continue;
8422 }
8423
8424 len = asc_prt_line(cp, leftlen, " %X:%c",
8425 i, (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8426 ASC_PRT_NEXT();
8427 }
8428 len = asc_prt_line(cp, leftlen, "\n");
8429 ASC_PRT_NEXT();
8430
8431 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
8432 len = asc_prt_line(cp, leftlen,
8433" Transfer Bit Width:");
8434 ASC_PRT_NEXT();
8435 for (i = 0; i <= ADV_MAX_TID; i++) {
8436 if ((chip_scsi_id == i) ||
8437 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8438 continue;
8439 }
8440
8441 AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
8442 lramword);
8443
8444 len = asc_prt_line(cp, leftlen, " %X:%d",
8445 i, (lramword & 0x8000) ? 16 : 8);
8446 ASC_PRT_NEXT();
8447
8448 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
8449 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8450 len = asc_prt_line(cp, leftlen, "*");
8451 ASC_PRT_NEXT();
8452 renegotiate = 1;
8453 }
8454 }
8455 len = asc_prt_line(cp, leftlen, "\n");
8456 ASC_PRT_NEXT();
8457
8458 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8459 len = asc_prt_line(cp, leftlen,
8460" Synchronous Enabled:");
8461 ASC_PRT_NEXT();
8462 for (i = 0; i <= ADV_MAX_TID; i++) {
8463 if ((chip_scsi_id == i) ||
8464 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8465 continue;
8466 }
8467
8468 len = asc_prt_line(cp, leftlen, " %X:%c",
8469 i, (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8470 ASC_PRT_NEXT();
8471 }
8472 len = asc_prt_line(cp, leftlen, "\n");
8473 ASC_PRT_NEXT();
8474
8475 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
8476 for (i = 0; i <= ADV_MAX_TID; i++) {
8477
8478 AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
8479 lramword);
8480 lramword &= ~0x8000;
8481
8482 if ((chip_scsi_id == i) ||
8483 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
8484 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
8485 continue;
8486 }
8487
8488 len = asc_prt_line(cp, leftlen, " %X:", i);
8489 ASC_PRT_NEXT();
8490
8491 if ((lramword & 0x1F) == 0) /* Check for REQ/ACK Offset 0. */
8492 {
8493 len = asc_prt_line(cp, leftlen, " Asynchronous");
8494 ASC_PRT_NEXT();
8495 } else
8496 {
8497 len = asc_prt_line(cp, leftlen, " Transfer Period Factor: ");
8498 ASC_PRT_NEXT();
8499
8500 if ((lramword & 0x1F00) == 0x1100) /* 80 Mhz */
8501 {
8502 len = asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
8503 ASC_PRT_NEXT();
8504 } else if ((lramword & 0x1F00) == 0x1000) /* 40 Mhz */
8505 {
8506 len = asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
8507 ASC_PRT_NEXT();
8508 } else /* 20 Mhz or below. */
8509 {
8510 period = (((lramword >> 8) * 25) + 50)/4;
8511
8512 if (period == 0) /* Should never happen. */
8513 {
8514 len = asc_prt_line(cp, leftlen, "%d (? Mhz), ");
8515 ASC_PRT_NEXT();
8516 } else
8517 {
8518 len = asc_prt_line(cp, leftlen,
8519 "%d (%d.%d Mhz),",
8520 period, 250/period, ASC_TENTHS(250, period));
8521 ASC_PRT_NEXT();
8522 }
8523 }
8524
8525 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
8526 lramword & 0x1F);
8527 ASC_PRT_NEXT();
8528 }
8529
8530 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8531 len = asc_prt_line(cp, leftlen, "*\n");
8532 renegotiate = 1;
8533 } else
8534 {
8535 len = asc_prt_line(cp, leftlen, "\n");
8536 }
8537 ASC_PRT_NEXT();
8538 }
8539
8540 if (renegotiate)
8541 {
8542 len = asc_prt_line(cp, leftlen,
8543 " * = Re-negotiation pending before next command.\n");
8544 ASC_PRT_NEXT();
8545 }
8546
8547 return totlen;
8548}
8549
8550/*
8551 * asc_proc_copy()
8552 *
8553 * Copy proc information to a read buffer taking into account the current
8554 * read offset in the file and the remaining space in the read buffer.
8555 */
8556STATIC int
8557asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
8558 char *cp, int cplen)
8559{
8560 int cnt = 0;
8561
8562 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
8563 (unsigned) offset, (unsigned) advoffset, cplen);
8564 if (offset <= advoffset) {
8565 /* Read offset below current offset, copy everything. */
8566 cnt = min(cplen, leftlen);
8567 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
8568 (ulong) curbuf, (ulong) cp, cnt);
8569 memcpy(curbuf, cp, cnt);
8570 } else if (offset < advoffset + cplen) {
8571 /* Read offset within current range, partial copy. */
8572 cnt = (advoffset + cplen) - offset;
8573 cp = (cp + cplen) - cnt;
8574 cnt = min(cnt, leftlen);
8575 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
8576 (ulong) curbuf, (ulong) cp, cnt);
8577 memcpy(curbuf, cp, cnt);
8578 }
8579 return cnt;
8580}
8581
8582/*
8583 * asc_prt_line()
8584 *
8585 * If 'cp' is NULL print to the console, otherwise print to a buffer.
8586 *
8587 * Return 0 if printing to the console, otherwise return the number of
8588 * bytes written to the buffer.
8589 *
8590 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
8591 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
8592 */
8593STATIC int
8594asc_prt_line(char *buf, int buflen, char *fmt, ...)
8595{
8596 va_list args;
8597 int ret;
8598 char s[ASC_PRTLINE_SIZE];
8599
8600 va_start(args, fmt);
8601 ret = vsprintf(s, fmt, args);
8602 ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
8603 if (buf == NULL) {
8604 (void) printk(s);
8605 ret = 0;
8606 } else {
8607 ret = min(buflen, ret);
8608 memcpy(buf, s, ret);
8609 }
8610 va_end(args);
8611 return ret;
8612}
8613#endif /* CONFIG_PROC_FS */
8614
8615
8616/*
8617 * --- Functions Required by the Asc Library
8618 */
8619
8620/*
8621 * Delay for 'n' milliseconds. Don't use the 'jiffies'
8622 * global variable which is incremented once every 5 ms
8623 * from a timer interrupt, because this function may be
8624 * called when interrupts are disabled.
8625 */
8626STATIC void
8627DvcSleepMilliSecond(ADV_DCNT n)
8628{
8629 ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong) n);
8630 mdelay(n);
8631}
8632
8633/*
8634 * Currently and inline noop but leave as a placeholder.
8635 * Leave DvcEnterCritical() as a noop placeholder.
8636 */
8637STATIC inline ulong
8638DvcEnterCritical(void)
8639{
8640 return 0;
8641}
8642
8643/*
8644 * Critical sections are all protected by the board spinlock.
8645 * Leave DvcLeaveCritical() as a noop placeholder.
8646 */
8647STATIC inline void
8648DvcLeaveCritical(ulong flags)
8649{
8650 return;
8651}
8652
8653/*
8654 * void
8655 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
8656 *
8657 * Calling/Exit State:
8658 * none
8659 *
8660 * Description:
8661 * Output an ASC_SCSI_Q structure to the chip
8662 */
8663STATIC void
8664DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
8665{
8666 int i;
8667
8668 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
8669 AscSetChipLramAddr(iop_base, s_addr);
8670 for (i = 0; i < 2 * words; i += 2) {
8671 if (i == 4 || i == 20) {
8672 continue;
8673 }
8674 outpw(iop_base + IOP_RAM_DATA,
8675 ((ushort) outbuf[i + 1] << 8) | outbuf[i]);
8676 }
8677}
8678
8679/*
8680 * void
8681 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
8682 *
8683 * Calling/Exit State:
8684 * none
8685 *
8686 * Description:
8687 * Input an ASC_QDONE_INFO structure from the chip
8688 */
8689STATIC void
8690DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
8691{
8692 int i;
8693 ushort word;
8694
8695 AscSetChipLramAddr(iop_base, s_addr);
8696 for (i = 0; i < 2 * words; i += 2) {
8697 if (i == 10) {
8698 continue;
8699 }
8700 word = inpw(iop_base + IOP_RAM_DATA);
8701 inbuf[i] = word & 0xff;
8702 inbuf[i + 1] = (word >> 8) & 0xff;
8703 }
8704 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
8705}
8706
8707/*
8708 * Read a PCI configuration byte.
8709 */
8710STATIC uchar __init
8711DvcReadPCIConfigByte(
8712 ASC_DVC_VAR *asc_dvc,
8713 ushort offset)
8714{
8715#ifdef CONFIG_PCI
8716 uchar byte_data;
8717 pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
8718 return byte_data;
8719#else /* !defined(CONFIG_PCI) */
8720 return 0;
8721#endif /* !defined(CONFIG_PCI) */
8722}
8723
8724/*
8725 * Write a PCI configuration byte.
8726 */
8727STATIC void __init
8728DvcWritePCIConfigByte(
8729 ASC_DVC_VAR *asc_dvc,
8730 ushort offset,
8731 uchar byte_data)
8732{
8733#ifdef CONFIG_PCI
8734 pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
8735#endif /* CONFIG_PCI */
8736}
8737
8738/*
8739 * Return the BIOS address of the adapter at the specified
8740 * I/O port and with the specified bus type.
8741 */
8742STATIC ushort __init
8743AscGetChipBiosAddress(
8744 PortAddr iop_base,
8745 ushort bus_type)
8746{
8747 ushort cfg_lsw;
8748 ushort bios_addr;
8749
8750 /*
8751 * The PCI BIOS is re-located by the motherboard BIOS. Because
8752 * of this the driver can not determine where a PCI BIOS is
8753 * loaded and executes.
8754 */
8755 if (bus_type & ASC_IS_PCI)
8756 {
8757 return(0);
8758 }
8759
8760#ifdef CONFIG_ISA
8761 if((bus_type & ASC_IS_EISA) != 0)
8762 {
8763 cfg_lsw = AscGetEisaChipCfg(iop_base);
8764 cfg_lsw &= 0x000F;
8765 bios_addr = (ushort)(ASC_BIOS_MIN_ADDR +
8766 (cfg_lsw * ASC_BIOS_BANK_SIZE));
8767 return(bios_addr);
8768 }/* if */
8769#endif /* CONFIG_ISA */
8770
8771 cfg_lsw = AscGetChipCfgLsw(iop_base);
8772
8773 /*
8774 * ISA PnP uses the top bit as the 32K BIOS flag
8775 */
8776 if (bus_type == ASC_IS_ISAPNP)
8777 {
8778 cfg_lsw &= 0x7FFF;
8779 }/* if */
8780
8781 bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
8782 ASC_BIOS_MIN_ADDR);
8783 return(bios_addr);
8784}
8785
8786
8787/*
8788 * --- Functions Required by the Adv Library
8789 */
8790
8791/*
8792 * DvcGetPhyAddr()
8793 *
8794 * Return the physical address of 'vaddr' and set '*lenp' to the
8795 * number of physically contiguous bytes that follow 'vaddr'.
8796 * 'flag' indicates the type of structure whose physical address
8797 * is being translated.
8798 *
8799 * Note: Because Linux currently doesn't page the kernel and all
8800 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
8801 */
8802ADV_PADDR
8803DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
8804 uchar *vaddr, ADV_SDCNT *lenp, int flag)
8805{
8806 ADV_PADDR paddr;
8807
8808 paddr = virt_to_bus(vaddr);
8809
8810 ASC_DBG4(4,
8811 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
8812 (ulong) vaddr, (ulong) lenp, (ulong) *((ulong *) lenp), (ulong) paddr);
8813
8814 return paddr;
8815}
8816
8817/*
8818 * Read a PCI configuration byte.
8819 */
8820STATIC uchar __init
8821DvcAdvReadPCIConfigByte(
8822 ADV_DVC_VAR *asc_dvc,
8823 ushort offset)
8824{
8825#ifdef CONFIG_PCI
8826 uchar byte_data;
8827 pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
8828 return byte_data;
8829#else /* CONFIG_PCI */
8830 return 0;
8831#endif /* CONFIG_PCI */
8832}
8833
8834/*
8835 * Write a PCI configuration byte.
8836 */
8837STATIC void __init
8838DvcAdvWritePCIConfigByte(
8839 ADV_DVC_VAR *asc_dvc,
8840 ushort offset,
8841 uchar byte_data)
8842{
8843#ifdef CONFIG_PCI
8844 pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
8845#else /* CONFIG_PCI */
8846 return;
8847#endif /* CONFIG_PCI */
8848}
8849
8850/*
8851 * --- Tracing and Debugging Functions
8852 */
8853
8854#ifdef ADVANSYS_STATS
8855#ifdef CONFIG_PROC_FS
8856/*
8857 * asc_prt_board_stats()
8858 *
8859 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8860 * cf. asc_prt_line().
8861 *
8862 * Return the number of characters copied into 'cp'. No more than
8863 * 'cplen' characters will be copied to 'cp'.
8864 */
8865STATIC int
8866asc_prt_board_stats(struct Scsi_Host *shp, char *cp, int cplen)
8867{
8868 int leftlen;
8869 int totlen;
8870 int len;
8871 struct asc_stats *s;
8872 asc_board_t *boardp;
8873
8874 leftlen = cplen;
8875 totlen = len = 0;
8876
8877 boardp = ASC_BOARDP(shp);
8878 s = &boardp->asc_stats;
8879
8880 len = asc_prt_line(cp, leftlen,
8881"\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", shp->host_no);
8882 ASC_PRT_NEXT();
8883
8884 len = asc_prt_line(cp, leftlen,
8885" queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
8886 s->queuecommand, s->reset, s->biosparam, s->interrupt);
8887 ASC_PRT_NEXT();
8888
8889 len = asc_prt_line(cp, leftlen,
8890" callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
8891 s->callback, s->done, s->build_error, s->adv_build_noreq,
8892 s->adv_build_nosg);
8893 ASC_PRT_NEXT();
8894
8895 len = asc_prt_line(cp, leftlen,
8896" exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
8897 s->exe_noerror, s->exe_busy, s->exe_error, s->exe_unknown);
8898 ASC_PRT_NEXT();
8899
8900 /*
8901 * Display data transfer statistics.
8902 */
8903 if (s->cont_cnt > 0) {
8904 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
8905 ASC_PRT_NEXT();
8906
8907 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
8908 s->cont_xfer/2,
8909 ASC_TENTHS(s->cont_xfer, 2));
8910 ASC_PRT_NEXT();
8911
8912 /* Contiguous transfer average size */
8913 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
8914 (s->cont_xfer/2)/s->cont_cnt,
8915 ASC_TENTHS((s->cont_xfer/2), s->cont_cnt));
8916 ASC_PRT_NEXT();
8917 }
8918
8919 if (s->sg_cnt > 0) {
8920
8921 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
8922 s->sg_cnt, s->sg_elem);
8923 ASC_PRT_NEXT();
8924
8925 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
8926 s->sg_xfer/2,
8927 ASC_TENTHS(s->sg_xfer, 2));
8928 ASC_PRT_NEXT();
8929
8930 /* Scatter gather transfer statistics */
8931 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
8932 s->sg_elem/s->sg_cnt,
8933 ASC_TENTHS(s->sg_elem, s->sg_cnt));
8934 ASC_PRT_NEXT();
8935
8936 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
8937 (s->sg_xfer/2)/s->sg_elem,
8938 ASC_TENTHS((s->sg_xfer/2), s->sg_elem));
8939 ASC_PRT_NEXT();
8940
8941 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
8942 (s->sg_xfer/2)/s->sg_cnt,
8943 ASC_TENTHS((s->sg_xfer/2), s->sg_cnt));
8944 ASC_PRT_NEXT();
8945 }
8946
8947 /*
8948 * Display request queuing statistics.
8949 */
8950 len = asc_prt_line(cp, leftlen,
8951" Active and Waiting Request Queues (Time Unit: %d HZ):\n", HZ);
8952 ASC_PRT_NEXT();
8953
8954
8955 return totlen;
8956}
8957
8958/*
8959 * asc_prt_target_stats()
8960 *
8961 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8962 * cf. asc_prt_line().
8963 *
8964 * This is separated from asc_prt_board_stats because a full set
8965 * of targets will overflow ASC_PRTBUF_SIZE.
8966 *
8967 * Return the number of characters copied into 'cp'. No more than
8968 * 'cplen' characters will be copied to 'cp'.
8969 */
8970STATIC int
8971asc_prt_target_stats(struct Scsi_Host *shp, int tgt_id, char *cp, int cplen)
8972{
8973 int leftlen;
8974 int totlen;
8975 int len;
8976 struct asc_stats *s;
8977 ushort chip_scsi_id;
8978 asc_board_t *boardp;
8979 asc_queue_t *active;
8980 asc_queue_t *waiting;
8981
8982 leftlen = cplen;
8983 totlen = len = 0;
8984
8985 boardp = ASC_BOARDP(shp);
8986 s = &boardp->asc_stats;
8987
8988 active = &ASC_BOARDP(shp)->active;
8989 waiting = &ASC_BOARDP(shp)->waiting;
8990
8991 if (ASC_NARROW_BOARD(boardp)) {
8992 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
8993 } else {
8994 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
8995 }
8996
8997 if ((chip_scsi_id == tgt_id) ||
8998 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
8999 return 0;
9000 }
9001
9002 do {
9003 if (active->q_tot_cnt[tgt_id] > 0 || waiting->q_tot_cnt[tgt_id] > 0) {
9004 len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
9005 ASC_PRT_NEXT();
9006
9007 len = asc_prt_line(cp, leftlen,
9008" active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
9009 active->q_cur_cnt[tgt_id], active->q_max_cnt[tgt_id],
9010 active->q_tot_cnt[tgt_id],
9011 active->q_min_tim[tgt_id], active->q_max_tim[tgt_id],
9012 (active->q_tot_cnt[tgt_id] == 0) ? 0 :
9013 (active->q_tot_tim[tgt_id]/active->q_tot_cnt[tgt_id]),
9014 (active->q_tot_cnt[tgt_id] == 0) ? 0 :
9015 ASC_TENTHS(active->q_tot_tim[tgt_id],
9016 active->q_tot_cnt[tgt_id]));
9017 ASC_PRT_NEXT();
9018
9019 len = asc_prt_line(cp, leftlen,
9020" waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
9021 waiting->q_cur_cnt[tgt_id], waiting->q_max_cnt[tgt_id],
9022 waiting->q_tot_cnt[tgt_id],
9023 waiting->q_min_tim[tgt_id], waiting->q_max_tim[tgt_id],
9024 (waiting->q_tot_cnt[tgt_id] == 0) ? 0 :
9025 (waiting->q_tot_tim[tgt_id]/waiting->q_tot_cnt[tgt_id]),
9026 (waiting->q_tot_cnt[tgt_id] == 0) ? 0 :
9027 ASC_TENTHS(waiting->q_tot_tim[tgt_id],
9028 waiting->q_tot_cnt[tgt_id]));
9029 ASC_PRT_NEXT();
9030 }
9031 } while (0);
9032
9033 return totlen;
9034}
9035#endif /* CONFIG_PROC_FS */
9036#endif /* ADVANSYS_STATS */
9037
9038#ifdef ADVANSYS_DEBUG
9039/*
9040 * asc_prt_scsi_host()
9041 */
9042STATIC void
9043asc_prt_scsi_host(struct Scsi_Host *s)
9044{
9045 asc_board_t *boardp;
9046
9047 boardp = ASC_BOARDP(s);
9048
9049 printk("Scsi_Host at addr 0x%lx\n", (ulong) s);
9050 printk(
9051" host_busy %u, host_no %d, last_reset %d,\n",
9052 s->host_busy, s->host_no,
9053 (unsigned) s->last_reset);
9054
9055 printk(
9056" base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
9057 (ulong) s->base, (ulong) s->io_port, s->n_io_port, s->irq);
9058
9059 printk(
9060" dma_channel %d, this_id %d, can_queue %d,\n",
9061 s->dma_channel, s->this_id, s->can_queue);
9062
9063 printk(
9064" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
9065 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
9066
9067 if (ASC_NARROW_BOARD(boardp)) {
9068 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
9069 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
9070 } else {
9071 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
9072 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
9073 }
9074}
9075
9076/*
9077 * asc_prt_scsi_cmnd()
9078 */
9079STATIC void
9080asc_prt_scsi_cmnd(struct scsi_cmnd *s)
9081{
9082 printk("struct scsi_cmnd at addr 0x%lx\n", (ulong) s);
9083
9084 printk(
9085" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
9086 (ulong) s->device->host, (ulong) s->device, s->device->id, s->device->lun,
9087 s->device->channel);
9088
9089 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
9090
9091 printk (
9092"sc_data_direction %u, resid %d\n",
9093 s->sc_data_direction, s->resid);
9094
9095 printk(
f5ad5614
CH
9096" use_sg %u, sglist_len %u\n",
9097 s->use_sg, s->sglist_len);
1da177e4
LT
9098
9099 printk(
c6295cdf 9100" serial_number 0x%x, retries %d, allowed %d\n",
9101 (unsigned) s->serial_number, s->retries, s->allowed);
1da177e4
LT
9102
9103 printk(
b21a4138
JB
9104" timeout_per_command %d\n",
9105 s->timeout_per_command);
1da177e4 9106
1da177e4
LT
9107 printk(
9108" scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
9109 (ulong) s->scsi_done, (ulong) s->done,
9110 (ulong) s->host_scribble, s->result);
9111
9112 printk(
9113" tag %u, pid %u\n",
9114 (unsigned) s->tag, (unsigned) s->pid);
9115}
9116
9117/*
9118 * asc_prt_asc_dvc_var()
9119 */
9120STATIC void
9121asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
9122{
9123 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong) h);
9124
9125 printk(
9126" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n",
9127 h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
9128
9129 printk(
9130" bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n",
9131 h->bus_type, (ulong) h->isr_callback, (ulong) h->exe_callback,
9132 (unsigned) h->init_sdtr);
9133
9134 printk(
9135" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n",
9136 (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng,
9137 (unsigned) h->unit_not_ready, (unsigned) h->chip_no);
9138
9139 printk(
9140" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n",
9141 (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor,
9142 (unsigned) h->scsi_reset_wait);
9143
9144 printk(
9145" is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n",
9146 (unsigned) h->is_in_int, (unsigned) h->max_total_qng,
9147 (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt);
9148
9149 printk(
9150" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n",
9151 (unsigned) h->last_q_shortage, (unsigned) h->init_state,
9152 (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer);
9153
9154 printk(
9155" cfg 0x%lx, irq_no 0x%x\n",
9156 (ulong) h->cfg, (unsigned) h->irq_no);
9157}
9158
9159/*
9160 * asc_prt_asc_dvc_cfg()
9161 */
9162STATIC void
9163asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
9164{
9165 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong) h);
9166
9167 printk(
9168" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
9169 h->can_tagged_qng, h->cmd_qng_enabled);
9170 printk(
9171" disc_enable 0x%x, sdtr_enable 0x%x,\n",
9172 h->disc_enable, h->sdtr_enable);
9173
9174 printk(
9175" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
9176 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
9177 h->chip_version);
9178
9179 printk(
9180" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
9181 to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
9182 h->mcode_date);
9183
9184 printk(
9185" mcode_version %d, overrun_buf 0x%lx\n",
9186 h->mcode_version, (ulong) h->overrun_buf);
9187}
9188
9189/*
9190 * asc_prt_asc_scsi_q()
9191 */
9192STATIC void
9193asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
9194{
9195 ASC_SG_HEAD *sgp;
9196 int i;
9197
9198 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong) q);
9199
9200 printk(
9201" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
9202 q->q2.target_ix, q->q1.target_lun,
9203 (ulong) q->q2.srb_ptr, q->q2.tag_code);
9204
9205 printk(
9206" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
9207 (ulong) le32_to_cpu(q->q1.data_addr),
9208 (ulong) le32_to_cpu(q->q1.data_cnt),
9209 (ulong) le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
9210
9211 printk(
9212" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
9213 (ulong) q->cdbptr, q->q2.cdb_len,
9214 (ulong) q->sg_head, q->q1.sg_queue_cnt);
9215
9216 if (q->sg_head) {
9217 sgp = q->sg_head;
9218 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong) sgp);
9219 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt);
9220 for (i = 0; i < sgp->entry_cnt; i++) {
9221 printk(" [%u]: addr 0x%lx, bytes %lu\n",
9222 i, (ulong) le32_to_cpu(sgp->sg_list[i].addr),
9223 (ulong) le32_to_cpu(sgp->sg_list[i].bytes));
9224 }
9225
9226 }
9227}
9228
9229/*
9230 * asc_prt_asc_qdone_info()
9231 */
9232STATIC void
9233asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
9234{
9235 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong) q);
9236 printk(
9237" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
9238 (ulong) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
9239 q->d2.tag_code);
9240 printk(
9241" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
9242 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
9243}
9244
9245/*
9246 * asc_prt_adv_dvc_var()
9247 *
9248 * Display an ADV_DVC_VAR structure.
9249 */
9250STATIC void
9251asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
9252{
9253 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong) h);
9254
9255 printk(
9256" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
9257 (ulong) h->iop_base, h->err_code, (unsigned) h->ultra_able);
9258
9259 printk(
9260" isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
9261 (ulong) h->isr_callback, (unsigned) h->sdtr_able,
9262 (unsigned) h->wdtr_able);
9263
9264 printk(
9265" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
9266 (unsigned) h->start_motor,
9267 (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
9268
9269 printk(
9270" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
9271 (unsigned) h->max_host_qng, (unsigned) h->max_dvc_qng,
9272 (ulong) h->carr_freelist);
9273
9274 printk(
9275" icq_sp 0x%lx, irq_sp 0x%lx\n",
9276 (ulong) h->icq_sp, (ulong) h->irq_sp);
9277
9278 printk(
9279" no_scam 0x%x, tagqng_able 0x%x\n",
9280 (unsigned) h->no_scam, (unsigned) h->tagqng_able);
9281
9282 printk(
9283" chip_scsi_id 0x%x, cfg 0x%lx\n",
9284 (unsigned) h->chip_scsi_id, (ulong) h->cfg);
9285}
9286
9287/*
9288 * asc_prt_adv_dvc_cfg()
9289 *
9290 * Display an ADV_DVC_CFG structure.
9291 */
9292STATIC void
9293asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
9294{
9295 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong) h);
9296
9297 printk(
9298" disc_enable 0x%x, termination 0x%x\n",
9299 h->disc_enable, h->termination);
9300
9301 printk(
9302" chip_version 0x%x, mcode_date 0x%x\n",
9303 h->chip_version, h->mcode_date);
9304
9305 printk(
9306" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
9307 h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
9308
9309 printk(
9310" control_flag 0x%x, pci_slot_info 0x%x\n",
9311 h->control_flag, h->pci_slot_info);
9312}
9313
9314/*
9315 * asc_prt_adv_scsi_req_q()
9316 *
9317 * Display an ADV_SCSI_REQ_Q structure.
9318 */
9319STATIC void
9320asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
9321{
9322 int sg_blk_cnt;
9323 struct asc_sg_block *sg_ptr;
9324
9325 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong) q);
9326
9327 printk(
9328" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
9329 q->target_id, q->target_lun, (ulong) q->srb_ptr, q->a_flag);
9330
9331 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
9332 q->cntl, (ulong) le32_to_cpu(q->data_addr), (ulong) q->vdata_addr);
9333
9334 printk(
9335" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
9336 (ulong) le32_to_cpu(q->data_cnt),
9337 (ulong) le32_to_cpu(q->sense_addr), q->sense_len);
9338
9339 printk(
9340" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
9341 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
9342
9343 printk(
9344" sg_working_ix 0x%x, target_cmd %u\n",
9345 q->sg_working_ix, q->target_cmd);
9346
9347 printk(
9348" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
9349 (ulong) le32_to_cpu(q->scsiq_rptr),
9350 (ulong) le32_to_cpu(q->sg_real_addr), (ulong) q->sg_list_ptr);
9351
9352 /* Display the request's ADV_SG_BLOCK structures. */
9353 if (q->sg_list_ptr != NULL)
9354 {
9355 sg_blk_cnt = 0;
9356 while (1) {
9357 /*
9358 * 'sg_ptr' is a physical address. Convert it to a virtual
9359 * address by indexing 'sg_blk_cnt' into the virtual address
9360 * array 'sg_list_ptr'.
9361 *
9362 * XXX - Assumes all SG physical blocks are virtually contiguous.
9363 */
9364 sg_ptr = &(((ADV_SG_BLOCK *) (q->sg_list_ptr))[sg_blk_cnt]);
9365 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
9366 if (sg_ptr->sg_ptr == 0)
9367 {
9368 break;
9369 }
9370 sg_blk_cnt++;
9371 }
9372 }
9373}
9374
9375/*
9376 * asc_prt_adv_sgblock()
9377 *
9378 * Display an ADV_SG_BLOCK structure.
9379 */
9380STATIC void
9381asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
9382{
9383 int i;
9384
9385 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
9386 (ulong) b, sgblockno);
9387 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
9388 b->sg_cnt, (ulong) le32_to_cpu(b->sg_ptr));
9389 ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
9390 if (b->sg_ptr != 0)
9391 {
9392 ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
9393 }
9394 for (i = 0; i < b->sg_cnt; i++) {
9395 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
9396 i, (ulong) b->sg_list[i].sg_addr, (ulong) b->sg_list[i].sg_count);
9397 }
9398}
9399
9400/*
9401 * asc_prt_hex()
9402 *
9403 * Print hexadecimal output in 4 byte groupings 32 bytes
9404 * or 8 double-words per line.
9405 */
9406STATIC void
9407asc_prt_hex(char *f, uchar *s, int l)
9408{
9409 int i;
9410 int j;
9411 int k;
9412 int m;
9413
9414 printk("%s: (%d bytes)\n", f, l);
9415
9416 for (i = 0; i < l; i += 32) {
9417
9418 /* Display a maximum of 8 double-words per line. */
9419 if ((k = (l - i) / 4) >= 8) {
9420 k = 8;
9421 m = 0;
9422 } else {
9423 m = (l - i) % 4;
9424 }
9425
9426 for (j = 0; j < k; j++) {
9427 printk(" %2.2X%2.2X%2.2X%2.2X",
9428 (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1],
9429 (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]);
9430 }
9431
9432 switch (m) {
9433 case 0:
9434 default:
9435 break;
9436 case 1:
9437 printk(" %2.2X",
9438 (unsigned) s[i+(j*4)]);
9439 break;
9440 case 2:
9441 printk(" %2.2X%2.2X",
9442 (unsigned) s[i+(j*4)],
9443 (unsigned) s[i+(j*4)+1]);
9444 break;
9445 case 3:
9446 printk(" %2.2X%2.2X%2.2X",
9447 (unsigned) s[i+(j*4)+1],
9448 (unsigned) s[i+(j*4)+2],
9449 (unsigned) s[i+(j*4)+3]);
9450 break;
9451 }
9452
9453 printk("\n");
9454 }
9455}
9456#endif /* ADVANSYS_DEBUG */
9457
9458/*
9459 * --- Asc Library Functions
9460 */
9461
9462STATIC ushort __init
9463AscGetEisaChipCfg(
9464 PortAddr iop_base)
9465{
9466 PortAddr eisa_cfg_iop;
9467
9468 eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
9469 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
9470 return (inpw(eisa_cfg_iop));
9471}
9472
9473STATIC uchar __init
9474AscSetChipScsiID(
9475 PortAddr iop_base,
9476 uchar new_host_id
9477)
9478{
9479 ushort cfg_lsw;
9480
9481 if (AscGetChipScsiID(iop_base) == new_host_id) {
9482 return (new_host_id);
9483 }
9484 cfg_lsw = AscGetChipCfgLsw(iop_base);
9485 cfg_lsw &= 0xF8FF;
9486 cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID) << 8);
9487 AscSetChipCfgLsw(iop_base, cfg_lsw);
9488 return (AscGetChipScsiID(iop_base));
9489}
9490
9491STATIC uchar __init
9492AscGetChipScsiCtrl(
9493 PortAddr iop_base)
9494{
9495 uchar sc;
9496
9497 AscSetBank(iop_base, 1);
9498 sc = inp(iop_base + IOP_REG_SC);
9499 AscSetBank(iop_base, 0);
9500 return (sc);
9501}
9502
9503STATIC uchar __init
9504AscGetChipVersion(
9505 PortAddr iop_base,
9506 ushort bus_type
9507)
9508{
9509 if ((bus_type & ASC_IS_EISA) != 0) {
9510 PortAddr eisa_iop;
9511 uchar revision;
9512 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
9513 (PortAddr) ASC_EISA_REV_IOP_MASK;
9514 revision = inp(eisa_iop);
9515 return ((uchar) ((ASC_CHIP_MIN_VER_EISA - 1) + revision));
9516 }
9517 return (AscGetChipVerNo(iop_base));
9518}
9519
9520STATIC ushort __init
9521AscGetChipBusType(
9522 PortAddr iop_base)
9523{
9524 ushort chip_ver;
9525
9526 chip_ver = AscGetChipVerNo(iop_base);
9527 if (
9528 (chip_ver >= ASC_CHIP_MIN_VER_VL)
9529 && (chip_ver <= ASC_CHIP_MAX_VER_VL)
9530) {
9531 if (
9532 ((iop_base & 0x0C30) == 0x0C30)
9533 || ((iop_base & 0x0C50) == 0x0C50)
9534) {
9535 return (ASC_IS_EISA);
9536 }
9537 return (ASC_IS_VL);
9538 }
9539 if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
9540 (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
9541 if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
9542 return (ASC_IS_ISAPNP);
9543 }
9544 return (ASC_IS_ISA);
9545 } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
9546 (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
9547 return (ASC_IS_PCI);
9548 }
9549 return (0);
9550}
9551
9552STATIC ASC_DCNT
9553AscLoadMicroCode(
9554 PortAddr iop_base,
9555 ushort s_addr,
9556 uchar *mcode_buf,
9557 ushort mcode_size
9558)
9559{
9560 ASC_DCNT chksum;
9561 ushort mcode_word_size;
9562 ushort mcode_chksum;
9563
9564 /* Write the microcode buffer starting at LRAM address 0. */
9565 mcode_word_size = (ushort) (mcode_size >> 1);
9566 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
9567 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
9568
9569 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
9570 ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong) chksum);
9571 mcode_chksum = (ushort) AscMemSumLramWord(iop_base,
9572 (ushort) ASC_CODE_SEC_BEG,
9573 (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2));
9574 ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
9575 (ulong) mcode_chksum);
9576 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
9577 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
9578 return (chksum);
9579}
9580
9581STATIC int
9582AscFindSignature(
9583 PortAddr iop_base
9584)
9585{
9586 ushort sig_word;
9587
9588 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
9589 iop_base, AscGetChipSignatureByte(iop_base));
9590 if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) {
9591 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
9592 iop_base, AscGetChipSignatureWord(iop_base));
9593 sig_word = AscGetChipSignatureWord(iop_base);
9594 if ((sig_word == (ushort) ASC_1000_ID0W) ||
9595 (sig_word == (ushort) ASC_1000_ID0W_FIX)) {
9596 return (1);
9597 }
9598 }
9599 return (0);
9600}
9601
9602STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __initdata =
9603{
9604 0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
9605 ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
9606};
9607
9608#ifdef CONFIG_ISA
9609STATIC uchar _isa_pnp_inited __initdata = 0;
9610
9611STATIC PortAddr __init
9612AscSearchIOPortAddr(
9613 PortAddr iop_beg,
9614 ushort bus_type)
9615{
9616 if (bus_type & ASC_IS_VL) {
9617 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
9618 if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL) {
9619 return (iop_beg);
9620 }
9621 }
9622 return (0);
9623 }
9624 if (bus_type & ASC_IS_ISA) {
9625 if (_isa_pnp_inited == 0) {
9626 AscSetISAPNPWaitForKey();
9627 _isa_pnp_inited++;
9628 }
9629 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
9630 if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT) != 0) {
9631 return (iop_beg);
9632 }
9633 }
9634 return (0);
9635 }
9636 if (bus_type & ASC_IS_EISA) {
9637 if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
9638 return (iop_beg);
9639 }
9640 return (0);
9641 }
9642 return (0);
9643}
9644
9645STATIC PortAddr __init
9646AscSearchIOPortAddr11(
9647 PortAddr s_addr
9648)
9649{
9650 int i;
9651 PortAddr iop_base;
9652
9653 for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
9654 if (_asc_def_iop_base[i] > s_addr) {
9655 break;
9656 }
9657 }
9658 for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
9659 iop_base = _asc_def_iop_base[i];
35d68483 9660 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")){
1da177e4
LT
9661 ASC_DBG1(1,
9662 "AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n",
9663 iop_base);
9664 continue;
9665 }
9666 ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n", iop_base);
35d68483 9667 release_region(iop_base, ASC_IOADR_GAP);
1da177e4
LT
9668 if (AscFindSignature(iop_base)) {
9669 return (iop_base);
9670 }
9671 }
9672 return (0);
9673}
9674
9675STATIC void __init
9676AscSetISAPNPWaitForKey(void)
9677{
9678 outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
9679 outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
9680 return;
9681}
9682#endif /* CONFIG_ISA */
9683
9684STATIC void __init
9685AscToggleIRQAct(
9686 PortAddr iop_base
9687)
9688{
9689 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
9690 AscSetChipStatus(iop_base, 0);
9691 return;
9692}
9693
9694STATIC uchar __init
9695AscGetChipIRQ(
9696 PortAddr iop_base,
9697 ushort bus_type)
9698{
9699 ushort cfg_lsw;
9700 uchar chip_irq;
9701
9702 if ((bus_type & ASC_IS_EISA) != 0) {
9703 cfg_lsw = AscGetEisaChipCfg(iop_base);
9704 chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10);
9705 if ((chip_irq == 13) || (chip_irq > 15)) {
9706 return (0);
9707 }
9708 return (chip_irq);
9709 }
9710 if ((bus_type & ASC_IS_VL) != 0) {
9711 cfg_lsw = AscGetChipCfgLsw(iop_base);
9712 chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07));
9713 if ((chip_irq == 0) ||
9714 (chip_irq == 4) ||
9715 (chip_irq == 7)) {
9716 return (0);
9717 }
9718 return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1)));
9719 }
9720 cfg_lsw = AscGetChipCfgLsw(iop_base);
9721 chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03));
9722 if (chip_irq == 3)
9723 chip_irq += (uchar) 2;
9724 return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
9725}
9726
9727STATIC uchar __init
9728AscSetChipIRQ(
9729 PortAddr iop_base,
9730 uchar irq_no,
9731 ushort bus_type)
9732{
9733 ushort cfg_lsw;
9734
9735 if ((bus_type & ASC_IS_VL) != 0) {
9736 if (irq_no != 0) {
9737 if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) {
9738 irq_no = 0;
9739 } else {
9740 irq_no -= (uchar) ((ASC_MIN_IRQ_NO - 1));
9741 }
9742 }
9743 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE3);
9744 cfg_lsw |= (ushort) 0x0010;
9745 AscSetChipCfgLsw(iop_base, cfg_lsw);
9746 AscToggleIRQAct(iop_base);
9747 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE0);
9748 cfg_lsw |= (ushort) ((irq_no & 0x07) << 2);
9749 AscSetChipCfgLsw(iop_base, cfg_lsw);
9750 AscToggleIRQAct(iop_base);
9751 return (AscGetChipIRQ(iop_base, bus_type));
9752 }
9753 if ((bus_type & (ASC_IS_ISA)) != 0) {
9754 if (irq_no == 15)
9755 irq_no -= (uchar) 2;
9756 irq_no -= (uchar) ASC_MIN_IRQ_NO;
9757 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFF3);
9758 cfg_lsw |= (ushort) ((irq_no & 0x03) << 2);
9759 AscSetChipCfgLsw(iop_base, cfg_lsw);
9760 return (AscGetChipIRQ(iop_base, bus_type));
9761 }
9762 return (0);
9763}
9764
9765#ifdef CONFIG_ISA
9766STATIC void __init
9767AscEnableIsaDma(
9768 uchar dma_channel)
9769{
9770 if (dma_channel < 4) {
9771 outp(0x000B, (ushort) (0xC0 | dma_channel));
9772 outp(0x000A, dma_channel);
9773 } else if (dma_channel < 8) {
9774 outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4)));
9775 outp(0x00D4, (ushort) (dma_channel - 4));
9776 }
9777 return;
9778}
9779#endif /* CONFIG_ISA */
9780
9781STATIC int
9782AscIsrChipHalted(
9783 ASC_DVC_VAR *asc_dvc
9784)
9785{
9786 EXT_MSG ext_msg;
9787 EXT_MSG out_msg;
9788 ushort halt_q_addr;
9789 int sdtr_accept;
9790 ushort int_halt_code;
9791 ASC_SCSI_BIT_ID_TYPE scsi_busy;
9792 ASC_SCSI_BIT_ID_TYPE target_id;
9793 PortAddr iop_base;
9794 uchar tag_code;
9795 uchar q_status;
9796 uchar halt_qp;
9797 uchar sdtr_data;
9798 uchar target_ix;
9799 uchar q_cntl, tid_no;
9800 uchar cur_dvc_qng;
9801 uchar asyn_sdtr;
9802 uchar scsi_status;
9803 asc_board_t *boardp;
9804
9805 ASC_ASSERT(asc_dvc->drv_ptr != NULL);
9806 boardp = asc_dvc->drv_ptr;
9807
9808 iop_base = asc_dvc->iop_base;
9809 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
9810
9811 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
9812 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
9813 target_ix = AscReadLramByte(iop_base,
9814 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX));
9815 q_cntl = AscReadLramByte(iop_base,
9816 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL));
9817 tid_no = ASC_TIX_TO_TID(target_ix);
9818 target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no);
9819 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
9820 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
9821 } else {
9822 asyn_sdtr = 0;
9823 }
9824 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
9825 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
9826 AscSetChipSDTR(iop_base, 0, tid_no);
9827 boardp->sdtr_data[tid_no] = 0;
9828 }
9829 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9830 return (0);
9831 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
9832 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
9833 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
9834 boardp->sdtr_data[tid_no] = asyn_sdtr;
9835 }
9836 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9837 return (0);
9838 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
9839
9840 AscMemWordCopyPtrFromLram(iop_base,
9841 ASCV_MSGIN_BEG,
9842 (uchar *) &ext_msg,
9843 sizeof(EXT_MSG) >> 1);
9844
9845 if (ext_msg.msg_type == MS_EXTEND &&
9846 ext_msg.msg_req == MS_SDTR_CODE &&
9847 ext_msg.msg_len == MS_SDTR_LEN) {
9848 sdtr_accept = TRUE;
9849 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
9850
9851 sdtr_accept = FALSE;
9852 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
9853 }
9854 if ((ext_msg.xfer_period <
9855 asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index]) ||
9856 (ext_msg.xfer_period >
9857 asc_dvc->sdtr_period_tbl[asc_dvc->max_sdtr_index])) {
9858 sdtr_accept = FALSE;
9859 ext_msg.xfer_period =
9860 asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index];
9861 }
9862 if (sdtr_accept) {
9863 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
9864 ext_msg.req_ack_offset);
9865 if ((sdtr_data == 0xFF)) {
9866
9867 q_cntl |= QC_MSG_OUT;
9868 asc_dvc->init_sdtr &= ~target_id;
9869 asc_dvc->sdtr_done &= ~target_id;
9870 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
9871 boardp->sdtr_data[tid_no] = asyn_sdtr;
9872 }
9873 }
9874 if (ext_msg.req_ack_offset == 0) {
9875
9876 q_cntl &= ~QC_MSG_OUT;
9877 asc_dvc->init_sdtr &= ~target_id;
9878 asc_dvc->sdtr_done &= ~target_id;
9879 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
9880 } else {
9881 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
9882
9883 q_cntl &= ~QC_MSG_OUT;
9884 asc_dvc->sdtr_done |= target_id;
9885 asc_dvc->init_sdtr |= target_id;
9886 asc_dvc->pci_fix_asyn_xfer &= ~target_id;
9887 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
9888 ext_msg.req_ack_offset);
9889 AscSetChipSDTR(iop_base, sdtr_data, tid_no);
9890 boardp->sdtr_data[tid_no] = sdtr_data;
9891 } else {
9892
9893 q_cntl |= QC_MSG_OUT;
9894 AscMsgOutSDTR(asc_dvc,
9895 ext_msg.xfer_period,
9896 ext_msg.req_ack_offset);
9897 asc_dvc->pci_fix_asyn_xfer &= ~target_id;
9898 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
9899 ext_msg.req_ack_offset);
9900 AscSetChipSDTR(iop_base, sdtr_data, tid_no);
9901 boardp->sdtr_data[tid_no] = sdtr_data;
9902 asc_dvc->sdtr_done |= target_id;
9903 asc_dvc->init_sdtr |= target_id;
9904 }
9905 }
9906
9907 AscWriteLramByte(iop_base,
9908 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
9909 q_cntl);
9910 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9911 return (0);
9912 } else if (ext_msg.msg_type == MS_EXTEND &&
9913 ext_msg.msg_req == MS_WDTR_CODE &&
9914 ext_msg.msg_len == MS_WDTR_LEN) {
9915
9916 ext_msg.wdtr_width = 0;
9917 AscMemWordCopyPtrToLram(iop_base,
9918 ASCV_MSGOUT_BEG,
9919 (uchar *) &ext_msg,
9920 sizeof(EXT_MSG) >> 1);
9921 q_cntl |= QC_MSG_OUT;
9922 AscWriteLramByte(iop_base,
9923 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
9924 q_cntl);
9925 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9926 return (0);
9927 } else {
9928
9929 ext_msg.msg_type = MESSAGE_REJECT;
9930 AscMemWordCopyPtrToLram(iop_base,
9931 ASCV_MSGOUT_BEG,
9932 (uchar *) &ext_msg,
9933 sizeof(EXT_MSG) >> 1);
9934 q_cntl |= QC_MSG_OUT;
9935 AscWriteLramByte(iop_base,
9936 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
9937 q_cntl);
9938 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9939 return (0);
9940 }
9941 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
9942
9943 q_cntl |= QC_REQ_SENSE;
9944
9945 if ((asc_dvc->init_sdtr & target_id) != 0) {
9946
9947 asc_dvc->sdtr_done &= ~target_id;
9948
9949 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9950 q_cntl |= QC_MSG_OUT;
9951 AscMsgOutSDTR(asc_dvc,
9952 asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
9953 (uchar) (asc_dvc->max_sdtr_index - 1)],
9954 (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
9955 }
9956
9957 AscWriteLramByte(iop_base,
9958 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
9959 q_cntl);
9960
9961 tag_code = AscReadLramByte(iop_base,
9962 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
9963 tag_code &= 0xDC;
9964 if (
9965 (asc_dvc->pci_fix_asyn_xfer & target_id)
9966 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
9967) {
9968
9969 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
9970 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
9971
9972 }
9973 AscWriteLramByte(iop_base,
9974 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE),
9975 tag_code);
9976
9977 q_status = AscReadLramByte(iop_base,
9978 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS));
9979 q_status |= (QS_READY | QS_BUSY);
9980 AscWriteLramByte(iop_base,
9981 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
9982 q_status);
9983
9984 scsi_busy = AscReadLramByte(iop_base,
9985 (ushort) ASCV_SCSIBUSY_B);
9986 scsi_busy &= ~target_id;
9987 AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B, scsi_busy);
9988
9989 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9990 return (0);
9991 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
9992
9993 AscMemWordCopyPtrFromLram(iop_base,
9994 ASCV_MSGOUT_BEG,
9995 (uchar *) &out_msg,
9996 sizeof(EXT_MSG) >> 1);
9997
9998 if ((out_msg.msg_type == MS_EXTEND) &&
9999 (out_msg.msg_len == MS_SDTR_LEN) &&
10000 (out_msg.msg_req == MS_SDTR_CODE)) {
10001
10002 asc_dvc->init_sdtr &= ~target_id;
10003 asc_dvc->sdtr_done &= ~target_id;
10004 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10005 boardp->sdtr_data[tid_no] = asyn_sdtr;
10006 }
10007 q_cntl &= ~QC_MSG_OUT;
10008 AscWriteLramByte(iop_base,
10009 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10010 q_cntl);
10011 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10012 return (0);
10013 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
10014
10015 scsi_status = AscReadLramByte(iop_base,
10016 (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS));
10017 cur_dvc_qng = AscReadLramByte(iop_base,
10018 (ushort) ((ushort) ASC_QADR_BEG + (ushort) target_ix));
10019 if ((cur_dvc_qng > 0) &&
10020 (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
10021
10022 scsi_busy = AscReadLramByte(iop_base,
10023 (ushort) ASCV_SCSIBUSY_B);
10024 scsi_busy |= target_id;
10025 AscWriteLramByte(iop_base,
10026 (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10027 asc_dvc->queue_full_or_busy |= target_id;
10028
10029 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
10030 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
10031 cur_dvc_qng -= 1;
10032 asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
10033
10034 AscWriteLramByte(iop_base,
10035 (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG +
10036 (ushort) tid_no),
10037 cur_dvc_qng);
10038
10039 /*
10040 * Set the device queue depth to the number of
10041 * active requests when the QUEUE FULL condition
10042 * was encountered.
10043 */
10044 boardp->queue_full |= target_id;
10045 boardp->queue_full_cnt[tid_no] = cur_dvc_qng;
10046 }
10047 }
10048 }
10049 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10050 return (0);
10051 }
10052#if CC_VERY_LONG_SG_LIST
10053 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC)
10054 {
10055 uchar q_no;
10056 ushort q_addr;
10057 uchar sg_wk_q_no;
10058 uchar first_sg_wk_q_no;
10059 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
10060 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
10061 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
10062 ushort sg_list_dwords;
10063 ushort sg_entry_cnt;
10064 uchar next_qp;
10065 int i;
10066
10067 q_no = AscReadLramByte(iop_base, (ushort) ASCV_REQ_SG_LIST_QP);
10068 if (q_no == ASC_QLINK_END)
10069 {
10070 return(0);
10071 }
10072
10073 q_addr = ASC_QNO_TO_QADDR(q_no);
10074
10075 /*
10076 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
10077 * structure pointer using a macro provided by the driver.
10078 * The ASC_SCSI_REQ pointer provides a pointer to the
10079 * host ASC_SG_HEAD structure.
10080 */
10081 /* Read request's SRB pointer. */
10082 scsiq = (ASC_SCSI_Q *)
10083 ASC_SRB2SCSIQ(
10084 ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
10085 (ushort) (q_addr + ASC_SCSIQ_D_SRBPTR))));
10086
10087 /*
10088 * Get request's first and working SG queue.
10089 */
10090 sg_wk_q_no = AscReadLramByte(iop_base,
10091 (ushort) (q_addr + ASC_SCSIQ_B_SG_WK_QP));
10092
10093 first_sg_wk_q_no = AscReadLramByte(iop_base,
10094 (ushort) (q_addr + ASC_SCSIQ_B_FIRST_SG_WK_QP));
10095
10096 /*
10097 * Reset request's working SG queue back to the
10098 * first SG queue.
10099 */
10100 AscWriteLramByte(iop_base,
10101 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SG_WK_QP),
10102 first_sg_wk_q_no);
10103
10104 sg_head = scsiq->sg_head;
10105
10106 /*
10107 * Set sg_entry_cnt to the number of SG elements
10108 * that will be completed on this interrupt.
10109 *
10110 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
10111 * SG elements. The data_cnt and data_addr fields which
10112 * add 1 to the SG element capacity are not used when
10113 * restarting SG handling after a halt.
10114 */
10115 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1))
10116 {
10117 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
10118
10119 /*
10120 * Keep track of remaining number of SG elements that will
10121 * need to be handled on the next interrupt.
10122 */
10123 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
10124 } else
10125 {
10126 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
10127 scsiq->remain_sg_entry_cnt = 0;
10128 }
10129
10130 /*
10131 * Copy SG elements into the list of allocated SG queues.
10132 *
10133 * Last index completed is saved in scsiq->next_sg_index.
10134 */
10135 next_qp = first_sg_wk_q_no;
10136 q_addr = ASC_QNO_TO_QADDR(next_qp);
10137 scsi_sg_q.sg_head_qp = q_no;
10138 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
10139 for( i = 0; i < sg_head->queue_cnt; i++)
10140 {
10141 scsi_sg_q.seq_no = i + 1;
10142 if (sg_entry_cnt > ASC_SG_LIST_PER_Q)
10143 {
10144 sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
10145 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
10146 /*
10147 * After very first SG queue RISC FW uses next
10148 * SG queue first element then checks sg_list_cnt
10149 * against zero and then decrements, so set
10150 * sg_list_cnt 1 less than number of SG elements
10151 * in each SG queue.
10152 */
10153 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
10154 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
10155 } else {
10156 /*
10157 * This is the last SG queue in the list of
10158 * allocated SG queues. If there are more
10159 * SG elements than will fit in the allocated
10160 * queues, then set the QCSG_SG_XFER_MORE flag.
10161 */
10162 if (scsiq->remain_sg_entry_cnt != 0)
10163 {
10164 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
10165 } else
10166 {
10167 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
10168 }
10169 /* equals sg_entry_cnt * 2 */
10170 sg_list_dwords = sg_entry_cnt << 1;
10171 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
10172 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
10173 sg_entry_cnt = 0;
10174 }
10175
10176 scsi_sg_q.q_no = next_qp;
10177 AscMemWordCopyPtrToLram(iop_base,
10178 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
10179 (uchar *) &scsi_sg_q,
10180 sizeof(ASC_SG_LIST_Q) >> 1);
10181
10182 AscMemDWordCopyPtrToLram(iop_base,
10183 q_addr + ASC_SGQ_LIST_BEG,
10184 (uchar *) &sg_head->sg_list[scsiq->next_sg_index],
10185 sg_list_dwords);
10186
10187 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
10188
10189 /*
10190 * If the just completed SG queue contained the
10191 * last SG element, then no more SG queues need
10192 * to be written.
10193 */
10194 if (scsi_sg_q.cntl & QCSG_SG_XFER_END)
10195 {
10196 break;
10197 }
10198
10199 next_qp = AscReadLramByte( iop_base,
10200 ( ushort )( q_addr+ASC_SCSIQ_B_FWD ) );
10201 q_addr = ASC_QNO_TO_QADDR( next_qp );
10202 }
10203
10204 /*
10205 * Clear the halt condition so the RISC will be restarted
10206 * after the return.
10207 */
10208 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10209 return(0);
10210 }
10211#endif /* CC_VERY_LONG_SG_LIST */
10212 return (0);
10213}
10214
10215STATIC uchar
10216_AscCopyLramScsiDoneQ(
10217 PortAddr iop_base,
10218 ushort q_addr,
10219 ASC_QDONE_INFO * scsiq,
10220 ASC_DCNT max_dma_count
10221)
10222{
10223 ushort _val;
10224 uchar sg_queue_cnt;
10225
10226 DvcGetQinfo(iop_base,
10227 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
10228 (uchar *) scsiq,
10229 (sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2);
10230
10231 _val = AscReadLramWord(iop_base,
10232 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS));
10233 scsiq->q_status = (uchar) _val;
10234 scsiq->q_no = (uchar) (_val >> 8);
10235 _val = AscReadLramWord(iop_base,
10236 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL));
10237 scsiq->cntl = (uchar) _val;
10238 sg_queue_cnt = (uchar) (_val >> 8);
10239 _val = AscReadLramWord(iop_base,
10240 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN));
10241 scsiq->sense_len = (uchar) _val;
10242 scsiq->extra_bytes = (uchar) (_val >> 8);
10243
10244 /*
10245 * Read high word of remain bytes from alternate location.
10246 */
10247 scsiq->remain_bytes = (((ADV_DCNT) AscReadLramWord( iop_base,
10248 (ushort) (q_addr+ (ushort) ASC_SCSIQ_W_ALT_DC1))) << 16);
10249 /*
10250 * Read low word of remain bytes from original location.
10251 */
10252 scsiq->remain_bytes += AscReadLramWord(iop_base,
10253 (ushort) (q_addr+ (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT));
10254
10255 scsiq->remain_bytes &= max_dma_count;
10256 return (sg_queue_cnt);
10257}
10258
10259STATIC int
10260AscIsrQDone(
10261 ASC_DVC_VAR *asc_dvc
10262)
10263{
10264 uchar next_qp;
10265 uchar n_q_used;
10266 uchar sg_list_qp;
10267 uchar sg_queue_cnt;
10268 uchar q_cnt;
10269 uchar done_q_tail;
10270 uchar tid_no;
10271 ASC_SCSI_BIT_ID_TYPE scsi_busy;
10272 ASC_SCSI_BIT_ID_TYPE target_id;
10273 PortAddr iop_base;
10274 ushort q_addr;
10275 ushort sg_q_addr;
10276 uchar cur_target_qng;
10277 ASC_QDONE_INFO scsiq_buf;
10278 ASC_QDONE_INFO *scsiq;
10279 int false_overrun;
10280 ASC_ISR_CALLBACK asc_isr_callback;
10281
10282 iop_base = asc_dvc->iop_base;
10283 asc_isr_callback = asc_dvc->isr_callback;
10284 n_q_used = 1;
10285 scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
10286 done_q_tail = (uchar) AscGetVarDoneQTail(iop_base);
10287 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
10288 next_qp = AscReadLramByte(iop_base,
10289 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD));
10290 if (next_qp != ASC_QLINK_END) {
10291 AscPutVarDoneQTail(iop_base, next_qp);
10292 q_addr = ASC_QNO_TO_QADDR(next_qp);
10293 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
10294 asc_dvc->max_dma_count);
10295 AscWriteLramByte(iop_base,
10296 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10297 (uchar) (scsiq->q_status & (uchar) ~ (QS_READY | QS_ABORTED)));
10298 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
10299 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
10300 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
10301 sg_q_addr = q_addr;
10302 sg_list_qp = next_qp;
10303 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
10304 sg_list_qp = AscReadLramByte(iop_base,
10305 (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_FWD));
10306 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
10307 if (sg_list_qp == ASC_QLINK_END) {
10308 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_Q_LINKS);
10309 scsiq->d3.done_stat = QD_WITH_ERROR;
10310 scsiq->d3.host_stat = QHSTA_D_QDONE_SG_LIST_CORRUPTED;
10311 goto FATAL_ERR_QDONE;
10312 }
10313 AscWriteLramByte(iop_base,
10314 (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10315 QS_FREE);
10316 }
10317 n_q_used = sg_queue_cnt + 1;
10318 AscPutVarDoneQTail(iop_base, sg_list_qp);
10319 }
10320 if (asc_dvc->queue_full_or_busy & target_id) {
10321 cur_target_qng = AscReadLramByte(iop_base,
10322 (ushort) ((ushort) ASC_QADR_BEG + (ushort) scsiq->d2.target_ix));
10323 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
10324 scsi_busy = AscReadLramByte(iop_base,
10325 (ushort) ASCV_SCSIBUSY_B);
10326 scsi_busy &= ~target_id;
10327 AscWriteLramByte(iop_base,
10328 (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10329 asc_dvc->queue_full_or_busy &= ~target_id;
10330 }
10331 }
10332 if (asc_dvc->cur_total_qng >= n_q_used) {
10333 asc_dvc->cur_total_qng -= n_q_used;
10334 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
10335 asc_dvc->cur_dvc_qng[tid_no]--;
10336 }
10337 } else {
10338 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
10339 scsiq->d3.done_stat = QD_WITH_ERROR;
10340 goto FATAL_ERR_QDONE;
10341 }
10342 if ((scsiq->d2.srb_ptr == 0UL) ||
10343 ((scsiq->q_status & QS_ABORTED) != 0)) {
10344 return (0x11);
10345 } else if (scsiq->q_status == QS_DONE) {
10346 false_overrun = FALSE;
10347 if (scsiq->extra_bytes != 0) {
10348 scsiq->remain_bytes += (ADV_DCNT) scsiq->extra_bytes;
10349 }
10350 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
10351 if (scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN) {
10352 if ((scsiq->cntl & (QC_DATA_IN | QC_DATA_OUT)) == 0) {
10353 scsiq->d3.done_stat = QD_NO_ERROR;
10354 scsiq->d3.host_stat = QHSTA_NO_ERROR;
10355 } else if (false_overrun) {
10356 scsiq->d3.done_stat = QD_NO_ERROR;
10357 scsiq->d3.host_stat = QHSTA_NO_ERROR;
10358 }
10359 } else if (scsiq->d3.host_stat ==
10360 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
10361 AscStopChip(iop_base);
10362 AscSetChipControl(iop_base,
10363 (uchar) (CC_SCSI_RESET | CC_HALT));
10364 DvcDelayNanoSecond(asc_dvc, 60000);
10365 AscSetChipControl(iop_base, CC_HALT);
10366 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10367 AscSetChipStatus(iop_base, 0);
10368 AscSetChipControl(iop_base, 0);
10369 }
10370 }
10371 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
10372 (*asc_isr_callback) (asc_dvc, scsiq);
10373 } else {
10374 if ((AscReadLramByte(iop_base,
10375 (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) ==
10376 START_STOP)) {
10377 asc_dvc->unit_not_ready &= ~target_id;
10378 if (scsiq->d3.done_stat != QD_NO_ERROR) {
10379 asc_dvc->start_motor &= ~target_id;
10380 }
10381 }
10382 }
10383 return (1);
10384 } else {
10385 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
10386 FATAL_ERR_QDONE:
10387 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
10388 (*asc_isr_callback) (asc_dvc, scsiq);
10389 }
10390 return (0x80);
10391 }
10392 }
10393 return (0);
10394}
10395
10396STATIC int
10397AscISR(
10398 ASC_DVC_VAR *asc_dvc
10399)
10400{
10401 ASC_CS_TYPE chipstat;
10402 PortAddr iop_base;
10403 ushort saved_ram_addr;
10404 uchar ctrl_reg;
10405 uchar saved_ctrl_reg;
10406 int int_pending;
10407 int status;
10408 uchar host_flag;
10409
10410 iop_base = asc_dvc->iop_base;
10411 int_pending = FALSE;
10412
10413 if (AscIsIntPending(iop_base) == 0)
10414 {
10415 return int_pending;
10416 }
10417
10418 if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
10419 || (asc_dvc->isr_callback == 0)
10420) {
10421 return (ERR);
10422 }
10423 if (asc_dvc->in_critical_cnt != 0) {
10424 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
10425 return (ERR);
10426 }
10427 if (asc_dvc->is_in_int) {
10428 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
10429 return (ERR);
10430 }
10431 asc_dvc->is_in_int = TRUE;
10432 ctrl_reg = AscGetChipControl(iop_base);
10433 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
10434 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
10435 chipstat = AscGetChipStatus(iop_base);
10436 if (chipstat & CSW_SCSI_RESET_LATCH) {
10437 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
10438 int i = 10;
10439 int_pending = TRUE;
10440 asc_dvc->sdtr_done = 0;
10441 saved_ctrl_reg &= (uchar) (~CC_HALT);
10442 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) &&
10443 (i-- > 0))
10444 {
10445 DvcSleepMilliSecond(100);
10446 }
10447 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
10448 AscSetChipControl(iop_base, CC_HALT);
10449 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10450 AscSetChipStatus(iop_base, 0);
10451 chipstat = AscGetChipStatus(iop_base);
10452 }
10453 }
10454 saved_ram_addr = AscGetChipLramAddr(iop_base);
10455 host_flag = AscReadLramByte(iop_base,
10456 ASCV_HOST_FLAG_B) & (uchar) (~ASC_HOST_FLAG_IN_ISR);
10457 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10458 (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR));
10459 if ((chipstat & CSW_INT_PENDING)
10460 || (int_pending)
10461) {
10462 AscAckInterrupt(iop_base);
10463 int_pending = TRUE;
10464 if ((chipstat & CSW_HALTED) &&
10465 (ctrl_reg & CC_SINGLE_STEP)) {
10466 if (AscIsrChipHalted(asc_dvc) == ERR) {
10467 goto ISR_REPORT_QDONE_FATAL_ERROR;
10468 } else {
10469 saved_ctrl_reg &= (uchar) (~CC_HALT);
10470 }
10471 } else {
10472 ISR_REPORT_QDONE_FATAL_ERROR:
10473 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
10474 while (((status = AscIsrQDone(asc_dvc)) & 0x01) != 0) {
10475 }
10476 } else {
10477 do {
10478 if ((status = AscIsrQDone(asc_dvc)) == 1) {
10479 break;
10480 }
10481 } while (status == 0x11);
10482 }
10483 if ((status & 0x80) != 0)
10484 int_pending = ERR;
10485 }
10486 }
10487 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10488 AscSetChipLramAddr(iop_base, saved_ram_addr);
10489 AscSetChipControl(iop_base, saved_ctrl_reg);
10490 asc_dvc->is_in_int = FALSE;
10491 return (int_pending);
10492}
10493
10494/* Microcode buffer is kept after initialization for error recovery. */
10495STATIC uchar _asc_mcode_buf[] =
10496{
10497 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10498 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10499 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10500 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10501 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
10502 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10503 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
10504 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00,
10505 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
10506 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2, 0xC2, 0x00, 0x92, 0x80,
10507 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80,
10508 0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
10509 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8, 0xCD, 0x04, 0x4D, 0x00,
10510 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1,
10511 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88,
10512 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00, 0x84, 0x97, 0x07, 0xA6,
10513 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00,
10514 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6,
10515 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6, 0x34, 0x01, 0x00, 0x33,
10516 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04,
10517 0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23,
10518 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01, 0x00, 0x33, 0x0A, 0x00,
10519 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04,
10520 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01,
10521 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3, 0x3C, 0x01, 0x00, 0x05,
10522 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01,
10523 0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0,
10524 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00, 0xC2, 0x88, 0x06, 0x23,
10525 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0,
10526 0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61,
10527 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC, 0x4F, 0x00, 0x84, 0x97,
10528 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80,
10529 0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
10530 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88, 0x04, 0x98, 0xF0, 0x80,
10531 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6,
10532 0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95,
10533 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02, 0x07, 0xA6, 0x5A, 0x02,
10534 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96,
10535 0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC,
10536 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01, 0x6F, 0x00, 0xA5, 0x01,
10537 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02,
10538 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02,
10539 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E, 0x80, 0x63, 0x00, 0x43,
10540 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01,
10541 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82,
10542 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8, 0x00, 0x33, 0x1F, 0x00,
10543 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6,
10544 0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6,
10545 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xEE, 0x82,
10546 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8,
10547 0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98,
10548 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6, 0x3C, 0x04, 0x06, 0xA6,
10549 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83,
10550 0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33,
10551 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05, 0xFF, 0xA2, 0x7A, 0x03,
10552 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03,
10553 0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03,
10554 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6, 0xA4, 0x03, 0x00, 0xA6,
10555 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03,
10556 0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42,
10557 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95, 0xC0, 0x83, 0x00, 0x33,
10558 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23,
10559 0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
10560 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04, 0x06, 0xA6, 0x0A, 0x04,
10561 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84,
10562 0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
10563 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6, 0x38, 0x04, 0x00, 0x33,
10564 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC,
10565 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
10566 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0xA3, 0x01,
10567 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00,
10568 0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
10569 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04, 0x08, 0x23, 0x22, 0xA3,
10570 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23,
10571 0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98,
10572 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20, 0x81, 0x62, 0xE8, 0x81,
10573 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81,
10574 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23,
10575 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3, 0xF4, 0x04, 0x00, 0x33,
10576 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01,
10577 0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
10578 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85, 0x46, 0x97, 0xCD, 0x04,
10579 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85,
10580 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
10581 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x49, 0x00, 0x81, 0x01,
10582 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01,
10583 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
10584 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63, 0x07, 0xA4, 0xF8, 0x05,
10585 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0,
10586 0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
10587 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00, 0x62, 0x97, 0x04, 0x85,
10588 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0,
10589 0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
10590 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05, 0x80, 0x67, 0x80, 0x63,
10591 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23,
10592 0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
10593 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23, 0x07, 0x41, 0x83, 0x03,
10594 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6,
10595 0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
10596 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00, 0x52, 0x00, 0x06, 0x61,
10597 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01,
10598 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
10599 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23, 0xDF, 0x00, 0x06, 0xA6,
10600 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20,
10601 0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
10602 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B, 0x40, 0x0E, 0x80, 0x63,
10603 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43,
10604 0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
10605 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x07, 0xA6, 0xD6, 0x06,
10606 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6,
10607 0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
10608 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20, 0x81, 0x62, 0x04, 0x01,
10609 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33,
10610 0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
10611 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88, 0x00, 0x00, 0x80, 0x67,
10612 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61,
10613 0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
10614 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04, 0x80, 0x05, 0x81, 0x05,
10615 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01,
10616 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
10617 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01, 0xF1, 0x00, 0x70, 0x00,
10618 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00,
10619 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
10620 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1, 0xC4, 0x07, 0x00, 0x33,
10621 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01,
10622 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
10623 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x05, 0x05, 0x00, 0x63,
10624 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02,
10625 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
10626 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63, 0xF3, 0x04,
10627 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08,
10628 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
10629 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04, 0x5A, 0x88, 0x02, 0x01,
10630 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08,
10631 0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
10632 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x38, 0x2B,
10633 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09,
10634 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
10635 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32, 0x40, 0x36, 0x40, 0x3A,
10636 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3,
10637 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
10638 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01, 0xA1, 0x23, 0xA1, 0x01,
10639 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2,
10640 0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
10641};
10642
10643STATIC ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
10644STATIC ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
10645
10646#define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
10647STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] =
10648{
10649 INQUIRY,
10650 REQUEST_SENSE,
10651 READ_CAPACITY,
10652 READ_TOC,
10653 MODE_SELECT,
10654 MODE_SENSE,
10655 MODE_SELECT_10,
10656 MODE_SENSE_10,
10657 0xFF,
10658 0xFF,
10659 0xFF,
10660 0xFF,
10661 0xFF,
10662 0xFF,
10663 0xFF,
10664 0xFF
10665};
10666
10667STATIC int
10668AscExeScsiQueue(
10669 ASC_DVC_VAR *asc_dvc,
10670 ASC_SCSI_Q *scsiq
10671)
10672{
10673 PortAddr iop_base;
10674 ulong last_int_level;
10675 int sta;
10676 int n_q_required;
10677 int disable_syn_offset_one_fix;
10678 int i;
10679 ASC_PADDR addr;
10680 ASC_EXE_CALLBACK asc_exe_callback;
10681 ushort sg_entry_cnt = 0;
10682 ushort sg_entry_cnt_minus_one = 0;
10683 uchar target_ix;
10684 uchar tid_no;
10685 uchar sdtr_data;
10686 uchar extra_bytes;
10687 uchar scsi_cmd;
10688 uchar disable_cmd;
10689 ASC_SG_HEAD *sg_head;
10690 ASC_DCNT data_cnt;
10691
10692 iop_base = asc_dvc->iop_base;
10693 sg_head = scsiq->sg_head;
10694 asc_exe_callback = asc_dvc->exe_callback;
10695 if (asc_dvc->err_code != 0)
10696 return (ERR);
10697 if (scsiq == (ASC_SCSI_Q *) 0L) {
10698 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
10699 return (ERR);
10700 }
10701 scsiq->q1.q_no = 0;
10702 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
10703 scsiq->q1.extra_bytes = 0;
10704 }
10705 sta = 0;
10706 target_ix = scsiq->q2.target_ix;
10707 tid_no = ASC_TIX_TO_TID(target_ix);
10708 n_q_required = 1;
10709 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
10710 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
10711 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
10712 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10713 AscMsgOutSDTR(asc_dvc,
10714 asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
10715 (uchar) (asc_dvc->max_sdtr_index - 1)],
10716 (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
10717 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
10718 }
10719 }
10720 last_int_level = DvcEnterCritical();
10721 if (asc_dvc->in_critical_cnt != 0) {
10722 DvcLeaveCritical(last_int_level);
10723 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
10724 return (ERR);
10725 }
10726 asc_dvc->in_critical_cnt++;
10727 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10728 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
10729 asc_dvc->in_critical_cnt--;
10730 DvcLeaveCritical(last_int_level);
10731 return (ERR);
10732 }
10733#if !CC_VERY_LONG_SG_LIST
10734 if (sg_entry_cnt > ASC_MAX_SG_LIST)
10735 {
10736 asc_dvc->in_critical_cnt--;
10737 DvcLeaveCritical(last_int_level);
10738 return(ERR);
10739 }
10740#endif /* !CC_VERY_LONG_SG_LIST */
10741 if (sg_entry_cnt == 1) {
10742 scsiq->q1.data_addr = (ADV_PADDR) sg_head->sg_list[0].addr;
10743 scsiq->q1.data_cnt = (ADV_DCNT) sg_head->sg_list[0].bytes;
10744 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
10745 }
10746 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
10747 }
10748 scsi_cmd = scsiq->cdbptr[0];
10749 disable_syn_offset_one_fix = FALSE;
10750 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
10751 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
10752 if (scsiq->q1.cntl & QC_SG_HEAD) {
10753 data_cnt = 0;
10754 for (i = 0; i < sg_entry_cnt; i++) {
10755 data_cnt += (ADV_DCNT) le32_to_cpu(sg_head->sg_list[i].bytes);
10756 }
10757 } else {
10758 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
10759 }
10760 if (data_cnt != 0UL) {
10761 if (data_cnt < 512UL) {
10762 disable_syn_offset_one_fix = TRUE;
10763 } else {
10764 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST; i++) {
10765 disable_cmd = _syn_offset_one_disable_cmd[i];
10766 if (disable_cmd == 0xFF) {
10767 break;
10768 }
10769 if (scsi_cmd == disable_cmd) {
10770 disable_syn_offset_one_fix = TRUE;
10771 break;
10772 }
10773 }
10774 }
10775 }
10776 }
10777 if (disable_syn_offset_one_fix) {
10778 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
10779 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
10780 ASC_TAG_FLAG_DISABLE_DISCONNECT);
10781 } else {
10782 scsiq->q2.tag_code &= 0x27;
10783 }
10784 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10785 if (asc_dvc->bug_fix_cntl) {
10786 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10787 if ((scsi_cmd == READ_6) ||
10788 (scsi_cmd == READ_10)) {
10789 addr =
10790 (ADV_PADDR) le32_to_cpu(
10791 sg_head->sg_list[sg_entry_cnt_minus_one].addr) +
10792 (ADV_DCNT) le32_to_cpu(
10793 sg_head->sg_list[sg_entry_cnt_minus_one].bytes);
10794 extra_bytes = (uchar) ((ushort) addr & 0x0003);
10795 if ((extra_bytes != 0) &&
10796 ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
10797 == 0)) {
10798 scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
10799 scsiq->q1.extra_bytes = extra_bytes;
10800 data_cnt = le32_to_cpu(
10801 sg_head->sg_list[sg_entry_cnt_minus_one].bytes);
10802 data_cnt -= (ASC_DCNT) extra_bytes;
10803 sg_head->sg_list[sg_entry_cnt_minus_one].bytes =
10804 cpu_to_le32(data_cnt);
10805 }
10806 }
10807 }
10808 }
10809 sg_head->entry_to_copy = sg_head->entry_cnt;
10810#if CC_VERY_LONG_SG_LIST
10811 /*
10812 * Set the sg_entry_cnt to the maximum possible. The rest of
10813 * the SG elements will be copied when the RISC completes the
10814 * SG elements that fit and halts.
10815 */
10816 if (sg_entry_cnt > ASC_MAX_SG_LIST)
10817 {
10818 sg_entry_cnt = ASC_MAX_SG_LIST;
10819 }
10820#endif /* CC_VERY_LONG_SG_LIST */
10821 n_q_required = AscSgListToQueue(sg_entry_cnt);
10822 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
10823 (uint) n_q_required) || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
10824 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
10825 n_q_required)) == 1) {
10826 asc_dvc->in_critical_cnt--;
10827 if (asc_exe_callback != 0) {
10828 (*asc_exe_callback) (asc_dvc, scsiq);
10829 }
10830 DvcLeaveCritical(last_int_level);
10831 return (sta);
10832 }
10833 }
10834 } else {
10835 if (asc_dvc->bug_fix_cntl) {
10836 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10837 if ((scsi_cmd == READ_6) ||
10838 (scsi_cmd == READ_10)) {
10839 addr = le32_to_cpu(scsiq->q1.data_addr) +
10840 le32_to_cpu(scsiq->q1.data_cnt);
10841 extra_bytes = (uchar) ((ushort) addr & 0x0003);
10842 if ((extra_bytes != 0) &&
10843 ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
10844 == 0)) {
10845 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
10846 if (((ushort) data_cnt & 0x01FF) == 0) {
10847 scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
10848 data_cnt -= (ASC_DCNT) extra_bytes;
10849 scsiq->q1.data_cnt = cpu_to_le32(data_cnt);
10850 scsiq->q1.extra_bytes = extra_bytes;
10851 }
10852 }
10853 }
10854 }
10855 }
10856 n_q_required = 1;
10857 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
10858 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
10859 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
10860 n_q_required)) == 1) {
10861 asc_dvc->in_critical_cnt--;
10862 if (asc_exe_callback != 0) {
10863 (*asc_exe_callback) (asc_dvc, scsiq);
10864 }
10865 DvcLeaveCritical(last_int_level);
10866 return (sta);
10867 }
10868 }
10869 }
10870 asc_dvc->in_critical_cnt--;
10871 DvcLeaveCritical(last_int_level);
10872 return (sta);
10873}
10874
10875STATIC int
10876AscSendScsiQueue(
10877 ASC_DVC_VAR *asc_dvc,
10878 ASC_SCSI_Q *scsiq,
10879 uchar n_q_required
10880)
10881{
10882 PortAddr iop_base;
10883 uchar free_q_head;
10884 uchar next_qp;
10885 uchar tid_no;
10886 uchar target_ix;
10887 int sta;
10888
10889 iop_base = asc_dvc->iop_base;
10890 target_ix = scsiq->q2.target_ix;
10891 tid_no = ASC_TIX_TO_TID(target_ix);
10892 sta = 0;
10893 free_q_head = (uchar) AscGetVarFreeQHead(iop_base);
10894 if (n_q_required > 1) {
10895 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
10896 free_q_head, (uchar) (n_q_required)))
10897 != (uchar) ASC_QLINK_END) {
10898 asc_dvc->last_q_shortage = 0;
10899 scsiq->sg_head->queue_cnt = n_q_required - 1;
10900 scsiq->q1.q_no = free_q_head;
10901 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
10902 free_q_head)) == 1) {
10903 AscPutVarFreeQHead(iop_base, next_qp);
10904 asc_dvc->cur_total_qng += (uchar) (n_q_required);
10905 asc_dvc->cur_dvc_qng[tid_no]++;
10906 }
10907 return (sta);
10908 }
10909 } else if (n_q_required == 1) {
10910 if ((next_qp = AscAllocFreeQueue(iop_base,
10911 free_q_head)) != ASC_QLINK_END) {
10912 scsiq->q1.q_no = free_q_head;
10913 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
10914 free_q_head)) == 1) {
10915 AscPutVarFreeQHead(iop_base, next_qp);
10916 asc_dvc->cur_total_qng++;
10917 asc_dvc->cur_dvc_qng[tid_no]++;
10918 }
10919 return (sta);
10920 }
10921 }
10922 return (sta);
10923}
10924
10925STATIC int
10926AscSgListToQueue(
10927 int sg_list
10928)
10929{
10930 int n_sg_list_qs;
10931
10932 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
10933 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
10934 n_sg_list_qs++;
10935 return (n_sg_list_qs + 1);
10936}
10937
10938
10939STATIC uint
10940AscGetNumOfFreeQueue(
10941 ASC_DVC_VAR *asc_dvc,
10942 uchar target_ix,
10943 uchar n_qs
10944)
10945{
10946 uint cur_used_qs;
10947 uint cur_free_qs;
10948 ASC_SCSI_BIT_ID_TYPE target_id;
10949 uchar tid_no;
10950
10951 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
10952 tid_no = ASC_TIX_TO_TID(target_ix);
10953 if ((asc_dvc->unit_not_ready & target_id) ||
10954 (asc_dvc->queue_full_or_busy & target_id)) {
10955 return (0);
10956 }
10957 if (n_qs == 1) {
10958 cur_used_qs = (uint) asc_dvc->cur_total_qng +
10959 (uint) asc_dvc->last_q_shortage +
10960 (uint) ASC_MIN_FREE_Q;
10961 } else {
10962 cur_used_qs = (uint) asc_dvc->cur_total_qng +
10963 (uint) ASC_MIN_FREE_Q;
10964 }
10965 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
10966 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
10967 if (asc_dvc->cur_dvc_qng[tid_no] >=
10968 asc_dvc->max_dvc_qng[tid_no]) {
10969 return (0);
10970 }
10971 return (cur_free_qs);
10972 }
10973 if (n_qs > 1) {
10974 if ((n_qs > asc_dvc->last_q_shortage) && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
10975 asc_dvc->last_q_shortage = n_qs;
10976 }
10977 }
10978 return (0);
10979}
10980
10981STATIC int
10982AscPutReadyQueue(
10983 ASC_DVC_VAR *asc_dvc,
10984 ASC_SCSI_Q *scsiq,
10985 uchar q_no
10986)
10987{
10988 ushort q_addr;
10989 uchar tid_no;
10990 uchar sdtr_data;
10991 uchar syn_period_ix;
10992 uchar syn_offset;
10993 PortAddr iop_base;
10994
10995 iop_base = asc_dvc->iop_base;
10996 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
10997 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
10998 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
10999 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
11000 syn_period_ix = (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
11001 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
11002 AscMsgOutSDTR(asc_dvc,
11003 asc_dvc->sdtr_period_tbl[syn_period_ix],
11004 syn_offset);
11005 scsiq->q1.cntl |= QC_MSG_OUT;
11006 }
11007 q_addr = ASC_QNO_TO_QADDR(q_no);
11008 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
11009 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG ;
11010 }
11011 scsiq->q1.status = QS_FREE;
11012 AscMemWordCopyPtrToLram(iop_base,
11013 q_addr + ASC_SCSIQ_CDB_BEG,
11014 (uchar *) scsiq->cdbptr,
11015 scsiq->q2.cdb_len >> 1);
11016
11017 DvcPutScsiQ(iop_base,
11018 q_addr + ASC_SCSIQ_CPY_BEG,
11019 (uchar *) &scsiq->q1.cntl,
11020 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
11021 AscWriteLramWord(iop_base,
11022 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
11023 (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY));
11024 return (1);
11025}
11026
11027STATIC int
11028AscPutReadySgListQueue(
11029 ASC_DVC_VAR *asc_dvc,
11030 ASC_SCSI_Q *scsiq,
11031 uchar q_no
11032)
11033{
11034 int sta;
11035 int i;
11036 ASC_SG_HEAD *sg_head;
11037 ASC_SG_LIST_Q scsi_sg_q;
11038 ASC_DCNT saved_data_addr;
11039 ASC_DCNT saved_data_cnt;
11040 PortAddr iop_base;
11041 ushort sg_list_dwords;
11042 ushort sg_index;
11043 ushort sg_entry_cnt;
11044 ushort q_addr;
11045 uchar next_qp;
11046
11047 iop_base = asc_dvc->iop_base;
11048 sg_head = scsiq->sg_head;
11049 saved_data_addr = scsiq->q1.data_addr;
11050 saved_data_cnt = scsiq->q1.data_cnt;
11051 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
11052 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
11053#if CC_VERY_LONG_SG_LIST
11054 /*
11055 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
11056 * then not all SG elements will fit in the allocated queues.
11057 * The rest of the SG elements will be copied when the RISC
11058 * completes the SG elements that fit and halts.
11059 */
11060 if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
11061 {
11062 /*
11063 * Set sg_entry_cnt to be the number of SG elements that
11064 * will fit in the allocated SG queues. It is minus 1, because
11065 * the first SG element is handled above. ASC_MAX_SG_LIST is
11066 * already inflated by 1 to account for this. For example it
11067 * may be 50 which is 1 + 7 queues * 7 SG elements.
11068 */
11069 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
11070
11071 /*
11072 * Keep track of remaining number of SG elements that will
11073 * need to be handled from a_isr.c.
11074 */
11075 scsiq->remain_sg_entry_cnt = sg_head->entry_cnt - ASC_MAX_SG_LIST;
11076 } else
11077 {
11078#endif /* CC_VERY_LONG_SG_LIST */
11079 /*
11080 * Set sg_entry_cnt to be the number of SG elements that
11081 * will fit in the allocated SG queues. It is minus 1, because
11082 * the first SG element is handled above.
11083 */
11084 sg_entry_cnt = sg_head->entry_cnt - 1;
11085#if CC_VERY_LONG_SG_LIST
11086 }
11087#endif /* CC_VERY_LONG_SG_LIST */
11088 if (sg_entry_cnt != 0) {
11089 scsiq->q1.cntl |= QC_SG_HEAD;
11090 q_addr = ASC_QNO_TO_QADDR(q_no);
11091 sg_index = 1;
11092 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
11093 scsi_sg_q.sg_head_qp = q_no;
11094 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
11095 for (i = 0; i < sg_head->queue_cnt; i++) {
11096 scsi_sg_q.seq_no = i + 1;
11097 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
11098 sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
11099 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
11100 if (i == 0) {
11101 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q;
11102 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q;
11103 } else {
11104 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
11105 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
11106 }
11107 } else {
11108#if CC_VERY_LONG_SG_LIST
11109 /*
11110 * This is the last SG queue in the list of
11111 * allocated SG queues. If there are more
11112 * SG elements than will fit in the allocated
11113 * queues, then set the QCSG_SG_XFER_MORE flag.
11114 */
11115 if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
11116 {
11117 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
11118 } else
11119 {
11120#endif /* CC_VERY_LONG_SG_LIST */
11121 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
11122#if CC_VERY_LONG_SG_LIST
11123 }
11124#endif /* CC_VERY_LONG_SG_LIST */
11125 sg_list_dwords = sg_entry_cnt << 1;
11126 if (i == 0) {
11127 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
11128 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt;
11129 } else {
11130 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
11131 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
11132 }
11133 sg_entry_cnt = 0;
11134 }
11135 next_qp = AscReadLramByte(iop_base,
11136 (ushort) (q_addr + ASC_SCSIQ_B_FWD));
11137 scsi_sg_q.q_no = next_qp;
11138 q_addr = ASC_QNO_TO_QADDR(next_qp);
11139 AscMemWordCopyPtrToLram(iop_base,
11140 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
11141 (uchar *) &scsi_sg_q,
11142 sizeof(ASC_SG_LIST_Q) >> 1);
11143 AscMemDWordCopyPtrToLram(iop_base,
11144 q_addr + ASC_SGQ_LIST_BEG,
11145 (uchar *) &sg_head->sg_list[sg_index],
11146 sg_list_dwords);
11147 sg_index += ASC_SG_LIST_PER_Q;
11148 scsiq->next_sg_index = sg_index;
11149 }
11150 } else {
11151 scsiq->q1.cntl &= ~QC_SG_HEAD;
11152 }
11153 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
11154 scsiq->q1.data_addr = saved_data_addr;
11155 scsiq->q1.data_cnt = saved_data_cnt;
11156 return (sta);
11157}
11158
11159STATIC int
11160AscSetRunChipSynRegAtID(
11161 PortAddr iop_base,
11162 uchar tid_no,
11163 uchar sdtr_data
11164)
11165{
11166 int sta = FALSE;
11167
11168 if (AscHostReqRiscHalt(iop_base)) {
11169 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
11170 AscStartChip(iop_base);
11171 return (sta);
11172 }
11173 return (sta);
11174}
11175
11176STATIC int
11177AscSetChipSynRegAtID(
11178 PortAddr iop_base,
11179 uchar id,
11180 uchar sdtr_data
11181)
11182{
11183 ASC_SCSI_BIT_ID_TYPE org_id;
11184 int i;
11185 int sta = TRUE;
11186
11187 AscSetBank(iop_base, 1);
11188 org_id = AscReadChipDvcID(iop_base);
11189 for (i = 0; i <= ASC_MAX_TID; i++) {
11190 if (org_id == (0x01 << i))
11191 break;
11192 }
11193 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
11194 AscWriteChipDvcID(iop_base, id);
11195 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
11196 AscSetBank(iop_base, 0);
11197 AscSetChipSyn(iop_base, sdtr_data);
11198 if (AscGetChipSyn(iop_base) != sdtr_data) {
11199 sta = FALSE;
11200 }
11201 } else {
11202 sta = FALSE;
11203 }
11204 AscSetBank(iop_base, 1);
11205 AscWriteChipDvcID(iop_base, org_id);
11206 AscSetBank(iop_base, 0);
11207 return (sta);
11208}
11209
11210STATIC ushort
11211AscInitLram(
11212 ASC_DVC_VAR *asc_dvc
11213)
11214{
11215 uchar i;
11216 ushort s_addr;
11217 PortAddr iop_base;
11218 ushort warn_code;
11219
11220 iop_base = asc_dvc->iop_base;
11221 warn_code = 0;
11222 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
11223 (ushort) (((int) (asc_dvc->max_total_qng + 2 + 1) * 64) >> 1)
11224);
11225 i = ASC_MIN_ACTIVE_QNO;
11226 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
11227 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11228 (uchar) (i + 1));
11229 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11230 (uchar) (asc_dvc->max_total_qng));
11231 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11232 (uchar) i);
11233 i++;
11234 s_addr += ASC_QBLK_SIZE;
11235 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
11236 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11237 (uchar) (i + 1));
11238 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11239 (uchar) (i - 1));
11240 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11241 (uchar) i);
11242 }
11243 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11244 (uchar) ASC_QLINK_END);
11245 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11246 (uchar) (asc_dvc->max_total_qng - 1));
11247 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11248 (uchar) asc_dvc->max_total_qng);
11249 i++;
11250 s_addr += ASC_QBLK_SIZE;
11251 for (; i <= (uchar) (asc_dvc->max_total_qng + 3);
11252 i++, s_addr += ASC_QBLK_SIZE) {
11253 AscWriteLramByte(iop_base,
11254 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_FWD), i);
11255 AscWriteLramByte(iop_base,
11256 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_BWD), i);
11257 AscWriteLramByte(iop_base,
11258 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_QNO), i);
11259 }
11260 return (warn_code);
11261}
11262
11263STATIC ushort
11264AscInitQLinkVar(
11265 ASC_DVC_VAR *asc_dvc
11266)
11267{
11268 PortAddr iop_base;
11269 int i;
11270 ushort lram_addr;
11271
11272 iop_base = asc_dvc->iop_base;
11273 AscPutRiscVarFreeQHead(iop_base, 1);
11274 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
11275 AscPutVarFreeQHead(iop_base, 1);
11276 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
11277 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
11278 (uchar) ((int) asc_dvc->max_total_qng + 1));
11279 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
11280 (uchar) ((int) asc_dvc->max_total_qng + 2));
11281 AscWriteLramByte(iop_base, (ushort) ASCV_TOTAL_READY_Q_B,
11282 asc_dvc->max_total_qng);
11283 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
11284 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
11285 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
11286 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
11287 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
11288 AscPutQDoneInProgress(iop_base, 0);
11289 lram_addr = ASC_QADR_BEG;
11290 for (i = 0; i < 32; i++, lram_addr += 2) {
11291 AscWriteLramWord(iop_base, lram_addr, 0);
11292 }
11293 return (0);
11294}
11295
11296STATIC int
11297AscSetLibErrorCode(
11298 ASC_DVC_VAR *asc_dvc,
11299 ushort err_code
11300)
11301{
11302 if (asc_dvc->err_code == 0) {
11303 asc_dvc->err_code = err_code;
11304 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
11305 err_code);
11306 }
11307 return (err_code);
11308}
11309
11310
11311STATIC uchar
11312AscMsgOutSDTR(
11313 ASC_DVC_VAR *asc_dvc,
11314 uchar sdtr_period,
11315 uchar sdtr_offset
11316)
11317{
11318 EXT_MSG sdtr_buf;
11319 uchar sdtr_period_index;
11320 PortAddr iop_base;
11321
11322 iop_base = asc_dvc->iop_base;
11323 sdtr_buf.msg_type = MS_EXTEND;
11324 sdtr_buf.msg_len = MS_SDTR_LEN;
11325 sdtr_buf.msg_req = MS_SDTR_CODE;
11326 sdtr_buf.xfer_period = sdtr_period;
11327 sdtr_offset &= ASC_SYN_MAX_OFFSET;
11328 sdtr_buf.req_ack_offset = sdtr_offset;
11329 if ((sdtr_period_index =
11330 AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
11331 asc_dvc->max_sdtr_index) {
11332 AscMemWordCopyPtrToLram(iop_base,
11333 ASCV_MSGOUT_BEG,
11334 (uchar *) &sdtr_buf,
11335 sizeof (EXT_MSG) >> 1);
11336 return ((sdtr_period_index << 4) | sdtr_offset);
11337 } else {
11338
11339 sdtr_buf.req_ack_offset = 0;
11340 AscMemWordCopyPtrToLram(iop_base,
11341 ASCV_MSGOUT_BEG,
11342 (uchar *) &sdtr_buf,
11343 sizeof (EXT_MSG) >> 1);
11344 return (0);
11345 }
11346}
11347
11348STATIC uchar
11349AscCalSDTRData(
11350 ASC_DVC_VAR *asc_dvc,
11351 uchar sdtr_period,
11352 uchar syn_offset
11353)
11354{
11355 uchar byte;
11356 uchar sdtr_period_ix;
11357
11358 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
11359 if (
11360 (sdtr_period_ix > asc_dvc->max_sdtr_index)
11361) {
11362 return (0xFF);
11363 }
11364 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
11365 return (byte);
11366}
11367
11368STATIC void
11369AscSetChipSDTR(
11370 PortAddr iop_base,
11371 uchar sdtr_data,
11372 uchar tid_no
11373)
11374{
11375 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
11376 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
11377 return;
11378}
11379
11380STATIC uchar
11381AscGetSynPeriodIndex(
11382 ASC_DVC_VAR *asc_dvc,
11383 uchar syn_time
11384)
11385{
11386 uchar *period_table;
11387 int max_index;
11388 int min_index;
11389 int i;
11390
11391 period_table = asc_dvc->sdtr_period_tbl;
11392 max_index = (int) asc_dvc->max_sdtr_index;
11393 min_index = (int)asc_dvc->host_init_sdtr_index;
11394 if ((syn_time <= period_table[max_index])) {
11395 for (i = min_index; i < (max_index - 1); i++) {
11396 if (syn_time <= period_table[i]) {
11397 return ((uchar) i);
11398 }
11399 }
11400 return ((uchar) max_index);
11401 } else {
11402 return ((uchar) (max_index + 1));
11403 }
11404}
11405
11406STATIC uchar
11407AscAllocFreeQueue(
11408 PortAddr iop_base,
11409 uchar free_q_head
11410)
11411{
11412 ushort q_addr;
11413 uchar next_qp;
11414 uchar q_status;
11415
11416 q_addr = ASC_QNO_TO_QADDR(free_q_head);
11417 q_status = (uchar) AscReadLramByte(iop_base,
11418 (ushort) (q_addr + ASC_SCSIQ_B_STATUS));
11419 next_qp = AscReadLramByte(iop_base,
11420 (ushort) (q_addr + ASC_SCSIQ_B_FWD));
11421 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
11422 return (next_qp);
11423 }
11424 return (ASC_QLINK_END);
11425}
11426
11427STATIC uchar
11428AscAllocMultipleFreeQueue(
11429 PortAddr iop_base,
11430 uchar free_q_head,
11431 uchar n_free_q
11432)
11433{
11434 uchar i;
11435
11436 for (i = 0; i < n_free_q; i++) {
11437 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
11438 == ASC_QLINK_END) {
11439 return (ASC_QLINK_END);
11440 }
11441 }
11442 return (free_q_head);
11443}
11444
11445STATIC int
11446AscHostReqRiscHalt(
11447 PortAddr iop_base
11448)
11449{
11450 int count = 0;
11451 int sta = 0;
11452 uchar saved_stop_code;
11453
11454 if (AscIsChipHalted(iop_base))
11455 return (1);
11456 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
11457 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11458 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP
11459);
11460 do {
11461 if (AscIsChipHalted(iop_base)) {
11462 sta = 1;
11463 break;
11464 }
11465 DvcSleepMilliSecond(100);
11466 } while (count++ < 20);
11467 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
11468 return (sta);
11469}
11470
11471STATIC int
11472AscStopQueueExe(
11473 PortAddr iop_base
11474)
11475{
11476 int count = 0;
11477
11478 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
11479 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11480 ASC_STOP_REQ_RISC_STOP);
11481 do {
11482 if (
11483 AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
11484 ASC_STOP_ACK_RISC_STOP) {
11485 return (1);
11486 }
11487 DvcSleepMilliSecond(100);
11488 } while (count++ < 20);
11489 }
11490 return (0);
11491}
11492
11493STATIC void
11494DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
11495{
11496 udelay(micro_sec);
11497}
11498
11499STATIC void
11500DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
11501{
11502 udelay((nano_sec + 999)/1000);
11503}
11504
11505#ifdef CONFIG_ISA
11506STATIC ASC_DCNT __init
11507AscGetEisaProductID(
11508 PortAddr iop_base)
11509{
11510 PortAddr eisa_iop;
11511 ushort product_id_high, product_id_low;
11512 ASC_DCNT product_id;
11513
11514 eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
11515 product_id_low = inpw(eisa_iop);
11516 product_id_high = inpw(eisa_iop + 2);
11517 product_id = ((ASC_DCNT) product_id_high << 16) |
11518 (ASC_DCNT) product_id_low;
11519 return (product_id);
11520}
11521
11522STATIC PortAddr __init
11523AscSearchIOPortAddrEISA(
11524 PortAddr iop_base)
11525{
11526 ASC_DCNT eisa_product_id;
11527
11528 if (iop_base == 0) {
11529 iop_base = ASC_EISA_MIN_IOP_ADDR;
11530 } else {
11531 if (iop_base == ASC_EISA_MAX_IOP_ADDR)
11532 return (0);
11533 if ((iop_base & 0x0050) == 0x0050) {
11534 iop_base += ASC_EISA_BIG_IOP_GAP;
11535 } else {
11536 iop_base += ASC_EISA_SMALL_IOP_GAP;
11537 }
11538 }
11539 while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
11540 eisa_product_id = AscGetEisaProductID(iop_base);
11541 if ((eisa_product_id == ASC_EISA_ID_740) ||
11542 (eisa_product_id == ASC_EISA_ID_750)) {
11543 if (AscFindSignature(iop_base)) {
11544 inpw(iop_base + 4);
11545 return (iop_base);
11546 }
11547 }
11548 if (iop_base == ASC_EISA_MAX_IOP_ADDR)
11549 return (0);
11550 if ((iop_base & 0x0050) == 0x0050) {
11551 iop_base += ASC_EISA_BIG_IOP_GAP;
11552 } else {
11553 iop_base += ASC_EISA_SMALL_IOP_GAP;
11554 }
11555 }
11556 return (0);
11557}
11558#endif /* CONFIG_ISA */
11559
11560STATIC int
11561AscStartChip(
11562 PortAddr iop_base
11563)
11564{
11565 AscSetChipControl(iop_base, 0);
11566 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
11567 return (0);
11568 }
11569 return (1);
11570}
11571
11572STATIC int
11573AscStopChip(
11574 PortAddr iop_base
11575)
11576{
11577 uchar cc_val;
11578
11579 cc_val = AscGetChipControl(iop_base) & (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
11580 AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT));
11581 AscSetChipIH(iop_base, INS_HALT);
11582 AscSetChipIH(iop_base, INS_RFLAG_WTM);
11583 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
11584 return (0);
11585 }
11586 return (1);
11587}
11588
11589STATIC int
11590AscIsChipHalted(
11591 PortAddr iop_base
11592)
11593{
11594 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
11595 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
11596 return (1);
11597 }
11598 }
11599 return (0);
11600}
11601
11602STATIC void
11603AscSetChipIH(
11604 PortAddr iop_base,
11605 ushort ins_code
11606)
11607{
11608 AscSetBank(iop_base, 1);
11609 AscWriteChipIH(iop_base, ins_code);
11610 AscSetBank(iop_base, 0);
11611 return;
11612}
11613
11614STATIC void
11615AscAckInterrupt(
11616 PortAddr iop_base
11617)
11618{
11619 uchar host_flag;
11620 uchar risc_flag;
11621 ushort loop;
11622
11623 loop = 0;
11624 do {
11625 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
11626 if (loop++ > 0x7FFF) {
11627 break;
11628 }
11629 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
11630 host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
11631 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
11632 (uchar) (host_flag | ASC_HOST_FLAG_ACK_INT));
11633 AscSetChipStatus(iop_base, CIW_INT_ACK);
11634 loop = 0;
11635 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
11636 AscSetChipStatus(iop_base, CIW_INT_ACK);
11637 if (loop++ > 3) {
11638 break;
11639 }
11640 }
11641 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
11642 return;
11643}
11644
11645STATIC void
11646AscDisableInterrupt(
11647 PortAddr iop_base
11648)
11649{
11650 ushort cfg;
11651
11652 cfg = AscGetChipCfgLsw(iop_base);
11653 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
11654 return;
11655}
11656
11657STATIC void
11658AscEnableInterrupt(
11659 PortAddr iop_base
11660)
11661{
11662 ushort cfg;
11663
11664 cfg = AscGetChipCfgLsw(iop_base);
11665 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
11666 return;
11667}
11668
11669
11670
11671STATIC void
11672AscSetBank(
11673 PortAddr iop_base,
11674 uchar bank
11675)
11676{
11677 uchar val;
11678
11679 val = AscGetChipControl(iop_base) &
11680 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | CC_CHIP_RESET));
11681 if (bank == 1) {
11682 val |= CC_BANK_ONE;
11683 } else if (bank == 2) {
11684 val |= CC_DIAG | CC_BANK_ONE;
11685 } else {
11686 val &= ~CC_BANK_ONE;
11687 }
11688 AscSetChipControl(iop_base, val);
11689 return;
11690}
11691
11692STATIC int
11693AscResetChipAndScsiBus(
11694 ASC_DVC_VAR *asc_dvc
11695)
11696{
11697 PortAddr iop_base;
11698 int i = 10;
11699
11700 iop_base = asc_dvc->iop_base;
11701 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) && (i-- > 0))
11702 {
11703 DvcSleepMilliSecond(100);
11704 }
11705 AscStopChip(iop_base);
11706 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
11707 DvcDelayNanoSecond(asc_dvc, 60000);
11708 AscSetChipIH(iop_base, INS_RFLAG_WTM);
11709 AscSetChipIH(iop_base, INS_HALT);
11710 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
11711 AscSetChipControl(iop_base, CC_HALT);
11712 DvcSleepMilliSecond(200);
11713 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
11714 AscSetChipStatus(iop_base, 0);
11715 return (AscIsChipHalted(iop_base));
11716}
11717
11718STATIC ASC_DCNT __init
11719AscGetMaxDmaCount(
11720 ushort bus_type)
11721{
11722 if (bus_type & ASC_IS_ISA)
11723 return (ASC_MAX_ISA_DMA_COUNT);
11724 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
11725 return (ASC_MAX_VL_DMA_COUNT);
11726 return (ASC_MAX_PCI_DMA_COUNT);
11727}
11728
11729#ifdef CONFIG_ISA
11730STATIC ushort __init
11731AscGetIsaDmaChannel(
11732 PortAddr iop_base)
11733{
11734 ushort channel;
11735
11736 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
11737 if (channel == 0x03)
11738 return (0);
11739 else if (channel == 0x00)
11740 return (7);
11741 return (channel + 4);
11742}
11743
11744STATIC ushort __init
11745AscSetIsaDmaChannel(
11746 PortAddr iop_base,
11747 ushort dma_channel)
11748{
11749 ushort cfg_lsw;
11750 uchar value;
11751
11752 if ((dma_channel >= 5) && (dma_channel <= 7)) {
11753 if (dma_channel == 7)
11754 value = 0x00;
11755 else
11756 value = dma_channel - 4;
11757 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
11758 cfg_lsw |= value;
11759 AscSetChipCfgLsw(iop_base, cfg_lsw);
11760 return (AscGetIsaDmaChannel(iop_base));
11761 }
11762 return (0);
11763}
11764
11765STATIC uchar __init
11766AscSetIsaDmaSpeed(
11767 PortAddr iop_base,
11768 uchar speed_value)
11769{
11770 speed_value &= 0x07;
11771 AscSetBank(iop_base, 1);
11772 AscWriteChipDmaSpeed(iop_base, speed_value);
11773 AscSetBank(iop_base, 0);
11774 return (AscGetIsaDmaSpeed(iop_base));
11775}
11776
11777STATIC uchar __init
11778AscGetIsaDmaSpeed(
11779 PortAddr iop_base
11780)
11781{
11782 uchar speed_value;
11783
11784 AscSetBank(iop_base, 1);
11785 speed_value = AscReadChipDmaSpeed(iop_base);
11786 speed_value &= 0x07;
11787 AscSetBank(iop_base, 0);
11788 return (speed_value);
11789}
11790#endif /* CONFIG_ISA */
11791
11792STATIC ushort __init
11793AscReadPCIConfigWord(
11794 ASC_DVC_VAR *asc_dvc,
11795 ushort pci_config_offset)
11796{
11797 uchar lsb, msb;
11798
11799 lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
11800 msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
11801 return ((ushort) ((msb << 8) | lsb));
11802}
11803
11804STATIC ushort __init
11805AscInitGetConfig(
11806 ASC_DVC_VAR *asc_dvc
11807)
11808{
11809 ushort warn_code;
11810 PortAddr iop_base;
11811 ushort PCIDeviceID;
11812 ushort PCIVendorID;
11813 uchar PCIRevisionID;
11814 uchar prevCmdRegBits;
11815
11816 warn_code = 0;
11817 iop_base = asc_dvc->iop_base;
11818 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
11819 if (asc_dvc->err_code != 0) {
11820 return (UW_ERR);
11821 }
11822 if (asc_dvc->bus_type == ASC_IS_PCI) {
11823 PCIVendorID = AscReadPCIConfigWord(asc_dvc,
11824 AscPCIConfigVendorIDRegister);
11825
11826 PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
11827 AscPCIConfigDeviceIDRegister);
11828
11829 PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
11830 AscPCIConfigRevisionIDRegister);
11831
2672ea86 11832 if (PCIVendorID != PCI_VENDOR_ID_ASP) {
1da177e4
LT
11833 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
11834 }
11835 prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
11836 AscPCIConfigCommandRegister);
11837
11838 if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
11839 AscPCICmdRegBits_IOMemBusMaster) {
11840 DvcWritePCIConfigByte(asc_dvc,
11841 AscPCIConfigCommandRegister,
11842 (prevCmdRegBits |
11843 AscPCICmdRegBits_IOMemBusMaster));
11844
11845 if ((DvcReadPCIConfigByte(asc_dvc,
11846 AscPCIConfigCommandRegister)
11847 & AscPCICmdRegBits_IOMemBusMaster)
11848 != AscPCICmdRegBits_IOMemBusMaster) {
11849 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
11850 }
11851 }
2672ea86
DJ
11852 if ((PCIDeviceID == PCI_DEVICE_ID_ASP_1200A) ||
11853 (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940)) {
1da177e4
LT
11854 DvcWritePCIConfigByte(asc_dvc,
11855 AscPCIConfigLatencyTimer, 0x00);
11856 if (DvcReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer)
11857 != 0x00) {
11858 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
11859 }
2672ea86 11860 } else if (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940U) {
1da177e4
LT
11861 if (DvcReadPCIConfigByte(asc_dvc,
11862 AscPCIConfigLatencyTimer) < 0x20) {
11863 DvcWritePCIConfigByte(asc_dvc,
11864 AscPCIConfigLatencyTimer, 0x20);
11865
11866 if (DvcReadPCIConfigByte(asc_dvc,
11867 AscPCIConfigLatencyTimer) < 0x20) {
11868 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
11869 }
11870 }
11871 }
11872 }
11873
11874 if (AscFindSignature(iop_base)) {
11875 warn_code |= AscInitAscDvcVar(asc_dvc);
11876 warn_code |= AscInitFromEEP(asc_dvc);
11877 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
11878 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
11879 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
11880 }
11881 } else {
11882 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11883 }
11884 return(warn_code);
11885}
11886
11887STATIC ushort __init
11888AscInitSetConfig(
11889 ASC_DVC_VAR *asc_dvc
11890)
11891{
11892 ushort warn_code = 0;
11893
11894 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
11895 if (asc_dvc->err_code != 0)
11896 return (UW_ERR);
11897 if (AscFindSignature(asc_dvc->iop_base)) {
11898 warn_code |= AscInitFromAscDvcVar(asc_dvc);
11899 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
11900 } else {
11901 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11902 }
11903 return (warn_code);
11904}
11905
11906STATIC ushort __init
11907AscInitFromAscDvcVar(
11908 ASC_DVC_VAR *asc_dvc
11909)
11910{
11911 PortAddr iop_base;
11912 ushort cfg_msw;
11913 ushort warn_code;
11914 ushort pci_device_id = 0;
11915
11916 iop_base = asc_dvc->iop_base;
11917#ifdef CONFIG_PCI
11918 if (asc_dvc->cfg->dev)
11919 pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device;
11920#endif
11921 warn_code = 0;
11922 cfg_msw = AscGetChipCfgMsw(iop_base);
11923 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
11924 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
11925 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
11926 AscSetChipCfgMsw(iop_base, cfg_msw);
11927 }
11928 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
11929 asc_dvc->cfg->cmd_qng_enabled) {
11930 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
11931 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
11932 }
11933 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
11934 warn_code |= ASC_WARN_AUTO_CONFIG;
11935 }
11936 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
11937 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
11938 != asc_dvc->irq_no) {
11939 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
11940 }
11941 }
11942 if (asc_dvc->bus_type & ASC_IS_PCI) {
11943 cfg_msw &= 0xFFC0;
11944 AscSetChipCfgMsw(iop_base, cfg_msw);
11945 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
11946 } else {
2672ea86
DJ
11947 if ((pci_device_id == PCI_DEVICE_ID_ASP_1200A) ||
11948 (pci_device_id == PCI_DEVICE_ID_ASP_ABP940)) {
1da177e4
LT
11949 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
11950 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
11951 }
11952 }
11953 } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
11954 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
11955 == ASC_CHIP_VER_ASYN_BUG) {
11956 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
11957 }
11958 }
11959 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
11960 asc_dvc->cfg->chip_scsi_id) {
11961 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
11962 }
11963#ifdef CONFIG_ISA
11964 if (asc_dvc->bus_type & ASC_IS_ISA) {
11965 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
11966 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
11967 }
11968#endif /* CONFIG_ISA */
11969 return (warn_code);
11970}
11971
11972STATIC ushort
11973AscInitAsc1000Driver(
11974 ASC_DVC_VAR *asc_dvc
11975)
11976{
11977 ushort warn_code;
11978 PortAddr iop_base;
11979
11980 iop_base = asc_dvc->iop_base;
11981 warn_code = 0;
11982 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
11983 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
11984 AscResetChipAndScsiBus(asc_dvc);
11985 DvcSleepMilliSecond((ASC_DCNT)
11986 ((ushort) asc_dvc->scsi_reset_wait * 1000));
11987 }
11988 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
11989 if (asc_dvc->err_code != 0)
11990 return (UW_ERR);
11991 if (!AscFindSignature(asc_dvc->iop_base)) {
11992 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11993 return (warn_code);
11994 }
11995 AscDisableInterrupt(iop_base);
11996 warn_code |= AscInitLram(asc_dvc);
11997 if (asc_dvc->err_code != 0)
11998 return (UW_ERR);
11999 ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
12000 (ulong) _asc_mcode_chksum);
12001 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
12002 _asc_mcode_size) != _asc_mcode_chksum) {
12003 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
12004 return (warn_code);
12005 }
12006 warn_code |= AscInitMicroCodeVar(asc_dvc);
12007 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
12008 AscEnableInterrupt(iop_base);
12009 return (warn_code);
12010}
12011
12012STATIC ushort __init
12013AscInitAscDvcVar(
12014 ASC_DVC_VAR *asc_dvc)
12015{
12016 int i;
12017 PortAddr iop_base;
12018 ushort warn_code;
12019 uchar chip_version;
12020
12021 iop_base = asc_dvc->iop_base;
12022 warn_code = 0;
12023 asc_dvc->err_code = 0;
12024 if ((asc_dvc->bus_type &
12025 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
12026 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
12027 }
12028 AscSetChipControl(iop_base, CC_HALT);
12029 AscSetChipStatus(iop_base, 0);
12030 asc_dvc->bug_fix_cntl = 0;
12031 asc_dvc->pci_fix_asyn_xfer = 0;
12032 asc_dvc->pci_fix_asyn_xfer_always = 0;
12033 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
12034 asc_dvc->sdtr_done = 0;
12035 asc_dvc->cur_total_qng = 0;
12036 asc_dvc->is_in_int = 0;
12037 asc_dvc->in_critical_cnt = 0;
12038 asc_dvc->last_q_shortage = 0;
12039 asc_dvc->use_tagged_qng = 0;
12040 asc_dvc->no_scam = 0;
12041 asc_dvc->unit_not_ready = 0;
12042 asc_dvc->queue_full_or_busy = 0;
12043 asc_dvc->redo_scam = 0;
12044 asc_dvc->res2 = 0;
12045 asc_dvc->host_init_sdtr_index = 0;
12046 asc_dvc->cfg->can_tagged_qng = 0;
12047 asc_dvc->cfg->cmd_qng_enabled = 0;
12048 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
12049 asc_dvc->init_sdtr = 0;
12050 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
12051 asc_dvc->scsi_reset_wait = 3;
12052 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
12053 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
12054 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
12055 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
12056 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
12057 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
12058 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
12059 ASC_LIB_VERSION_MINOR;
12060 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
12061 asc_dvc->cfg->chip_version = chip_version;
12062 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
12063 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
12064 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
12065 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
12066 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
12067 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
12068 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
12069 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
12070 asc_dvc->max_sdtr_index = 7;
12071 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
12072 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
12073 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
12074 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
12075 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
12076 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
12077 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
12078 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
12079 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
12080 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
12081 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
12082 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
12083 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
12084 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
12085 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
12086 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
12087 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
12088 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
12089 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
12090 asc_dvc->max_sdtr_index = 15;
12091 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150)
12092 {
12093 AscSetExtraControl(iop_base,
12094 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
12095 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
12096 AscSetExtraControl(iop_base,
12097 (SEC_ACTIVE_NEGATE | SEC_ENABLE_FILTER));
12098 }
12099 }
12100 if (asc_dvc->bus_type == ASC_IS_PCI) {
12101 AscSetExtraControl(iop_base, (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
12102 }
12103
12104 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
12105 if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
12106 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
12107 asc_dvc->bus_type = ASC_IS_ISAPNP;
12108 }
12109#ifdef CONFIG_ISA
12110 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
12111 asc_dvc->cfg->isa_dma_channel = (uchar) AscGetIsaDmaChannel(iop_base);
12112 }
12113#endif /* CONFIG_ISA */
12114 for (i = 0; i <= ASC_MAX_TID; i++) {
12115 asc_dvc->cur_dvc_qng[i] = 0;
12116 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
12117 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *) 0L;
12118 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *) 0L;
12119 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
12120 }
12121 return (warn_code);
12122}
12123
12124STATIC ushort __init
12125AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
12126{
12127 ASCEEP_CONFIG eep_config_buf;
12128 ASCEEP_CONFIG *eep_config;
12129 PortAddr iop_base;
12130 ushort chksum;
12131 ushort warn_code;
12132 ushort cfg_msw, cfg_lsw;
12133 int i;
12134 int write_eep = 0;
12135
12136 iop_base = asc_dvc->iop_base;
12137 warn_code = 0;
12138 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
12139 AscStopQueueExe(iop_base);
12140 if ((AscStopChip(iop_base) == FALSE) ||
12141 (AscGetChipScsiCtrl(iop_base) != 0)) {
12142 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
12143 AscResetChipAndScsiBus(asc_dvc);
12144 DvcSleepMilliSecond((ASC_DCNT)
12145 ((ushort) asc_dvc->scsi_reset_wait * 1000));
12146 }
12147 if (AscIsChipHalted(iop_base) == FALSE) {
12148 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
12149 return (warn_code);
12150 }
12151 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
12152 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
12153 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
12154 return (warn_code);
12155 }
12156 eep_config = (ASCEEP_CONFIG *) &eep_config_buf;
12157 cfg_msw = AscGetChipCfgMsw(iop_base);
12158 cfg_lsw = AscGetChipCfgLsw(iop_base);
12159 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12160 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
12161 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12162 AscSetChipCfgMsw(iop_base, cfg_msw);
12163 }
12164 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
12165 ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
12166 if (chksum == 0) {
12167 chksum = 0xaa55;
12168 }
12169 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12170 warn_code |= ASC_WARN_AUTO_CONFIG;
12171 if (asc_dvc->cfg->chip_version == 3) {
12172 if (eep_config->cfg_lsw != cfg_lsw) {
12173 warn_code |= ASC_WARN_EEPROM_RECOVER;
12174 eep_config->cfg_lsw = AscGetChipCfgLsw(iop_base);
12175 }
12176 if (eep_config->cfg_msw != cfg_msw) {
12177 warn_code |= ASC_WARN_EEPROM_RECOVER;
12178 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
12179 }
12180 }
12181 }
12182 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
12183 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
12184 ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
12185 eep_config->chksum);
12186 if (chksum != eep_config->chksum) {
12187 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
12188 ASC_CHIP_VER_PCI_ULTRA_3050 )
12189 {
12190 ASC_DBG(1,
12191"AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
12192 eep_config->init_sdtr = 0xFF;
12193 eep_config->disc_enable = 0xFF;
12194 eep_config->start_motor = 0xFF;
12195 eep_config->use_cmd_qng = 0;
12196 eep_config->max_total_qng = 0xF0;
12197 eep_config->max_tag_qng = 0x20;
12198 eep_config->cntl = 0xBFFF;
12199 ASC_EEP_SET_CHIP_ID(eep_config, 7);
12200 eep_config->no_scam = 0;
12201 eep_config->adapter_info[0] = 0;
12202 eep_config->adapter_info[1] = 0;
12203 eep_config->adapter_info[2] = 0;
12204 eep_config->adapter_info[3] = 0;
12205 eep_config->adapter_info[4] = 0;
12206 /* Indicate EEPROM-less board. */
12207 eep_config->adapter_info[5] = 0xBB;
12208 } else {
12209 ASC_PRINT(
12210"AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
12211 write_eep = 1;
12212 warn_code |= ASC_WARN_EEPROM_CHKSUM;
12213 }
12214 }
12215 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
12216 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
12217 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
12218 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
12219 asc_dvc->start_motor = eep_config->start_motor;
12220 asc_dvc->dvc_cntl = eep_config->cntl;
12221 asc_dvc->no_scam = eep_config->no_scam;
12222 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
12223 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
12224 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
12225 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
12226 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
12227 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
12228 if (!AscTestExternalLram(asc_dvc)) {
12229 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA)) {
12230 eep_config->max_total_qng = ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
12231 eep_config->max_tag_qng = ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
12232 } else {
12233 eep_config->cfg_msw |= 0x0800;
12234 cfg_msw |= 0x0800;
12235 AscSetChipCfgMsw(iop_base, cfg_msw);
12236 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
12237 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
12238 }
12239 } else {
12240 }
12241 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
12242 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
12243 }
12244 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
12245 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
12246 }
12247 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
12248 eep_config->max_tag_qng = eep_config->max_total_qng;
12249 }
12250 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
12251 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
12252 }
12253 asc_dvc->max_total_qng = eep_config->max_total_qng;
12254 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
12255 eep_config->use_cmd_qng) {
12256 eep_config->disc_enable = eep_config->use_cmd_qng;
12257 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12258 }
12259 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
12260 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
12261 }
12262 ASC_EEP_SET_CHIP_ID(eep_config, ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
12263 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
12264 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
12265 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
12266 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
12267 }
12268
12269 for (i = 0; i <= ASC_MAX_TID; i++) {
12270 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
12271 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
12272 asc_dvc->cfg->sdtr_period_offset[i] =
12273 (uchar) (ASC_DEF_SDTR_OFFSET |
12274 (asc_dvc->host_init_sdtr_index << 4));
12275 }
12276 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
12277 if (write_eep) {
12278 if ((i = AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type)) !=
12279 0) {
12280 ASC_PRINT1(
12281"AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n", i);
12282 } else {
d6e05edc 12283 ASC_PRINT("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
1da177e4
LT
12284 }
12285 }
12286 return (warn_code);
12287}
12288
12289STATIC ushort
12290AscInitMicroCodeVar(
12291 ASC_DVC_VAR *asc_dvc
12292)
12293{
12294 int i;
12295 ushort warn_code;
12296 PortAddr iop_base;
12297 ASC_PADDR phy_addr;
12298 ASC_DCNT phy_size;
12299
12300 iop_base = asc_dvc->iop_base;
12301 warn_code = 0;
12302 for (i = 0; i <= ASC_MAX_TID; i++) {
12303 AscPutMCodeInitSDTRAtID(iop_base, i,
12304 asc_dvc->cfg->sdtr_period_offset[i]
12305);
12306 }
12307
12308 AscInitQLinkVar(asc_dvc);
12309 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
12310 asc_dvc->cfg->disc_enable);
12311 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
12312 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
12313
12314 /* Align overrun buffer on an 8 byte boundary. */
12315 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
12316 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
12317 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
12318 (uchar *) &phy_addr, 1);
12319 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
12320 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
12321 (uchar *) &phy_size, 1);
12322
12323 asc_dvc->cfg->mcode_date =
12324 AscReadLramWord(iop_base, (ushort) ASCV_MC_DATE_W);
12325 asc_dvc->cfg->mcode_version =
12326 AscReadLramWord(iop_base, (ushort) ASCV_MC_VER_W);
12327
12328 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
12329 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
12330 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
12331 return (warn_code);
12332 }
12333 if (AscStartChip(iop_base) != 1) {
12334 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
12335 return (warn_code);
12336 }
12337
12338 return (warn_code);
12339}
12340
12341STATIC int __init
12342AscTestExternalLram(
12343 ASC_DVC_VAR *asc_dvc)
12344{
12345 PortAddr iop_base;
12346 ushort q_addr;
12347 ushort saved_word;
12348 int sta;
12349
12350 iop_base = asc_dvc->iop_base;
12351 sta = 0;
12352 q_addr = ASC_QNO_TO_QADDR(241);
12353 saved_word = AscReadLramWord(iop_base, q_addr);
12354 AscSetChipLramAddr(iop_base, q_addr);
12355 AscSetChipLramData(iop_base, 0x55AA);
12356 DvcSleepMilliSecond(10);
12357 AscSetChipLramAddr(iop_base, q_addr);
12358 if (AscGetChipLramData(iop_base) == 0x55AA) {
12359 sta = 1;
12360 AscWriteLramWord(iop_base, q_addr, saved_word);
12361 }
12362 return (sta);
12363}
12364
12365STATIC int __init
12366AscWriteEEPCmdReg(
12367 PortAddr iop_base,
12368 uchar cmd_reg
12369)
12370{
12371 uchar read_back;
12372 int retry;
12373
12374 retry = 0;
12375 while (TRUE) {
12376 AscSetChipEEPCmd(iop_base, cmd_reg);
12377 DvcSleepMilliSecond(1);
12378 read_back = AscGetChipEEPCmd(iop_base);
12379 if (read_back == cmd_reg) {
12380 return (1);
12381 }
12382 if (retry++ > ASC_EEP_MAX_RETRY) {
12383 return (0);
12384 }
12385 }
12386}
12387
12388STATIC int __init
12389AscWriteEEPDataReg(
12390 PortAddr iop_base,
12391 ushort data_reg
12392)
12393{
12394 ushort read_back;
12395 int retry;
12396
12397 retry = 0;
12398 while (TRUE) {
12399 AscSetChipEEPData(iop_base, data_reg);
12400 DvcSleepMilliSecond(1);
12401 read_back = AscGetChipEEPData(iop_base);
12402 if (read_back == data_reg) {
12403 return (1);
12404 }
12405 if (retry++ > ASC_EEP_MAX_RETRY) {
12406 return (0);
12407 }
12408 }
12409}
12410
12411STATIC void __init
12412AscWaitEEPRead(void)
12413{
12414 DvcSleepMilliSecond(1);
12415 return;
12416}
12417
12418STATIC void __init
12419AscWaitEEPWrite(void)
12420{
12421 DvcSleepMilliSecond(20);
12422 return;
12423}
12424
12425STATIC ushort __init
12426AscReadEEPWord(
12427 PortAddr iop_base,
12428 uchar addr)
12429{
12430 ushort read_wval;
12431 uchar cmd_reg;
12432
12433 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
12434 AscWaitEEPRead();
12435 cmd_reg = addr | ASC_EEP_CMD_READ;
12436 AscWriteEEPCmdReg(iop_base, cmd_reg);
12437 AscWaitEEPRead();
12438 read_wval = AscGetChipEEPData(iop_base);
12439 AscWaitEEPRead();
12440 return (read_wval);
12441}
12442
12443STATIC ushort __init
12444AscWriteEEPWord(
12445 PortAddr iop_base,
12446 uchar addr,
12447 ushort word_val)
12448{
12449 ushort read_wval;
12450
12451 read_wval = AscReadEEPWord(iop_base, addr);
12452 if (read_wval != word_val) {
12453 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
12454 AscWaitEEPRead();
12455 AscWriteEEPDataReg(iop_base, word_val);
12456 AscWaitEEPRead();
12457 AscWriteEEPCmdReg(iop_base,
12458 (uchar) ((uchar) ASC_EEP_CMD_WRITE | addr));
12459 AscWaitEEPWrite();
12460 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
12461 AscWaitEEPRead();
12462 return (AscReadEEPWord(iop_base, addr));
12463 }
12464 return (read_wval);
12465}
12466
12467STATIC ushort __init
12468AscGetEEPConfig(
12469 PortAddr iop_base,
12470 ASCEEP_CONFIG * cfg_buf, ushort bus_type)
12471{
12472 ushort wval;
12473 ushort sum;
12474 ushort *wbuf;
12475 int cfg_beg;
12476 int cfg_end;
12477 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
12478 int s_addr;
12479
12480 wbuf = (ushort *) cfg_buf;
12481 sum = 0;
12482 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
12483 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12484 *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
12485 sum += *wbuf;
12486 }
12487 if (bus_type & ASC_IS_VL) {
12488 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
12489 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
12490 } else {
12491 cfg_beg = ASC_EEP_DVC_CFG_BEG;
12492 cfg_end = ASC_EEP_MAX_DVC_ADDR;
12493 }
12494 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
12495 wval = AscReadEEPWord( iop_base, ( uchar )s_addr ) ;
12496 if (s_addr <= uchar_end_in_config) {
12497 /*
12498 * Swap all char fields - must unswap bytes already swapped
12499 * by AscReadEEPWord().
12500 */
12501 *wbuf = le16_to_cpu(wval);
12502 } else {
12503 /* Don't swap word field at the end - cntl field. */
12504 *wbuf = wval;
12505 }
12506 sum += wval; /* Checksum treats all EEPROM data as words. */
12507 }
12508 /*
12509 * Read the checksum word which will be compared against 'sum'
12510 * by the caller. Word field already swapped.
12511 */
12512 *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
12513 return (sum);
12514}
12515
12516STATIC int __init
12517AscSetEEPConfigOnce(
12518 PortAddr iop_base,
12519 ASCEEP_CONFIG * cfg_buf, ushort bus_type)
12520{
12521 int n_error;
12522 ushort *wbuf;
12523 ushort word;
12524 ushort sum;
12525 int s_addr;
12526 int cfg_beg;
12527 int cfg_end;
12528 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
12529
12530
12531 wbuf = (ushort *) cfg_buf;
12532 n_error = 0;
12533 sum = 0;
12534 /* Write two config words; AscWriteEEPWord() will swap bytes. */
12535 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12536 sum += *wbuf;
12537 if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
12538 n_error++;
12539 }
12540 }
12541 if (bus_type & ASC_IS_VL) {
12542 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
12543 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
12544 } else {
12545 cfg_beg = ASC_EEP_DVC_CFG_BEG;
12546 cfg_end = ASC_EEP_MAX_DVC_ADDR;
12547 }
12548 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
12549 if (s_addr <= uchar_end_in_config) {
12550 /*
12551 * This is a char field. Swap char fields before they are
12552 * swapped again by AscWriteEEPWord().
12553 */
12554 word = cpu_to_le16(*wbuf);
12555 if (word != AscWriteEEPWord( iop_base, (uchar) s_addr, word)) {
12556 n_error++;
12557 }
12558 } else {
12559 /* Don't swap word field at the end - cntl field. */
12560 if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
12561 n_error++;
12562 }
12563 }
12564 sum += *wbuf; /* Checksum calculated from word values. */
12565 }
12566 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
12567 *wbuf = sum;
12568 if (sum != AscWriteEEPWord(iop_base, (uchar) s_addr, sum)) {
12569 n_error++;
12570 }
12571
12572 /* Read EEPROM back again. */
12573 wbuf = (ushort *) cfg_buf;
12574 /*
12575 * Read two config words; Byte-swapping done by AscReadEEPWord().
12576 */
12577 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12578 if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
12579 n_error++;
12580 }
12581 }
12582 if (bus_type & ASC_IS_VL) {
12583 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
12584 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
12585 } else {
12586 cfg_beg = ASC_EEP_DVC_CFG_BEG;
12587 cfg_end = ASC_EEP_MAX_DVC_ADDR;
12588 }
12589 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
12590 if (s_addr <= uchar_end_in_config) {
12591 /*
12592 * Swap all char fields. Must unswap bytes already swapped
12593 * by AscReadEEPWord().
12594 */
12595 word = le16_to_cpu(AscReadEEPWord(iop_base, (uchar) s_addr));
12596 } else {
12597 /* Don't swap word field at the end - cntl field. */
12598 word = AscReadEEPWord(iop_base, (uchar) s_addr);
12599 }
12600 if (*wbuf != word) {
12601 n_error++;
12602 }
12603 }
12604 /* Read checksum; Byte swapping not needed. */
12605 if (AscReadEEPWord(iop_base, (uchar) s_addr) != sum) {
12606 n_error++;
12607 }
12608 return (n_error);
12609}
12610
12611STATIC int __init
12612AscSetEEPConfig(
12613 PortAddr iop_base,
12614 ASCEEP_CONFIG * cfg_buf, ushort bus_type
12615)
12616{
12617 int retry;
12618 int n_error;
12619
12620 retry = 0;
12621 while (TRUE) {
12622 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
12623 bus_type)) == 0) {
12624 break;
12625 }
12626 if (++retry > ASC_EEP_MAX_RETRY) {
12627 break;
12628 }
12629 }
12630 return (n_error);
12631}
12632
12633STATIC void
12634AscAsyncFix(
12635 ASC_DVC_VAR *asc_dvc,
12636 uchar tid_no,
12637 ASC_SCSI_INQUIRY *inq)
12638{
12639 uchar dvc_type;
12640 ASC_SCSI_BIT_ID_TYPE tid_bits;
12641
12642 dvc_type = ASC_INQ_DVC_TYPE(inq);
12643 tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
12644
12645 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN)
12646 {
12647 if (!(asc_dvc->init_sdtr & tid_bits))
12648 {
12649 if ((dvc_type == TYPE_ROM) &&
12650 (AscCompareString((uchar *) inq->vendor_id,
12651 (uchar *) "HP ", 3) == 0))
12652 {
12653 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
12654 }
12655 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
12656 if ((dvc_type == TYPE_PROCESSOR) ||
12657 (dvc_type == TYPE_SCANNER) ||
12658 (dvc_type == TYPE_ROM) ||
12659 (dvc_type == TYPE_TAPE))
12660 {
12661 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
12662 }
12663
12664 if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
12665 {
12666 AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no,
12667 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
12668 }
12669 }
12670 }
12671 return;
12672}
12673
12674STATIC int
12675AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
12676{
12677 if ((inq->add_len >= 32) &&
12678 (AscCompareString((uchar *) inq->vendor_id,
12679 (uchar *) "QUANTUM XP34301", 15) == 0) &&
12680 (AscCompareString((uchar *) inq->product_rev_level,
12681 (uchar *) "1071", 4) == 0))
12682 {
12683 return 0;
12684 }
12685 return 1;
12686}
12687
12688STATIC void
12689AscInquiryHandling(ASC_DVC_VAR *asc_dvc,
12690 uchar tid_no, ASC_SCSI_INQUIRY *inq)
12691{
12692 ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
12693 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
12694
12695 orig_init_sdtr = asc_dvc->init_sdtr;
12696 orig_use_tagged_qng = asc_dvc->use_tagged_qng;
12697
12698 asc_dvc->init_sdtr &= ~tid_bit;
12699 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
12700 asc_dvc->use_tagged_qng &= ~tid_bit;
12701
12702 if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) {
12703 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) {
12704 asc_dvc->init_sdtr |= tid_bit;
12705 }
12706 if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) &&
12707 ASC_INQ_CMD_QUEUE(inq)) {
12708 if (AscTagQueuingSafe(inq)) {
12709 asc_dvc->use_tagged_qng |= tid_bit;
12710 asc_dvc->cfg->can_tagged_qng |= tid_bit;
12711 }
12712 }
12713 }
12714 if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
12715 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
12716 asc_dvc->cfg->disc_enable);
12717 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
12718 asc_dvc->use_tagged_qng);
12719 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
12720 asc_dvc->cfg->can_tagged_qng);
12721
12722 asc_dvc->max_dvc_qng[tid_no] =
12723 asc_dvc->cfg->max_tag_qng[tid_no];
12724 AscWriteLramByte(asc_dvc->iop_base,
12725 (ushort) (ASCV_MAX_DVC_QNG_BEG + tid_no),
12726 asc_dvc->max_dvc_qng[tid_no]);
12727 }
12728 if (orig_init_sdtr != asc_dvc->init_sdtr) {
12729 AscAsyncFix(asc_dvc, tid_no, inq);
12730 }
12731 return;
12732}
12733
12734STATIC int
12735AscCompareString(
12736 uchar *str1,
12737 uchar *str2,
12738 int len
12739)
12740{
12741 int i;
12742 int diff;
12743
12744 for (i = 0; i < len; i++) {
12745 diff = (int) (str1[i] - str2[i]);
12746 if (diff != 0)
12747 return (diff);
12748 }
12749 return (0);
12750}
12751
12752STATIC uchar
12753AscReadLramByte(
12754 PortAddr iop_base,
12755 ushort addr
12756)
12757{
12758 uchar byte_data;
12759 ushort word_data;
12760
12761 if (isodd_word(addr)) {
12762 AscSetChipLramAddr(iop_base, addr - 1);
12763 word_data = AscGetChipLramData(iop_base);
12764 byte_data = (uchar) ((word_data >> 8) & 0xFF);
12765 } else {
12766 AscSetChipLramAddr(iop_base, addr);
12767 word_data = AscGetChipLramData(iop_base);
12768 byte_data = (uchar) (word_data & 0xFF);
12769 }
12770 return (byte_data);
12771}
12772STATIC ushort
12773AscReadLramWord(
12774 PortAddr iop_base,
12775 ushort addr
12776)
12777{
12778 ushort word_data;
12779
12780 AscSetChipLramAddr(iop_base, addr);
12781 word_data = AscGetChipLramData(iop_base);
12782 return (word_data);
12783}
12784
12785#if CC_VERY_LONG_SG_LIST
12786STATIC ASC_DCNT
12787AscReadLramDWord(
12788 PortAddr iop_base,
12789 ushort addr
12790)
12791{
12792 ushort val_low, val_high;
12793 ASC_DCNT dword_data;
12794
12795 AscSetChipLramAddr(iop_base, addr);
12796 val_low = AscGetChipLramData(iop_base);
12797 val_high = AscGetChipLramData(iop_base);
12798 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
12799 return (dword_data);
12800}
12801#endif /* CC_VERY_LONG_SG_LIST */
12802
12803STATIC void
12804AscWriteLramWord(
12805 PortAddr iop_base,
12806 ushort addr,
12807 ushort word_val
12808)
12809{
12810 AscSetChipLramAddr(iop_base, addr);
12811 AscSetChipLramData(iop_base, word_val);
12812 return;
12813}
12814
12815STATIC void
12816AscWriteLramByte(
12817 PortAddr iop_base,
12818 ushort addr,
12819 uchar byte_val
12820)
12821{
12822 ushort word_data;
12823
12824 if (isodd_word(addr)) {
12825 addr--;
12826 word_data = AscReadLramWord(iop_base, addr);
12827 word_data &= 0x00FF;
12828 word_data |= (((ushort) byte_val << 8) & 0xFF00);
12829 } else {
12830 word_data = AscReadLramWord(iop_base, addr);
12831 word_data &= 0xFF00;
12832 word_data |= ((ushort) byte_val & 0x00FF);
12833 }
12834 AscWriteLramWord(iop_base, addr, word_data);
12835 return;
12836}
12837
12838/*
12839 * Copy 2 bytes to LRAM.
12840 *
12841 * The source data is assumed to be in little-endian order in memory
12842 * and is maintained in little-endian order when written to LRAM.
12843 */
12844STATIC void
12845AscMemWordCopyPtrToLram(
12846 PortAddr iop_base,
12847 ushort s_addr,
12848 uchar *s_buffer,
12849 int words
12850)
12851{
12852 int i;
12853
12854 AscSetChipLramAddr(iop_base, s_addr);
12855 for (i = 0; i < 2 * words; i += 2) {
12856 /*
12857 * On a little-endian system the second argument below
12858 * produces a little-endian ushort which is written to
12859 * LRAM in little-endian order. On a big-endian system
12860 * the second argument produces a big-endian ushort which
12861 * is "transparently" byte-swapped by outpw() and written
12862 * in little-endian order to LRAM.
12863 */
12864 outpw(iop_base + IOP_RAM_DATA,
12865 ((ushort) s_buffer[i + 1] << 8) | s_buffer[i]);
12866 }
12867 return;
12868}
12869
12870/*
12871 * Copy 4 bytes to LRAM.
12872 *
12873 * The source data is assumed to be in little-endian order in memory
12874 * and is maintained in little-endian order when writen to LRAM.
12875 */
12876STATIC void
12877AscMemDWordCopyPtrToLram(
12878 PortAddr iop_base,
12879 ushort s_addr,
12880 uchar *s_buffer,
12881 int dwords
12882)
12883{
12884 int i;
12885
12886 AscSetChipLramAddr(iop_base, s_addr);
12887 for (i = 0; i < 4 * dwords; i += 4) {
12888 outpw(iop_base + IOP_RAM_DATA,
12889 ((ushort) s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
12890 outpw(iop_base + IOP_RAM_DATA,
12891 ((ushort) s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
12892 }
12893 return;
12894}
12895
12896/*
12897 * Copy 2 bytes from LRAM.
12898 *
12899 * The source data is assumed to be in little-endian order in LRAM
12900 * and is maintained in little-endian order when written to memory.
12901 */
12902STATIC void
12903AscMemWordCopyPtrFromLram(
12904 PortAddr iop_base,
12905 ushort s_addr,
12906 uchar *d_buffer,
12907 int words
12908)
12909{
12910 int i;
12911 ushort word;
12912
12913 AscSetChipLramAddr(iop_base, s_addr);
12914 for (i = 0; i < 2 * words; i += 2) {
12915 word = inpw(iop_base + IOP_RAM_DATA);
12916 d_buffer[i] = word & 0xff;
12917 d_buffer[i + 1] = (word >> 8) & 0xff;
12918 }
12919 return;
12920}
12921
12922STATIC ASC_DCNT
12923AscMemSumLramWord(
12924 PortAddr iop_base,
12925 ushort s_addr,
12926 int words
12927)
12928{
12929 ASC_DCNT sum;
12930 int i;
12931
12932 sum = 0L;
12933 for (i = 0; i < words; i++, s_addr += 2) {
12934 sum += AscReadLramWord(iop_base, s_addr);
12935 }
12936 return (sum);
12937}
12938
12939STATIC void
12940AscMemWordSetLram(
12941 PortAddr iop_base,
12942 ushort s_addr,
12943 ushort set_wval,
12944 int words
12945)
12946{
12947 int i;
12948
12949 AscSetChipLramAddr(iop_base, s_addr);
12950 for (i = 0; i < words; i++) {
12951 AscSetChipLramData(iop_base, set_wval);
12952 }
12953 return;
12954}
12955
12956
12957/*
12958 * --- Adv Library Functions
12959 */
12960
12961/* a_mcode.h */
12962
12963/* Microcode buffer is kept after initialization for error recovery. */
12964STATIC unsigned char _adv_asc3550_buf[] = {
12965 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc, 0x01, 0x00, 0x48, 0xe4,
12966 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7,
12967 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6,
12968 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00, 0x00, 0xec, 0x85, 0xf0,
12969 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00,
12970 0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80,
12971 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea,
12972 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00,
12973 0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54,
12974 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00, 0x3e, 0x00, 0x80, 0x00,
12975 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01,
12976 0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55,
12977 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
12978 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15,
12979 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0,
12980 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01,
12981 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c,
12982 0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0,
12983 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00,
12984 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10,
12985 0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15,
12986 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45,
12987 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6,
12988 0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa,
12989 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00, 0x9e, 0x00, 0xa8, 0x00,
12990 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01,
12991 0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08,
12992 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x06, 0x12,
12993 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17,
12994 0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47,
12995 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55, 0x14, 0x56, 0x77, 0x57,
12996 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe,
12997 0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff,
12998 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, 0x00, 0xfe, 0x57, 0x24,
12999 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08,
13000 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f,
13001 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xcf,
13002 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe,
13003 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe,
13004 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b, 0x02, 0xfe, 0xd4, 0x0c,
13005 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6,
13006 0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02,
13007 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02, 0xfe, 0x46, 0xf0, 0xfe,
13008 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44,
13009 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18,
13010 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9,
13011 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e,
13012 0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd,
13013 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, 0x1c, 0x17, 0x06,
13014 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe,
13015 0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f,
13016 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe, 0x69, 0x10, 0x17, 0x06,
13017 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe,
13018 0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40,
13019 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0x99, 0x01,
13020 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02,
13021 0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b,
13022 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0, 0xfe, 0x56, 0x03, 0xfe,
13023 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe,
13024 0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04,
13025 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40, 0x01, 0x0e, 0xac, 0x75,
13026 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe,
13027 0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4,
13028 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe, 0x0a, 0xf0, 0xfe, 0x7a,
13029 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe,
13030 0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c,
13031 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3, 0x0a, 0xca, 0x01, 0x0e,
13032 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f,
13033 0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f,
13034 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2b, 0xff, 0x02,
13035 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5,
13036 0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
13037 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d, 0xfe, 0x2a, 0x13, 0x2f,
13038 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86,
13039 0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12,
13040 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22,
13041 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29,
13042 0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4,
13043 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a, 0xfe, 0x70, 0x12, 0x49,
13044 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31,
13045 0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12,
13046 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05, 0x11, 0xfe, 0xe3, 0x00,
13047 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24,
13048 0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08,
13049 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01, 0x86, 0x24, 0x06, 0x12,
13050 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92,
13051 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe,
13052 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13, 0x47, 0x01, 0xa7, 0x26,
13053 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14,
13054 0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c,
13055 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x14,
13056 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57,
13057 0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04,
13058 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68, 0x06, 0x11, 0x9a, 0x01,
13059 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72,
13060 0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe,
13061 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07, 0x8d, 0x81, 0x02, 0x22,
13062 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00,
13063 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32,
13064 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15, 0xfe, 0x1b, 0x00, 0x01,
13065 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01,
13066 0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d,
13067 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12,
13068 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d,
13069 0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02,
13070 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x77, 0xfe, 0xca,
13071 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12,
13072 0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1,
13073 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f, 0x40, 0x12, 0x58, 0x01,
13074 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe,
13075 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe,
13076 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a, 0xfe, 0x2a, 0x12, 0xfe,
13077 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe,
13078 0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe,
13079 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x39, 0x18, 0x3a,
13080 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48,
13081 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80,
13082 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x7a, 0x08, 0x8d,
13083 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06,
13084 0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c,
13085 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe, 0x52, 0x12, 0xfe, 0x2c,
13086 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10,
13087 0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe,
13088 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xb5, 0xfe,
13089 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d,
13090 0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33,
13091 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a, 0xfe, 0x74, 0x18, 0x1c,
13092 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27,
13093 0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe,
13094 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc, 0xfe, 0x83, 0x80, 0xfe,
13095 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59,
13096 0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf,
13097 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e, 0x79, 0x56, 0x68, 0x57,
13098 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b,
13099 0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39,
13100 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x10, 0x58, 0xfe,
13101 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09,
13102 0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe,
13103 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08, 0x11, 0x9b, 0x09, 0x04,
13104 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe,
13105 0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12,
13106 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9, 0x14, 0x7a, 0x01, 0x33,
13107 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf,
13108 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10,
13109 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x84, 0x05, 0xcb, 0x1c,
13110 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a,
13111 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca,
13112 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe, 0x22, 0x00, 0x02, 0x5a,
13113 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe,
13114 0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10,
13115 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00, 0x2a, 0x13, 0xfe, 0x4e,
13116 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73,
13117 0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48,
13118 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xdb, 0x10, 0x11, 0xfe,
13119 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8,
13120 0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42,
13121 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c, 0x09, 0x04, 0x0b, 0xfe,
13122 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6,
13123 0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01,
13124 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x02, 0x29,
13125 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b,
13126 0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe,
13127 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01, 0xe8, 0x59, 0x11, 0x2d,
13128 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e,
13129 0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe,
13130 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d,
13131 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe,
13132 0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00,
13133 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa, 0xab, 0x70, 0x05, 0x6b,
13134 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01,
13135 0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01,
13136 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e, 0x1d, 0xfe, 0xce, 0x45,
13137 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe,
13138 0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d,
13139 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe,
13140 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee,
13141 0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e,
13142 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12, 0xce, 0x1e, 0x2d, 0x47,
13143 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe,
13144 0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02,
13145 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
13146 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea,
13147 0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01,
13148 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01,
13149 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e,
13150 0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24,
13151 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57,
13152 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe,
13153 0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04,
13154 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xe1,
13155 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c,
13156 0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d,
13157 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01, 0xe8, 0x11, 0xfe, 0xe9,
13158 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14,
13159 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe,
13160 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80, 0x40, 0x12, 0x20, 0x63,
13161 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac,
13162 0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe,
13163 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x24, 0x69, 0x12, 0xc9,
13164 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91,
13165 0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe,
13166 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c, 0x46, 0x1e, 0x20, 0xed,
13167 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c,
13168 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d,
13169 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46, 0xfa, 0xef, 0xfe, 0x42,
13170 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0,
13171 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10,
13172 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e, 0x10, 0x07, 0x7e, 0x45,
13173 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97,
13174 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe,
13175 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b, 0xfe, 0x48, 0x12, 0x07,
13176 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07,
13177 0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe,
13178 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b, 0x01, 0x08, 0x8c, 0x43,
13179 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b,
13180 0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04,
13181 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe, 0xc6, 0x10, 0x1e, 0x58,
13182 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23,
13183 0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1,
13184 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0xfe,
13185 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57,
13186 0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
13187 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e, 0x58, 0xfe, 0x1f, 0x40,
13188 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44,
13189 0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39,
13190 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06, 0x12, 0xcd, 0x02, 0x5b,
13191 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21,
13192 0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe,
13193 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51,
13194 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32,
13195 0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01,
13196 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44, 0x01, 0x08, 0x1f, 0xa2,
13197 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49,
13198 0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda,
13199 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1, 0x05, 0xc6, 0x28, 0x84,
13200 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
13201 0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02,
13202 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06, 0x21, 0x44, 0x01, 0xfe,
13203 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b,
13204 0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05,
13205 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xd8, 0x14, 0x02, 0x5c,
13206 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72,
13207 0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01,
13208 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0xfe, 0xff, 0x7f,
13209 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c,
13210 0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
13211 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58, 0x03, 0x0a, 0x50, 0x01,
13212 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4,
13213 0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27,
13214 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe,
13215 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60,
13216 0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14,
13217 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe, 0xcc, 0x12, 0x49, 0x04,
13218 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13,
13219 0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83,
13220 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c, 0x13, 0x06, 0xfe, 0x56,
13221 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93,
13222 0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4,
13223 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90, 0x01, 0xba, 0xfe, 0x4e,
13224 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe,
13225 0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c,
13226 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba, 0xfe, 0x9c, 0x14, 0xb7,
13227 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7,
13228 0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe,
13229 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x0b, 0x01,
13230 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03,
13231 0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08,
13232 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89, 0x4a, 0x01, 0x08, 0x03,
13233 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00,
13234 0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe,
13235 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd, 0x01, 0x43, 0x1e, 0xcd,
13236 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10,
13237 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88,
13238 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3, 0x88, 0x03, 0x0a, 0x42,
13239 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2,
13240 0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17,
13241 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe,
13242 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe,
13243 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10,
13244 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58, 0x05, 0xfe, 0x66, 0x01,
13245 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66,
13246 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6,
13247 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17, 0x10, 0x71, 0xfe, 0x83,
13248 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe,
13249 0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
13250 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71, 0xfe, 0x30, 0xbc, 0xfe,
13251 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a,
13252 0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02,
13253 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc, 0xfe, 0x1d, 0xf7, 0x4f,
13254 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58,
13255 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63,
13256 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14, 0x06, 0x37, 0x95, 0xa9,
13257 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d,
13258 0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c,
13259 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x3c, 0x8a, 0x0a,
13260 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc,
13261 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f,
13262 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xf6, 0xfe, 0xd6, 0xf0,
13263 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76,
13264 0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f,
13265 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68, 0xc8, 0xfe, 0x48, 0x55,
13266 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0,
13267 0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42,
13268 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01, 0x0e, 0x73, 0x75, 0x03,
13269 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b,
13270 0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b,
13271 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05, 0xfe, 0x94, 0x00, 0xfe,
13272 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e,
13273 0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe,
13274 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1b, 0xfe, 0x5a,
13275 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07,
13276 0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14,
13277 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9, 0x03, 0x25, 0xfe, 0xca,
13278 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00,
13279};
13280
13281STATIC unsigned short _adv_asc3550_size =
13282 sizeof(_adv_asc3550_buf); /* 0x13AD */
13283STATIC ADV_DCNT _adv_asc3550_chksum =
13284 0x04D52DDDUL; /* Expanded little-endian checksum. */
13285
13286/* Microcode buffer is kept after initialization for error recovery. */
13287STATIC unsigned char _adv_asc38C0800_buf[] = {
13288 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4, 0x01, 0x00, 0x48, 0xe4,
13289 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6,
13290 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0,
13291 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0, 0x18, 0xf4, 0x08, 0x00,
13292 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0,
13293 0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00,
13294 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13, 0xba, 0x13, 0x18, 0x40,
13295 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01,
13296 0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
13297 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12, 0x08, 0x12, 0x02, 0x4a,
13298 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa,
13299 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
13300 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d, 0x06, 0x13, 0x4c, 0x1c,
13301 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00,
13302 0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44,
13303 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa, 0x05, 0x00, 0x34, 0x00,
13304 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f,
13305 0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54,
13306 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0,
13307 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00,
13308 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03,
13309 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13, 0x12, 0x13, 0x24, 0x14,
13310 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44,
13311 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55,
13312 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0, 0x04, 0xf8,
13313 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00,
13314 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01,
13315 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08, 0x68, 0x08, 0x69, 0x08,
13316 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10,
13317 0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14,
13318 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18, 0xca, 0x18, 0xe6, 0x19,
13319 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe,
13320 0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff,
13321 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, 0x00, 0xfe, 0x57, 0x24,
13322 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08,
13323 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11,
13324 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xd6,
13325 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe,
13326 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe,
13327 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d, 0x02, 0xfe, 0xc8, 0x0d,
13328 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6,
13329 0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02,
13330 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02, 0xfe, 0x46, 0xf0, 0xfe,
13331 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44,
13332 0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14,
13333 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9,
13334 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8,
13335 0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd,
13336 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, 0x1c, 0x18, 0x06,
13337 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe,
13338 0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10,
13339 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe, 0x69, 0x10, 0x18, 0x06,
13340 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe,
13341 0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
13342 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x09,
13343 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
13344 0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe,
13345 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x40, 0x1c, 0x1c,
13346 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0,
13347 0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02,
13348 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13, 0x21, 0x22, 0xa3, 0xb7,
13349 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9,
13350 0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27,
13351 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe, 0x06, 0xf0, 0xfe, 0xc8,
13352 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe,
13353 0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19,
13354 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x74, 0x01, 0xaf, 0x8c,
13355 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79,
13356 0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02,
13357 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d, 0xfe, 0x3c, 0x04, 0x3b,
13358 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b,
13359 0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe,
13360 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0x4f, 0x79, 0x2a,
13361 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32,
13362 0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe,
13363 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x08, 0x13, 0x32, 0x07,
13364 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d,
13365 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6,
13366 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36, 0x02, 0x2b, 0xfe, 0x42,
13367 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe,
13368 0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c,
13369 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28, 0x17, 0xfe, 0x90, 0x05,
13370 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe,
13371 0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48,
13372 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0x12, 0xfe, 0xe3, 0x00,
13373 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25,
13374 0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02,
13375 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2, 0x08, 0x53, 0x05, 0xcb,
13376 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22,
13377 0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36,
13378 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb, 0x03, 0x5c, 0x28, 0xfe,
13379 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02,
13380 0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe,
13381 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62, 0x12, 0x03, 0x45, 0x28,
13382 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc,
13383 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2,
13384 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01, 0xfe, 0xcc, 0x15, 0x1d,
13385 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45,
13386 0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb,
13387 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07, 0xfe, 0x06, 0xf0, 0xfe,
13388 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b,
13389 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01,
13390 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38, 0x12, 0x08, 0x05, 0x1a,
13391 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
13392 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe,
13393 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b, 0xfe, 0x09, 0x6f, 0xba,
13394 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c,
13395 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01,
13396 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
13397 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07,
13398 0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe,
13399 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b, 0x37, 0x01, 0xb3, 0xb8,
13400 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51,
13401 0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c,
13402 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d, 0x14, 0x3e, 0xfe, 0x4a,
13403 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14,
13404 0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe,
13405 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f,
13406 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c,
13407 0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e,
13408 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe, 0x9a, 0x08, 0xc6, 0xfe,
13409 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24,
13410 0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12,
13411 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e, 0x1c, 0x02, 0xfe, 0x18,
13412 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa,
13413 0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7,
13414 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18, 0xfe, 0xf1, 0x18, 0xfe,
13415 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95,
13416 0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5,
13417 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18, 0x0b, 0xb6, 0xfe, 0xbf,
13418 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2,
13419 0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5,
13420 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15, 0x9d, 0x01, 0x36, 0x10,
13421 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19,
13422 0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe,
13423 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0x08, 0x05,
13424 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c,
13425 0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49,
13426 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18, 0x8f, 0xfe, 0xe3, 0x54,
13427 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b,
13428 0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b,
13429 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00, 0xad, 0xfe, 0x01, 0x59,
13430 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3,
13431 0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b,
13432 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63, 0x02, 0x4a, 0x08, 0x05,
13433 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1,
13434 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a,
13435 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29, 0x61, 0x0c, 0x7f, 0x14,
13436 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c,
13437 0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef,
13438 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40, 0xe4, 0x08, 0x05, 0x1f,
13439 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f,
13440 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05,
13441 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19, 0x81, 0x50, 0xfe, 0x10,
13442 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6,
13443 0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c,
13444 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7, 0x08, 0x05, 0x0a, 0xfe,
13445 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e,
13446 0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed,
13447 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe, 0x00, 0xff, 0x35, 0xfe,
13448 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03,
13449 0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe,
13450 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0,
13451 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00,
13452 0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0,
13453 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea, 0x0b, 0x10, 0x58, 0xfe,
13454 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f,
13455 0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34,
13456 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20, 0x0c, 0x1c, 0x34, 0x94,
13457 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10,
13458 0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33,
13459 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24, 0x33, 0x31, 0xdf, 0xbc,
13460 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d,
13461 0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28,
13462 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x44, 0xfe, 0x28, 0x00,
13463 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f,
13464 0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10,
13465 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xac,
13466 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01,
13467 0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08,
13468 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05, 0x1a, 0xfe, 0x58, 0x12,
13469 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe,
13470 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10,
13471 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10, 0xfe, 0x13, 0x00, 0xfe,
13472 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5,
13473 0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe,
13474 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0, 0xb4, 0x15, 0xfe, 0x31,
13475 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44,
13476 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75,
13477 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x44, 0x48,
13478 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09,
13479 0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d,
13480 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0xce, 0x47, 0xfe, 0xad,
13481 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13,
13482 0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06,
13483 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe, 0x3a, 0x01, 0x56, 0xfe,
13484 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05,
13485 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe,
13486 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13, 0x15, 0x1a, 0x39, 0xa0,
13487 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01,
13488 0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12,
13489 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12, 0x22, 0x9f, 0xb7, 0x13,
13490 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9,
13491 0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc,
13492 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21, 0xfe, 0x00, 0xcc, 0x04,
13493 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07,
13494 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe,
13495 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x0a, 0xfe, 0x3c, 0x50,
13496 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b,
13497 0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01,
13498 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01,
13499 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01,
13500 0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79,
13501 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00,
13502
13503 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09,
13504 0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52,
13505 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc, 0x0f, 0x44, 0x11, 0x0f,
13506 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20,
13507 0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
13508 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x04, 0x42,
13509 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01,
13510 0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f,
13511 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45,
13512 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09,
13513 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14,
13514 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d, 0xfe, 0x01, 0xec, 0xa2,
13515 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe,
13516 0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07,
13517 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17, 0xfe, 0x32, 0x12, 0x07,
13518 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12,
13519 0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d,
13520 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d, 0x32, 0x07, 0xa6, 0xfe,
13521 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12,
13522 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03,
13523 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21, 0x0c, 0x7f, 0x0c, 0x80,
13524 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55,
13525 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f,
13526 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40, 0x88, 0x9b, 0x2e, 0x9c,
13527 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14,
13528 0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61,
13529 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50,
13530 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40,
13531 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d,
13532 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23, 0x72, 0x01, 0xaf, 0x1e,
13533 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe,
13534 0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19,
13535 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31,
13536 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d,
13537 0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8,
13538 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53, 0x05, 0x1f, 0x35, 0xa9,
13539 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c,
13540 0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35,
13541 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x03, 0x5c, 0xc1, 0x0c,
13542 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c,
13543 0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1,
13544 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a, 0xf4, 0x06, 0xea, 0x32,
13545 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89,
13546 0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13,
13547 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0, 0x13, 0x1c, 0xfe, 0xd0,
13548 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02,
13549 0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f,
13550 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04,
13551 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52,
13552 0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03,
13553 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52, 0xfe, 0x00, 0x7d, 0xfe,
13554 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f,
13555 0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01,
13556 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33,
13557 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59,
13558 0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee,
13559 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c, 0x30, 0xfe, 0x78, 0x10,
13560 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00,
13561 0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00,
13562 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28, 0x10, 0x69, 0x06, 0xfe,
13563 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06,
13564 0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe,
13565 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4, 0x9e, 0xfe, 0xf3, 0x10,
13566 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
13567 0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
13568 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d, 0xf4, 0x00, 0xe9, 0x91,
13569 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01,
13570 0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76,
13571 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x19, 0x01, 0x0b,
13572 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76,
13573 0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8,
13574 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01,
13575 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00,
13576 0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06,
13577 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e, 0x07, 0x11, 0xae, 0x09,
13578 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80,
13579 0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e,
13580 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x4c,
13581 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87,
13582 0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24,
13583 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4, 0x17, 0xad, 0x9a, 0x1b,
13584 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10,
13585 0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe,
13586 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c,
13587 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17,
13588 0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75,
13589 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x2e, 0x97, 0xfe, 0x5a,
13590 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
13591 0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe,
13592 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0xcb, 0x97, 0xfe, 0x92,
13593 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02,
13594 0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d,
13595 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x9a, 0x5b, 0x41, 0xfe,
13596 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd,
13597 0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39,
13598 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04, 0xfe, 0x7e, 0x18, 0x1e,
13599 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10,
13600 0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09,
13601 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc,
13602 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c,
13603 0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14,
13604 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c, 0xe7, 0x0a, 0x10, 0xfe,
13605 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37,
13606 0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b,
13607 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77, 0x13, 0xa3, 0x04, 0x09,
13608 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8,
13609 0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09,
13610 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe, 0x1c, 0x19, 0x03, 0xfe,
13611 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19,
13612 0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b,
13613 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe, 0x08, 0x10, 0x03, 0xfe,
13614 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7,
13615 0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00,
13616 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19, 0x04, 0x07, 0x7e, 0xfe,
13617 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a,
13618 0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07,
13619 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59, 0xa9, 0xb8, 0x04, 0x15,
13620 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c,
13621 0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0,
13622 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
13623};
13624
13625STATIC unsigned short _adv_asc38C0800_size =
13626 sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
13627STATIC ADV_DCNT _adv_asc38C0800_chksum =
13628 0x050D3FD8UL; /* Expanded little-endian checksum. */
13629
13630/* Microcode buffer is kept after initialization for error recovery. */
13631STATIC unsigned char _adv_asc38C1600_buf[] = {
13632 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0, 0x18, 0xe4, 0x01, 0x00,
13633 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f,
13634 0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0,
13635 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00, 0x98, 0x57, 0x01, 0xe6,
13636 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0,
13637 0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0,
13638 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01, 0x06, 0x13, 0x0c, 0x1c,
13639 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80,
13640 0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea,
13641 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x04, 0x13, 0xbb, 0x55,
13642 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00,
13643 0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c,
13644 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01,
13645 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01,
13646 0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48,
13647 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x06, 0x00,
13648 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c,
13649 0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0,
13650 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00,
13651 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09,
13652 0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16,
13653 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
13654 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00,
13655 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c,
13656 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x42, 0x1d, 0x08, 0x44,
13657 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59,
13658 0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8,
13659 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0xa8, 0x00, 0xaa, 0x00,
13660 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01,
13661 0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d,
13662 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10, 0xf3, 0x10, 0x06, 0x12,
13663 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe,
13664 0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff,
13665 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, 0x00, 0xfe, 0x57, 0x24,
13666 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08,
13667 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13,
13668 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xe8,
13669 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe,
13670 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe,
13671 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d, 0x05, 0xfe, 0x08, 0x0f,
13672 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe,
13673 0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90,
13674 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8, 0x02, 0xfe, 0x46, 0xf0,
13675 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe,
13676 0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07,
13677 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02, 0x1c, 0xf5, 0xfe, 0x1e,
13678 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01,
13679 0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe,
13680 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, 0x1c, 0x1c,
13681 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02,
13682 0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01,
13683 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09, 0x1a, 0x31, 0xfe, 0x69,
13684 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c,
13685 0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51,
13686 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00,
13687 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54,
13688 0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30,
13689 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0, 0xfe, 0xe4, 0x01, 0xfe,
13690 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66,
13691 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f,
13692 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05, 0x70, 0x37, 0xfe, 0x48,
13693 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20,
13694 0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe,
13695 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32, 0x15, 0xfe, 0xe4, 0x00,
13696 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe,
13697 0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b,
13698 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xfe, 0x46, 0x1c,
13699 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75,
13700 0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77,
13701 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02,
13702 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04,
13703 0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01,
13704 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25, 0xee, 0xfe, 0x4c, 0x44,
13705 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d,
13706 0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe,
13707 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10, 0x13, 0x34, 0xfe, 0x4c,
13708 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06,
13709 0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f,
13710 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f, 0xfe, 0xa4, 0x0e, 0x05,
13711 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b,
13712 0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46,
13713 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04, 0xfe, 0x87, 0x83, 0xfe,
13714 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20,
13715 0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06,
13716 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda, 0x05, 0xd0, 0x54, 0x01,
13717 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff,
13718 0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe,
13719 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01, 0x38, 0xfe, 0x4a, 0xf0,
13720 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e,
13721 0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0,
13722 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe, 0x1c, 0x00, 0x4d, 0x01,
13723 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12,
13724 0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42,
13725 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13, 0x03, 0xb6, 0x1e, 0xfe,
13726 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a,
13727 0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68,
13728 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x03, 0x9a, 0x1e, 0xfe,
13729 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06,
13730 0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00,
13731 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17, 0xfe, 0xea, 0x06, 0x01,
13732 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15,
13733 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae,
13734 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a, 0x1e, 0xfe, 0x1a, 0x12,
13735 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80,
13736 0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6,
13737 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x17, 0xfe,
13738 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01,
13739 0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05,
13740 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0x9c, 0x32, 0x5f,
13741 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe,
13742 0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29,
13743 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14,
13744 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe,
13745 0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13,
13746 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
13747 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe,
13748 0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c,
13749 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x53, 0x63, 0x4e,
13750 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0,
13751 0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c,
13752 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe, 0x1e, 0xfe, 0x99, 0x58,
13753 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c,
13754 0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a,
13755 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40, 0x01, 0x0c, 0x61, 0x65,
13756 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50,
13757 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e,
13758 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e, 0x01, 0xfe, 0xfe, 0x1e,
13759 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06,
13760 0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b,
13761 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04, 0xfe, 0x9f, 0x83, 0x33,
13762 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6,
13763 0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e,
13764 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90, 0x04, 0xfe, 0xc0, 0x93,
13765 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c,
13766 0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
13767 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
13768 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a,
13769 0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41,
13770 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07, 0xfe, 0x14, 0x12, 0x01,
13771 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe,
13772 0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe,
13773 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe, 0x92, 0x10, 0xc4, 0xf6,
13774 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b,
13775 0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0,
13776 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07, 0x1b, 0xbf, 0xd4, 0x5b,
13777 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f,
13778 0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74,
13779 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78, 0x0f, 0x4d, 0x01, 0xfe,
13780 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2,
13781 0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21,
13782 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe, 0x83, 0x83, 0xfe, 0xc9,
13783 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84,
13784 0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b,
13785 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0x10,
13786 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64,
13787 0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64,
13788 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97, 0x10, 0x98, 0x91, 0x6c,
13789 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01,
13790 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58,
13791 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x01, 0x0c,
13792 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04,
13793 0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe,
13794 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb, 0x01, 0x0c, 0x06, 0x0d,
13795 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d,
13796 0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e,
13797 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41,
13798 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00,
13799 0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51,
13800 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe, 0x76, 0x10, 0xac, 0xfe,
13801 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe,
13802 0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92,
13803 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2, 0x0c, 0xfe, 0x3e, 0x10,
13804 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe,
13805 0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94,
13806 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3, 0xfe, 0xcc, 0xf0, 0xef,
13807 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
13808 0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
13809 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32, 0x2f, 0xfe, 0x3e, 0x0d,
13810 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f,
13811 0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99,
13812 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8, 0x9c, 0x2f, 0xfe, 0x8c,
13813 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70,
13814 0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13,
13815 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b, 0xfe, 0xda, 0x0e, 0x0a,
13816 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4,
13817 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85,
13818 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe, 0xcc, 0x10, 0x01, 0xa7,
13819 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe,
13820 0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2,
13821 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x40, 0x15,
13822 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01,
13823 0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe,
13824 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe,
13825 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44,
13826 0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19,
13827 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19, 0xfe, 0x41, 0x00, 0xa2,
13828 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04,
13829 0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c,
13830 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01, 0xfe, 0xd4, 0x11, 0x05,
13831 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51,
13832 0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56,
13833 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01, 0x0c, 0x06, 0x28, 0xfe,
13834 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe,
13835 0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe,
13836 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x05,
13837 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c,
13838 0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b,
13839 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe, 0xf0, 0x1a, 0x03, 0xfe,
13840 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00,
13841 0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b,
13842 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02, 0xea, 0xe7, 0x53, 0x92,
13843 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23,
13844 0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e,
13845 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02, 0x26, 0x02, 0x21, 0x96,
13846 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10,
13847 0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe,
13848 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe, 0x00, 0xcc, 0x02, 0xfe,
13849 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80,
13850 0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80,
13851 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe, 0x1d, 0x80, 0x04, 0xfe,
13852 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14,
13853 0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4,
13854 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09, 0x56, 0xfb, 0x01, 0xfe,
13855 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15,
13856 0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e,
13857 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe, 0x96, 0x90, 0x04, 0xfe,
13858 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06,
13859 0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01,
13860 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40, 0x21, 0x2c, 0xfe, 0x00,
13861 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe,
13862 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00,
13863 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10, 0x66, 0x10, 0x55, 0x10,
13864 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88,
13865 0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe,
13866 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c,
13867 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe,
13868 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47,
13869 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01, 0xa7, 0x90, 0x34, 0x60,
13870 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34,
13871 0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
13872 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a,
13873 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe,
13874 0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e,
13875 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01, 0xf4, 0xfe, 0xdd, 0x10,
13876 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe,
13877 0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23,
13878 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09, 0x24, 0xfe, 0x12, 0x12,
13879 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32,
13880 0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43,
13881 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80, 0x13, 0x01, 0x0c, 0x06,
13882 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe,
13883 0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10,
13884 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49, 0x88, 0x20, 0x6e, 0x01,
13885 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa,
13886 0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe,
13887 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe, 0xe5,
13888 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01,
13889 0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50,
13890 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50, 0x03, 0x68, 0x3b,
13891 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2,
13892 0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25,
13893 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01, 0xa6, 0x23, 0x3f, 0x1b,
13894 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31,
13895 0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01,
13896 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0,
13897 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05,
13898 0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08,
13899 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03, 0xb6, 0x1e, 0x83, 0x01,
13900 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01,
13901 0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82,
13902 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e, 0x05, 0x72, 0xfe, 0xc0,
13903 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17,
13904 0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd,
13905 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe, 0xe8, 0x14, 0x01, 0xa6,
13906 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43,
13907 0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73,
13908 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd, 0x09,
13909 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8,
13910 0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72,
13911 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0xc0, 0x19, 0x05,
13912 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26,
13913 0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32,
13914 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0xfe, 0xff,
13915 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad,
13916 0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
13917 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e, 0x02, 0x13, 0x58, 0xff,
13918 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01,
13919 0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54,
13920 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07, 0x7c, 0x3a, 0x0b, 0x0e,
13921 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00,
13922 0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe,
13923 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77, 0x02, 0x01, 0xc6, 0xfe,
13924 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08,
13925 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe,
13926 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12, 0x48, 0xfe, 0x08, 0x17,
13927 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07,
13928 0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55,
13929 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x1c, 0x63, 0x13,
13930 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80,
13931 0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60,
13932 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8, 0x00, 0x1c, 0x95, 0x13,
13933 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96,
13934 0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b,
13935 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x49,
13936 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe,
13937 0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13,
13938 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xbe, 0xfe, 0x03,
13939 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16,
13940 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9,
13941 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27,
13942 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24,
13943 0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e,
13944 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10, 0xfe, 0x40, 0x5a, 0x23,
13945 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa,
13946 0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
13947 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe, 0x43, 0x48, 0x2d, 0x93,
13948 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4,
13949 0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0,
13950 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa, 0x18, 0x45, 0xfe, 0x1c,
13951 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4,
13952 0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01,
13953 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe, 0x7e, 0x01, 0xfe, 0xc8,
13954 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01,
13955 0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14,
13956 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14,
13957 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07,
13958 0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
13959 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01, 0x08, 0x02, 0x50, 0x02,
13960 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08,
13961 0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe,
13962 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17, 0x74, 0x5f, 0xcc, 0x01,
13963 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00,
13964 0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f,
13965 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13, 0x16, 0xfe, 0x64, 0x1a,
13966 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02,
13967 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01,
13968 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa, 0xfe, 0x80, 0xe7, 0x1a,
13969 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18,
13970 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80,
13971 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x0a,
13972 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
13973 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3,
13974 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe, 0xf4, 0x1a, 0xfe, 0xfa,
13975 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03,
13976 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07,
13977 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x24, 0xb1, 0xfe,
13978 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c,
13979 0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1,
13980 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe, 0xaf, 0x19, 0xfe, 0x98,
13981 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f,
13982 0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04,
13983 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a, 0x7c, 0x12, 0xfe, 0x0f,
13984 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b,
13985 0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe,
13986 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee, 0x1b, 0xfe, 0x36, 0x14,
13987 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a,
13988 0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45,
13989 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe, 0x39, 0xf0, 0x75, 0x26,
13990 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe,
13991 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13,
13992 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe,
13993 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb,
13994 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01,
13995 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14, 0x56,
13996 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15,
13997 0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80,
13998 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90,
13999 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20,
14000 0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44,
14001 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09, 0x1a, 0xa4, 0x0a, 0x67,
14002 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52,
14003 0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b,
14004 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10, 0xfe, 0x4e, 0xe4, 0xfe,
14005 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03,
14006 0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1,
14007 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe,
14008 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a,
14009 0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8,
14010 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe, 0x1a, 0x10, 0x09, 0x0d,
14011 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42,
14012 0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08,
14013 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e, 0xfe, 0x82, 0xf0, 0xfe,
14014 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18,
14015 0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82,
14016 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86, 0x83, 0x33, 0x0b, 0x0e,
14017 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04,
14018 0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80,
14019 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04, 0xfe, 0x99, 0x83, 0xfe,
14020 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47,
14021 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
14022 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x08, 0x90, 0x04,
14023 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79,
14024 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
14025 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x3c, 0x90, 0x04,
14026 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83,
14027 0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
14028};
14029
14030STATIC unsigned short _adv_asc38C1600_size =
14031 sizeof(_adv_asc38C1600_buf); /* 0x1673 */
14032STATIC ADV_DCNT _adv_asc38C1600_chksum =
14033 0x0604EF77UL; /* Expanded little-endian checksum. */
14034
14035/* a_init.c */
14036/*
14037 * EEPROM Configuration.
14038 *
14039 * All drivers should use this structure to set the default EEPROM
14040 * configuration. The BIOS now uses this structure when it is built.
14041 * Additional structure information can be found in a_condor.h where
14042 * the structure is defined.
14043 *
14044 * The *_Field_IsChar structs are needed to correct for endianness.
14045 * These values are read from the board 16 bits at a time directly
14046 * into the structs. Because some fields are char, the values will be
14047 * in the wrong order. The *_Field_IsChar tells when to flip the
14048 * bytes. Data read and written to PCI memory is automatically swapped
14049 * on big-endian platforms so char fields read as words are actually being
14050 * unswapped on big-endian platforms.
14051 */
14052STATIC ADVEEP_3550_CONFIG
14053Default_3550_EEPROM_Config __initdata = {
14054 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
14055 0x0000, /* cfg_msw */
14056 0xFFFF, /* disc_enable */
14057 0xFFFF, /* wdtr_able */
14058 0xFFFF, /* sdtr_able */
14059 0xFFFF, /* start_motor */
14060 0xFFFF, /* tagqng_able */
14061 0xFFFF, /* bios_scan */
14062 0, /* scam_tolerant */
14063 7, /* adapter_scsi_id */
14064 0, /* bios_boot_delay */
14065 3, /* scsi_reset_delay */
14066 0, /* bios_id_lun */
14067 0, /* termination */
14068 0, /* reserved1 */
14069 0xFFE7, /* bios_ctrl */
14070 0xFFFF, /* ultra_able */
14071 0, /* reserved2 */
14072 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
14073 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
14074 0, /* dvc_cntl */
14075 0, /* bug_fix */
14076 0, /* serial_number_word1 */
14077 0, /* serial_number_word2 */
14078 0, /* serial_number_word3 */
14079 0, /* check_sum */
14080 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* oem_name[16] */
14081 0, /* dvc_err_code */
14082 0, /* adv_err_code */
14083 0, /* adv_err_addr */
14084 0, /* saved_dvc_err_code */
14085 0, /* saved_adv_err_code */
14086 0, /* saved_adv_err_addr */
14087 0 /* num_of_err */
14088};
14089
14090STATIC ADVEEP_3550_CONFIG
14091ADVEEP_3550_Config_Field_IsChar __initdata = {
14092 0, /* cfg_lsw */
14093 0, /* cfg_msw */
14094 0, /* -disc_enable */
14095 0, /* wdtr_able */
14096 0, /* sdtr_able */
14097 0, /* start_motor */
14098 0, /* tagqng_able */
14099 0, /* bios_scan */
14100 0, /* scam_tolerant */
14101 1, /* adapter_scsi_id */
14102 1, /* bios_boot_delay */
14103 1, /* scsi_reset_delay */
14104 1, /* bios_id_lun */
14105 1, /* termination */
14106 1, /* reserved1 */
14107 0, /* bios_ctrl */
14108 0, /* ultra_able */
14109 0, /* reserved2 */
14110 1, /* max_host_qng */
14111 1, /* max_dvc_qng */
14112 0, /* dvc_cntl */
14113 0, /* bug_fix */
14114 0, /* serial_number_word1 */
14115 0, /* serial_number_word2 */
14116 0, /* serial_number_word3 */
14117 0, /* check_sum */
14118 { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* oem_name[16] */
14119 0, /* dvc_err_code */
14120 0, /* adv_err_code */
14121 0, /* adv_err_addr */
14122 0, /* saved_dvc_err_code */
14123 0, /* saved_adv_err_code */
14124 0, /* saved_adv_err_addr */
14125 0 /* num_of_err */
14126};
14127
14128STATIC ADVEEP_38C0800_CONFIG
14129Default_38C0800_EEPROM_Config __initdata = {
14130 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
14131 0x0000, /* 01 cfg_msw */
14132 0xFFFF, /* 02 disc_enable */
14133 0xFFFF, /* 03 wdtr_able */
14134 0x4444, /* 04 sdtr_speed1 */
14135 0xFFFF, /* 05 start_motor */
14136 0xFFFF, /* 06 tagqng_able */
14137 0xFFFF, /* 07 bios_scan */
14138 0, /* 08 scam_tolerant */
14139 7, /* 09 adapter_scsi_id */
14140 0, /* bios_boot_delay */
14141 3, /* 10 scsi_reset_delay */
14142 0, /* bios_id_lun */
14143 0, /* 11 termination_se */
14144 0, /* termination_lvd */
14145 0xFFE7, /* 12 bios_ctrl */
14146 0x4444, /* 13 sdtr_speed2 */
14147 0x4444, /* 14 sdtr_speed3 */
14148 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
14149 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
14150 0, /* 16 dvc_cntl */
14151 0x4444, /* 17 sdtr_speed4 */
14152 0, /* 18 serial_number_word1 */
14153 0, /* 19 serial_number_word2 */
14154 0, /* 20 serial_number_word3 */
14155 0, /* 21 check_sum */
14156 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */
14157 0, /* 30 dvc_err_code */
14158 0, /* 31 adv_err_code */
14159 0, /* 32 adv_err_addr */
14160 0, /* 33 saved_dvc_err_code */
14161 0, /* 34 saved_adv_err_code */
14162 0, /* 35 saved_adv_err_addr */
14163 0, /* 36 reserved */
14164 0, /* 37 reserved */
14165 0, /* 38 reserved */
14166 0, /* 39 reserved */
14167 0, /* 40 reserved */
14168 0, /* 41 reserved */
14169 0, /* 42 reserved */
14170 0, /* 43 reserved */
14171 0, /* 44 reserved */
14172 0, /* 45 reserved */
14173 0, /* 46 reserved */
14174 0, /* 47 reserved */
14175 0, /* 48 reserved */
14176 0, /* 49 reserved */
14177 0, /* 50 reserved */
14178 0, /* 51 reserved */
14179 0, /* 52 reserved */
14180 0, /* 53 reserved */
14181 0, /* 54 reserved */
14182 0, /* 55 reserved */
14183 0, /* 56 cisptr_lsw */
14184 0, /* 57 cisprt_msw */
2672ea86
DJ
14185 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
14186 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
1da177e4
LT
14187 0, /* 60 reserved */
14188 0, /* 61 reserved */
14189 0, /* 62 reserved */
14190 0 /* 63 reserved */
14191};
14192
14193STATIC ADVEEP_38C0800_CONFIG
14194ADVEEP_38C0800_Config_Field_IsChar __initdata = {
14195 0, /* 00 cfg_lsw */
14196 0, /* 01 cfg_msw */
14197 0, /* 02 disc_enable */
14198 0, /* 03 wdtr_able */
14199 0, /* 04 sdtr_speed1 */
14200 0, /* 05 start_motor */
14201 0, /* 06 tagqng_able */
14202 0, /* 07 bios_scan */
14203 0, /* 08 scam_tolerant */
14204 1, /* 09 adapter_scsi_id */
14205 1, /* bios_boot_delay */
14206 1, /* 10 scsi_reset_delay */
14207 1, /* bios_id_lun */
14208 1, /* 11 termination_se */
14209 1, /* termination_lvd */
14210 0, /* 12 bios_ctrl */
14211 0, /* 13 sdtr_speed2 */
14212 0, /* 14 sdtr_speed3 */
14213 1, /* 15 max_host_qng */
14214 1, /* max_dvc_qng */
14215 0, /* 16 dvc_cntl */
14216 0, /* 17 sdtr_speed4 */
14217 0, /* 18 serial_number_word1 */
14218 0, /* 19 serial_number_word2 */
14219 0, /* 20 serial_number_word3 */
14220 0, /* 21 check_sum */
14221 { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* 22-29 oem_name[16] */
14222 0, /* 30 dvc_err_code */
14223 0, /* 31 adv_err_code */
14224 0, /* 32 adv_err_addr */
14225 0, /* 33 saved_dvc_err_code */
14226 0, /* 34 saved_adv_err_code */
14227 0, /* 35 saved_adv_err_addr */
14228 0, /* 36 reserved */
14229 0, /* 37 reserved */
14230 0, /* 38 reserved */
14231 0, /* 39 reserved */
14232 0, /* 40 reserved */
14233 0, /* 41 reserved */
14234 0, /* 42 reserved */
14235 0, /* 43 reserved */
14236 0, /* 44 reserved */
14237 0, /* 45 reserved */
14238 0, /* 46 reserved */
14239 0, /* 47 reserved */
14240 0, /* 48 reserved */
14241 0, /* 49 reserved */
14242 0, /* 50 reserved */
14243 0, /* 51 reserved */
14244 0, /* 52 reserved */
14245 0, /* 53 reserved */
14246 0, /* 54 reserved */
14247 0, /* 55 reserved */
14248 0, /* 56 cisptr_lsw */
14249 0, /* 57 cisprt_msw */
14250 0, /* 58 subsysvid */
14251 0, /* 59 subsysid */
14252 0, /* 60 reserved */
14253 0, /* 61 reserved */
14254 0, /* 62 reserved */
14255 0 /* 63 reserved */
14256};
14257
14258STATIC ADVEEP_38C1600_CONFIG
14259Default_38C1600_EEPROM_Config __initdata = {
14260 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
14261 0x0000, /* 01 cfg_msw */
14262 0xFFFF, /* 02 disc_enable */
14263 0xFFFF, /* 03 wdtr_able */
14264 0x5555, /* 04 sdtr_speed1 */
14265 0xFFFF, /* 05 start_motor */
14266 0xFFFF, /* 06 tagqng_able */
14267 0xFFFF, /* 07 bios_scan */
14268 0, /* 08 scam_tolerant */
14269 7, /* 09 adapter_scsi_id */
14270 0, /* bios_boot_delay */
14271 3, /* 10 scsi_reset_delay */
14272 0, /* bios_id_lun */
14273 0, /* 11 termination_se */
14274 0, /* termination_lvd */
14275 0xFFE7, /* 12 bios_ctrl */
14276 0x5555, /* 13 sdtr_speed2 */
14277 0x5555, /* 14 sdtr_speed3 */
14278 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
14279 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
14280 0, /* 16 dvc_cntl */
14281 0x5555, /* 17 sdtr_speed4 */
14282 0, /* 18 serial_number_word1 */
14283 0, /* 19 serial_number_word2 */
14284 0, /* 20 serial_number_word3 */
14285 0, /* 21 check_sum */
14286 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */
14287 0, /* 30 dvc_err_code */
14288 0, /* 31 adv_err_code */
14289 0, /* 32 adv_err_addr */
14290 0, /* 33 saved_dvc_err_code */
14291 0, /* 34 saved_adv_err_code */
14292 0, /* 35 saved_adv_err_addr */
14293 0, /* 36 reserved */
14294 0, /* 37 reserved */
14295 0, /* 38 reserved */
14296 0, /* 39 reserved */
14297 0, /* 40 reserved */
14298 0, /* 41 reserved */
14299 0, /* 42 reserved */
14300 0, /* 43 reserved */
14301 0, /* 44 reserved */
14302 0, /* 45 reserved */
14303 0, /* 46 reserved */
14304 0, /* 47 reserved */
14305 0, /* 48 reserved */
14306 0, /* 49 reserved */
14307 0, /* 50 reserved */
14308 0, /* 51 reserved */
14309 0, /* 52 reserved */
14310 0, /* 53 reserved */
14311 0, /* 54 reserved */
14312 0, /* 55 reserved */
14313 0, /* 56 cisptr_lsw */
14314 0, /* 57 cisprt_msw */
2672ea86
DJ
14315 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
14316 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
1da177e4
LT
14317 0, /* 60 reserved */
14318 0, /* 61 reserved */
14319 0, /* 62 reserved */
14320 0 /* 63 reserved */
14321};
14322
14323STATIC ADVEEP_38C1600_CONFIG
14324ADVEEP_38C1600_Config_Field_IsChar __initdata = {
14325 0, /* 00 cfg_lsw */
14326 0, /* 01 cfg_msw */
14327 0, /* 02 disc_enable */
14328 0, /* 03 wdtr_able */
14329 0, /* 04 sdtr_speed1 */
14330 0, /* 05 start_motor */
14331 0, /* 06 tagqng_able */
14332 0, /* 07 bios_scan */
14333 0, /* 08 scam_tolerant */
14334 1, /* 09 adapter_scsi_id */
14335 1, /* bios_boot_delay */
14336 1, /* 10 scsi_reset_delay */
14337 1, /* bios_id_lun */
14338 1, /* 11 termination_se */
14339 1, /* termination_lvd */
14340 0, /* 12 bios_ctrl */
14341 0, /* 13 sdtr_speed2 */
14342 0, /* 14 sdtr_speed3 */
14343 1, /* 15 max_host_qng */
14344 1, /* max_dvc_qng */
14345 0, /* 16 dvc_cntl */
14346 0, /* 17 sdtr_speed4 */
14347 0, /* 18 serial_number_word1 */
14348 0, /* 19 serial_number_word2 */
14349 0, /* 20 serial_number_word3 */
14350 0, /* 21 check_sum */
14351 { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* 22-29 oem_name[16] */
14352 0, /* 30 dvc_err_code */
14353 0, /* 31 adv_err_code */
14354 0, /* 32 adv_err_addr */
14355 0, /* 33 saved_dvc_err_code */
14356 0, /* 34 saved_adv_err_code */
14357 0, /* 35 saved_adv_err_addr */
14358 0, /* 36 reserved */
14359 0, /* 37 reserved */
14360 0, /* 38 reserved */
14361 0, /* 39 reserved */
14362 0, /* 40 reserved */
14363 0, /* 41 reserved */
14364 0, /* 42 reserved */
14365 0, /* 43 reserved */
14366 0, /* 44 reserved */
14367 0, /* 45 reserved */
14368 0, /* 46 reserved */
14369 0, /* 47 reserved */
14370 0, /* 48 reserved */
14371 0, /* 49 reserved */
14372 0, /* 50 reserved */
14373 0, /* 51 reserved */
14374 0, /* 52 reserved */
14375 0, /* 53 reserved */
14376 0, /* 54 reserved */
14377 0, /* 55 reserved */
14378 0, /* 56 cisptr_lsw */
14379 0, /* 57 cisprt_msw */
14380 0, /* 58 subsysvid */
14381 0, /* 59 subsysid */
14382 0, /* 60 reserved */
14383 0, /* 61 reserved */
14384 0, /* 62 reserved */
14385 0 /* 63 reserved */
14386};
14387
14388/*
14389 * Initialize the ADV_DVC_VAR structure.
14390 *
14391 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14392 *
14393 * For a non-fatal error return a warning code. If there are no warnings
14394 * then 0 is returned.
14395 */
14396STATIC int __init
14397AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
14398{
14399 ushort warn_code;
14400 AdvPortAddr iop_base;
14401 uchar pci_cmd_reg;
14402 int status;
14403
14404 warn_code = 0;
14405 asc_dvc->err_code = 0;
14406 iop_base = asc_dvc->iop_base;
14407
14408 /*
14409 * PCI Command Register
14410 *
14411 * Note: AscPCICmdRegBits_BusMastering definition (0x0007) includes
14412 * I/O Space Control, Memory Space Control and Bus Master Control bits.
14413 */
14414
14415 if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
14416 AscPCIConfigCommandRegister))
14417 & AscPCICmdRegBits_BusMastering)
14418 != AscPCICmdRegBits_BusMastering)
14419 {
14420 pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
14421
14422 DvcAdvWritePCIConfigByte(asc_dvc,
14423 AscPCIConfigCommandRegister, pci_cmd_reg);
14424
14425 if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister))
14426 & AscPCICmdRegBits_BusMastering)
14427 != AscPCICmdRegBits_BusMastering)
14428 {
14429 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14430 }
14431 }
14432
14433 /*
14434 * PCI Latency Timer
14435 *
14436 * If the "latency timer" register is 0x20 or above, then we don't need
14437 * to change it. Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
14438 * comes up less than 0x20).
14439 */
14440 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
14441 DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer, 0x20);
14442 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20)
14443 {
14444 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14445 }
14446 }
14447
14448 /*
14449 * Save the state of the PCI Configuration Command Register
14450 * "Parity Error Response Control" Bit. If the bit is clear (0),
14451 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
14452 * DMA parity errors.
14453 */
14454 asc_dvc->cfg->control_flag = 0;
14455 if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
14456 & AscPCICmdRegBits_ParErrRespCtrl)) == 0)
14457 {
14458 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
14459 }
14460
14461 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
14462 ADV_LIB_VERSION_MINOR;
14463 asc_dvc->cfg->chip_version =
14464 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
14465
14466 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
14467 (ushort) AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
14468 (ushort) ADV_CHIP_ID_BYTE);
14469
14470 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
14471 (ushort) AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
14472 (ushort) ADV_CHIP_ID_WORD);
14473
14474 /*
14475 * Reset the chip to start and allow register writes.
14476 */
14477 if (AdvFindSignature(iop_base) == 0)
14478 {
14479 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
14480 return ADV_ERROR;
14481 }
14482 else {
14483 /*
14484 * The caller must set 'chip_type' to a valid setting.
14485 */
14486 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
14487 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
14488 asc_dvc->chip_type != ADV_CHIP_ASC38C1600)
14489 {
14490 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14491 return ADV_ERROR;
14492 }
14493
14494 /*
14495 * Reset Chip.
14496 */
14497 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14498 ADV_CTRL_REG_CMD_RESET);
14499 DvcSleepMilliSecond(100);
14500 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14501 ADV_CTRL_REG_CMD_WR_IO_REG);
14502
14503 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
14504 {
14505 if ((status = AdvInitFrom38C1600EEP(asc_dvc)) == ADV_ERROR)
14506 {
14507 return ADV_ERROR;
14508 }
14509 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
14510 {
14511 if ((status = AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR)
14512 {
14513 return ADV_ERROR;
14514 }
14515 } else
14516 {
14517 if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR)
14518 {
14519 return ADV_ERROR;
14520 }
14521 }
14522 warn_code |= status;
14523 }
14524
14525 return warn_code;
14526}
14527
14528/*
14529 * Initialize the ASC-3550.
14530 *
14531 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14532 *
14533 * For a non-fatal error return a warning code. If there are no warnings
14534 * then 0 is returned.
14535 *
14536 * Needed after initialization for error recovery.
14537 */
14538STATIC int
14539AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
14540{
14541 AdvPortAddr iop_base;
14542 ushort warn_code;
14543 ADV_DCNT sum;
14544 int begin_addr;
14545 int end_addr;
14546 ushort code_sum;
14547 int word;
14548 int j;
14549 int adv_asc3550_expanded_size;
14550 ADV_CARR_T *carrp;
14551 ADV_DCNT contig_len;
14552 ADV_SDCNT buf_size;
14553 ADV_PADDR carr_paddr;
14554 int i;
14555 ushort scsi_cfg1;
14556 uchar tid;
14557 ushort bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
14558 ushort wdtr_able = 0, sdtr_able, tagqng_able;
14559 uchar max_cmd[ADV_MAX_TID + 1];
14560
14561 /* If there is already an error, don't continue. */
14562 if (asc_dvc->err_code != 0)
14563 {
14564 return ADV_ERROR;
14565 }
14566
14567 /*
14568 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
14569 */
14570 if (asc_dvc->chip_type != ADV_CHIP_ASC3550)
14571 {
14572 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14573 return ADV_ERROR;
14574 }
14575
14576 warn_code = 0;
14577 iop_base = asc_dvc->iop_base;
14578
14579 /*
14580 * Save the RISC memory BIOS region before writing the microcode.
14581 * The BIOS may already be loaded and using its RISC LRAM region
14582 * so its region must be saved and restored.
14583 *
14584 * Note: This code makes the assumption, which is currently true,
14585 * that a chip reset does not clear RISC LRAM.
14586 */
14587 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
14588 {
14589 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
14590 }
14591
14592 /*
14593 * Save current per TID negotiated values.
14594 */
14595 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
14596 {
14597 ushort bios_version, major, minor;
14598
14599 bios_version = bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM)/2];
14600 major = (bios_version >> 12) & 0xF;
14601 minor = (bios_version >> 8) & 0xF;
14602 if (major < 3 || (major == 3 && minor == 1))
14603 {
14604 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
14605 AdvReadWordLram(iop_base, 0x120, wdtr_able);
14606 } else
14607 {
14608 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14609 }
14610 }
14611 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14612 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14613 for (tid = 0; tid <= ADV_MAX_TID; tid++)
14614 {
14615 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14616 max_cmd[tid]);
14617 }
14618
14619 /*
14620 * Load the Microcode
14621 *
14622 * Write the microcode image to RISC memory starting at address 0.
14623 */
14624 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14625 /* Assume the following compressed format of the microcode buffer:
14626 *
14627 * 254 word (508 byte) table indexed by byte code followed
14628 * by the following byte codes:
14629 *
14630 * 1-Byte Code:
14631 * 00: Emit word 0 in table.
14632 * 01: Emit word 1 in table.
14633 * .
14634 * FD: Emit word 253 in table.
14635 *
14636 * Multi-Byte Code:
14637 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14638 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14639 */
14640 word = 0;
14641 for (i = 253 * 2; i < _adv_asc3550_size; i++)
14642 {
14643 if (_adv_asc3550_buf[i] == 0xff)
14644 {
14645 for (j = 0; j < _adv_asc3550_buf[i + 1]; j++)
14646 {
14647 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14648 _adv_asc3550_buf[i + 3] << 8) |
14649 _adv_asc3550_buf[i + 2]));
14650 word++;
14651 }
14652 i += 3;
14653 } else if (_adv_asc3550_buf[i] == 0xfe)
14654 {
14655 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14656 _adv_asc3550_buf[i + 2] << 8) |
14657 _adv_asc3550_buf[i + 1]));
14658 i += 2;
14659 word++;
14660 } else
14661 {
14662 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14663 _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) |
14664 _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
14665 word++;
14666 }
14667 }
14668
14669 /*
14670 * Set 'word' for later use to clear the rest of memory and save
14671 * the expanded mcode size.
14672 */
14673 word *= 2;
14674 adv_asc3550_expanded_size = word;
14675
14676 /*
14677 * Clear the rest of ASC-3550 Internal RAM (8KB).
14678 */
14679 for (; word < ADV_3550_MEMSIZE; word += 2)
14680 {
14681 AdvWriteWordAutoIncLram(iop_base, 0);
14682 }
14683
14684 /*
14685 * Verify the microcode checksum.
14686 */
14687 sum = 0;
14688 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14689
14690 for (word = 0; word < adv_asc3550_expanded_size; word += 2)
14691 {
14692 sum += AdvReadWordAutoIncLram(iop_base);
14693 }
14694
14695 if (sum != _adv_asc3550_chksum)
14696 {
14697 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14698 return ADV_ERROR;
14699 }
14700
14701 /*
14702 * Restore the RISC memory BIOS region.
14703 */
14704 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
14705 {
14706 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
14707 }
14708
14709 /*
14710 * Calculate and write the microcode code checksum to the microcode
14711 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14712 */
14713 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14714 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14715 code_sum = 0;
14716 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14717 for (word = begin_addr; word < end_addr; word += 2)
14718 {
14719 code_sum += AdvReadWordAutoIncLram(iop_base);
14720 }
14721 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14722
14723 /*
14724 * Read and save microcode version and date.
14725 */
14726 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
14727 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
14728
14729 /*
14730 * Set the chip type to indicate the ASC3550.
14731 */
14732 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
14733
14734 /*
14735 * If the PCI Configuration Command Register "Parity Error Response
14736 * Control" Bit was clear (0), then set the microcode variable
14737 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14738 * to ignore DMA parity errors.
14739 */
14740 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
14741 {
14742 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14743 word |= CONTROL_FLAG_IGNORE_PERR;
14744 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14745 }
14746
14747 /*
14748 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
14749 * threshold of 128 bytes. This register is only accessible to the host.
14750 */
14751 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14752 START_CTL_EMFU | READ_CMD_MRM);
14753
14754 /*
14755 * Microcode operating variables for WDTR, SDTR, and command tag
14756 * queuing will be set in AdvInquiryHandling() based on what a
14757 * device reports it is capable of in Inquiry byte 7.
14758 *
14759 * If SCSI Bus Resets have been disabled, then directly set
14760 * SDTR and WDTR from the EEPROM configuration. This will allow
14761 * the BIOS and warm boot to work without a SCSI bus hang on
14762 * the Inquiry caused by host and target mismatched DTR values.
14763 * Without the SCSI Bus Reset, before an Inquiry a device can't
14764 * be assumed to be in Asynchronous, Narrow mode.
14765 */
14766 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
14767 {
14768 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
14769 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
14770 }
14771
14772 /*
14773 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
14774 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
14775 * bitmask. These values determine the maximum SDTR speed negotiated
14776 * with a device.
14777 *
14778 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14779 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14780 * without determining here whether the device supports SDTR.
14781 *
14782 * 4-bit speed SDTR speed name
14783 * =========== ===============
14784 * 0000b (0x0) SDTR disabled
14785 * 0001b (0x1) 5 Mhz
14786 * 0010b (0x2) 10 Mhz
14787 * 0011b (0x3) 20 Mhz (Ultra)
14788 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
14789 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
14790 * 0110b (0x6) Undefined
14791 * .
14792 * 1111b (0xF) Undefined
14793 */
14794 word = 0;
14795 for (tid = 0; tid <= ADV_MAX_TID; tid++)
14796 {
14797 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able)
14798 {
14799 /* Set Ultra speed for TID 'tid'. */
14800 word |= (0x3 << (4 * (tid % 4)));
14801 } else
14802 {
14803 /* Set Fast speed for TID 'tid'. */
14804 word |= (0x2 << (4 * (tid % 4)));
14805 }
14806 if (tid == 3) /* Check if done with sdtr_speed1. */
14807 {
14808 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
14809 word = 0;
14810 } else if (tid == 7) /* Check if done with sdtr_speed2. */
14811 {
14812 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
14813 word = 0;
14814 } else if (tid == 11) /* Check if done with sdtr_speed3. */
14815 {
14816 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
14817 word = 0;
14818 } else if (tid == 15) /* Check if done with sdtr_speed4. */
14819 {
14820 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
14821 /* End of loop. */
14822 }
14823 }
14824
14825 /*
14826 * Set microcode operating variable for the disconnect per TID bitmask.
14827 */
14828 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
14829
14830 /*
14831 * Set SCSI_CFG0 Microcode Default Value.
14832 *
14833 * The microcode will set the SCSI_CFG0 register using this value
14834 * after it is started below.
14835 */
14836 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14837 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14838 asc_dvc->chip_scsi_id);
14839
14840 /*
14841 * Determine SCSI_CFG1 Microcode Default Value.
14842 *
14843 * The microcode will set the SCSI_CFG1 register using this value
14844 * after it is started below.
14845 */
14846
14847 /* Read current SCSI_CFG1 Register value. */
14848 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14849
14850 /*
14851 * If all three connectors are in use, return an error.
14852 */
14853 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
14854 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0)
14855 {
14856 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
14857 return ADV_ERROR;
14858 }
14859
14860 /*
14861 * If the internal narrow cable is reversed all of the SCSI_CTRL
14862 * register signals will be set. Check for and return an error if
14863 * this condition is found.
14864 */
14865 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
14866 {
14867 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14868 return ADV_ERROR;
14869 }
14870
14871 /*
14872 * If this is a differential board and a single-ended device
14873 * is attached to one of the connectors, return an error.
14874 */
14875 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0)
14876 {
14877 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
14878 return ADV_ERROR;
14879 }
14880
14881 /*
14882 * If automatic termination control is enabled, then set the
14883 * termination value based on a table listed in a_condor.h.
14884 *
14885 * If manual termination was specified with an EEPROM setting
14886 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
14887 * is ready to be 'ored' into SCSI_CFG1.
14888 */
14889 if (asc_dvc->cfg->termination == 0)
14890 {
14891 /*
14892 * The software always controls termination by setting TERM_CTL_SEL.
14893 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
14894 */
14895 asc_dvc->cfg->termination |= TERM_CTL_SEL;
14896
14897 switch(scsi_cfg1 & CABLE_DETECT)
14898 {
14899 /* TERM_CTL_H: on, TERM_CTL_L: on */
14900 case 0x3: case 0x7: case 0xB: case 0xD: case 0xE: case 0xF:
14901 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
14902 break;
14903
14904 /* TERM_CTL_H: on, TERM_CTL_L: off */
14905 case 0x1: case 0x5: case 0x9: case 0xA: case 0xC:
14906 asc_dvc->cfg->termination |= TERM_CTL_H;
14907 break;
14908
14909 /* TERM_CTL_H: off, TERM_CTL_L: off */
14910 case 0x2: case 0x6:
14911 break;
14912 }
14913 }
14914
14915 /*
14916 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
14917 */
14918 scsi_cfg1 &= ~TERM_CTL;
14919
14920 /*
14921 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
14922 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
14923 * referenced, because the hardware internally inverts
14924 * the Termination High and Low bits if TERM_POL is set.
14925 */
14926 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
14927
14928 /*
14929 * Set SCSI_CFG1 Microcode Default Value
14930 *
14931 * Set filter value and possibly modified termination control
14932 * bits in the Microcode SCSI_CFG1 Register Value.
14933 *
14934 * The microcode will set the SCSI_CFG1 register using this value
14935 * after it is started below.
14936 */
14937 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
14938 FLTR_DISABLE | scsi_cfg1);
14939
14940 /*
14941 * Set MEM_CFG Microcode Default Value
14942 *
14943 * The microcode will set the MEM_CFG register using this value
14944 * after it is started below.
14945 *
14946 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
14947 * are defined.
14948 *
14949 * ASC-3550 has 8KB internal memory.
14950 */
14951 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
14952 BIOS_EN | RAM_SZ_8KB);
14953
14954 /*
14955 * Set SEL_MASK Microcode Default Value
14956 *
14957 * The microcode will set the SEL_MASK register using this value
14958 * after it is started below.
14959 */
14960 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
14961 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
14962
14963 /*
14964 * Build carrier freelist.
14965 *
14966 * Driver must have already allocated memory and set 'carrier_buf'.
14967 */
14968 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
14969
14970 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
14971 asc_dvc->carr_freelist = NULL;
14972 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
14973 {
14974 buf_size = ADV_CARRIER_BUFSIZE;
14975 } else
14976 {
14977 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
14978 }
14979
14980 do {
14981 /*
14982 * Get physical address of the carrier 'carrp'.
14983 */
14984 contig_len = sizeof(ADV_CARR_T);
14985 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
14986 (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
14987
14988 buf_size -= sizeof(ADV_CARR_T);
14989
14990 /*
14991 * If the current carrier is not physically contiguous, then
14992 * maybe there was a page crossing. Try the next carrier aligned
14993 * start address.
14994 */
14995 if (contig_len < sizeof(ADV_CARR_T))
14996 {
14997 carrp++;
14998 continue;
14999 }
15000
15001 carrp->carr_pa = carr_paddr;
15002 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15003
15004 /*
15005 * Insert the carrier at the beginning of the freelist.
15006 */
15007 carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15008 asc_dvc->carr_freelist = carrp;
15009
15010 carrp++;
15011 }
15012 while (buf_size > 0);
15013
15014 /*
15015 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15016 */
15017
15018 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
15019 {
15020 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15021 return ADV_ERROR;
15022 }
15023 asc_dvc->carr_freelist = (ADV_CARR_T *)
15024 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15025
15026 /*
15027 * The first command issued will be placed in the stopper carrier.
15028 */
15029 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15030
15031 /*
15032 * Set RISC ICQ physical address start value.
15033 */
15034 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15035
15036 /*
15037 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15038 */
15039 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
15040 {
15041 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15042 return ADV_ERROR;
15043 }
15044 asc_dvc->carr_freelist = (ADV_CARR_T *)
15045 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15046
15047 /*
15048 * The first command completed by the RISC will be placed in
15049 * the stopper.
15050 *
15051 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15052 * completed the RISC will set the ASC_RQ_STOPPER bit.
15053 */
15054 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15055
15056 /*
15057 * Set RISC IRQ physical address start value.
15058 */
15059 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15060 asc_dvc->carr_pending_cnt = 0;
15061
15062 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15063 (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
15064
15065 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15066 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15067
15068 /* finally, finally, gentlemen, start your engine */
15069 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15070
15071 /*
15072 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15073 * Resets should be performed. The RISC has to be running
15074 * to issue a SCSI Bus Reset.
15075 */
15076 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
15077 {
15078 /*
15079 * If the BIOS Signature is present in memory, restore the
15080 * BIOS Handshake Configuration Table and do not perform
15081 * a SCSI Bus Reset.
15082 */
15083 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
15084 {
15085 /*
15086 * Restore per TID negotiated values.
15087 */
15088 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15089 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15090 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15091 for (tid = 0; tid <= ADV_MAX_TID; tid++)
15092 {
15093 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15094 max_cmd[tid]);
15095 }
15096 } else
15097 {
15098 if (AdvResetSB(asc_dvc) != ADV_TRUE)
15099 {
15100 warn_code = ASC_WARN_BUSRESET_ERROR;
15101 }
15102 }
15103 }
15104
15105 return warn_code;
15106}
15107
15108/*
15109 * Initialize the ASC-38C0800.
15110 *
15111 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15112 *
15113 * For a non-fatal error return a warning code. If there are no warnings
15114 * then 0 is returned.
15115 *
15116 * Needed after initialization for error recovery.
15117 */
15118STATIC int
15119AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
15120{
15121 AdvPortAddr iop_base;
15122 ushort warn_code;
15123 ADV_DCNT sum;
15124 int begin_addr;
15125 int end_addr;
15126 ushort code_sum;
15127 int word;
15128 int j;
15129 int adv_asc38C0800_expanded_size;
15130 ADV_CARR_T *carrp;
15131 ADV_DCNT contig_len;
15132 ADV_SDCNT buf_size;
15133 ADV_PADDR carr_paddr;
15134 int i;
15135 ushort scsi_cfg1;
15136 uchar byte;
15137 uchar tid;
15138 ushort bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
15139 ushort wdtr_able, sdtr_able, tagqng_able;
15140 uchar max_cmd[ADV_MAX_TID + 1];
15141
15142 /* If there is already an error, don't continue. */
15143 if (asc_dvc->err_code != 0)
15144 {
15145 return ADV_ERROR;
15146 }
15147
15148 /*
15149 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
15150 */
15151 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800)
15152 {
15153 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
15154 return ADV_ERROR;
15155 }
15156
15157 warn_code = 0;
15158 iop_base = asc_dvc->iop_base;
15159
15160 /*
15161 * Save the RISC memory BIOS region before writing the microcode.
15162 * The BIOS may already be loaded and using its RISC LRAM region
15163 * so its region must be saved and restored.
15164 *
15165 * Note: This code makes the assumption, which is currently true,
15166 * that a chip reset does not clear RISC LRAM.
15167 */
15168 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15169 {
15170 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15171 }
15172
15173 /*
15174 * Save current per TID negotiated values.
15175 */
15176 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15177 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15178 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15179 for (tid = 0; tid <= ADV_MAX_TID; tid++)
15180 {
15181 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15182 max_cmd[tid]);
15183 }
15184
15185 /*
15186 * RAM BIST (RAM Built-In Self Test)
15187 *
15188 * Address : I/O base + offset 0x38h register (byte).
15189 * Function: Bit 7-6(RW) : RAM mode
15190 * Normal Mode : 0x00
15191 * Pre-test Mode : 0x40
15192 * RAM Test Mode : 0x80
15193 * Bit 5 : unused
15194 * Bit 4(RO) : Done bit
15195 * Bit 3-0(RO) : Status
15196 * Host Error : 0x08
15197 * Int_RAM Error : 0x04
15198 * RISC Error : 0x02
15199 * SCSI Error : 0x01
15200 * No Error : 0x00
15201 *
15202 * Note: RAM BIST code should be put right here, before loading the
15203 * microcode and after saving the RISC memory BIOS region.
15204 */
15205
15206 /*
15207 * LRAM Pre-test
15208 *
15209 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15210 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15211 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15212 * to NORMAL_MODE, return an error too.
15213 */
15214 for (i = 0; i < 2; i++)
15215 {
15216 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15217 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15218 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15219 if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE)
15220 {
15221 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15222 return ADV_ERROR;
15223 }
15224
15225 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15226 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15227 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15228 != NORMAL_VALUE)
15229 {
15230 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15231 return ADV_ERROR;
15232 }
15233 }
15234
15235 /*
15236 * LRAM Test - It takes about 1.5 ms to run through the test.
15237 *
15238 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15239 * If Done bit not set or Status not 0, save register byte, set the
15240 * err_code, and return an error.
15241 */
15242 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15243 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
15244
15245 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15246 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0)
15247 {
15248 /* Get here if Done bit not set or Status not 0. */
15249 asc_dvc->bist_err_code = byte; /* for BIOS display message */
15250 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15251 return ADV_ERROR;
15252 }
15253
15254 /* We need to reset back to normal mode after LRAM test passes. */
15255 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15256
15257 /*
15258 * Load the Microcode
15259 *
15260 * Write the microcode image to RISC memory starting at address 0.
15261 *
15262 */
15263 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15264
15265 /* Assume the following compressed format of the microcode buffer:
15266 *
15267 * 254 word (508 byte) table indexed by byte code followed
15268 * by the following byte codes:
15269 *
15270 * 1-Byte Code:
15271 * 00: Emit word 0 in table.
15272 * 01: Emit word 1 in table.
15273 * .
15274 * FD: Emit word 253 in table.
15275 *
15276 * Multi-Byte Code:
15277 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15278 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15279 */
15280 word = 0;
15281 for (i = 253 * 2; i < _adv_asc38C0800_size; i++)
15282 {
15283 if (_adv_asc38C0800_buf[i] == 0xff)
15284 {
15285 for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++)
15286 {
15287 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15288 _adv_asc38C0800_buf[i + 3] << 8) |
15289 _adv_asc38C0800_buf[i + 2]));
15290 word++;
15291 }
15292 i += 3;
15293 } else if (_adv_asc38C0800_buf[i] == 0xfe)
15294 {
15295 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15296 _adv_asc38C0800_buf[i + 2] << 8) |
15297 _adv_asc38C0800_buf[i + 1]));
15298 i += 2;
15299 word++;
15300 } else
15301 {
15302 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15303 _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) |
15304 _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
15305 word++;
15306 }
15307 }
15308
15309 /*
15310 * Set 'word' for later use to clear the rest of memory and save
15311 * the expanded mcode size.
15312 */
15313 word *= 2;
15314 adv_asc38C0800_expanded_size = word;
15315
15316 /*
15317 * Clear the rest of ASC-38C0800 Internal RAM (16KB).
15318 */
15319 for (; word < ADV_38C0800_MEMSIZE; word += 2)
15320 {
15321 AdvWriteWordAutoIncLram(iop_base, 0);
15322 }
15323
15324 /*
15325 * Verify the microcode checksum.
15326 */
15327 sum = 0;
15328 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15329
15330 for (word = 0; word < adv_asc38C0800_expanded_size; word += 2)
15331 {
15332 sum += AdvReadWordAutoIncLram(iop_base);
15333 }
15334 ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
15335
15336 ASC_DBG2(1,
15337 "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
15338 (ulong) sum, (ulong) _adv_asc38C0800_chksum);
15339
15340 if (sum != _adv_asc38C0800_chksum)
15341 {
15342 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15343 return ADV_ERROR;
15344 }
15345
15346 /*
15347 * Restore the RISC memory BIOS region.
15348 */
15349 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15350 {
15351 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15352 }
15353
15354 /*
15355 * Calculate and write the microcode code checksum to the microcode
15356 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15357 */
15358 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15359 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15360 code_sum = 0;
15361 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15362 for (word = begin_addr; word < end_addr; word += 2)
15363 {
15364 code_sum += AdvReadWordAutoIncLram(iop_base);
15365 }
15366 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15367
15368 /*
15369 * Read microcode version and date.
15370 */
15371 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
15372 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
15373
15374 /*
15375 * Set the chip type to indicate the ASC38C0800.
15376 */
15377 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
15378
15379 /*
15380 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15381 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15382 * cable detection and then we are able to read C_DET[3:0].
15383 *
15384 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15385 * Microcode Default Value' section below.
15386 */
15387 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15388 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV);
15389
15390 /*
15391 * If the PCI Configuration Command Register "Parity Error Response
15392 * Control" Bit was clear (0), then set the microcode variable
15393 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15394 * to ignore DMA parity errors.
15395 */
15396 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
15397 {
15398 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15399 word |= CONTROL_FLAG_IGNORE_PERR;
15400 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15401 }
15402
15403 /*
15404 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
15405 * bits for the default FIFO threshold.
15406 *
15407 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
15408 *
15409 * For DMA Errata #4 set the BC_THRESH_ENB bit.
15410 */
15411 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15412 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
15413
15414 /*
15415 * Microcode operating variables for WDTR, SDTR, and command tag
15416 * queuing will be set in AdvInquiryHandling() based on what a
15417 * device reports it is capable of in Inquiry byte 7.
15418 *
15419 * If SCSI Bus Resets have been disabled, then directly set
15420 * SDTR and WDTR from the EEPROM configuration. This will allow
15421 * the BIOS and warm boot to work without a SCSI bus hang on
15422 * the Inquiry caused by host and target mismatched DTR values.
15423 * Without the SCSI Bus Reset, before an Inquiry a device can't
15424 * be assumed to be in Asynchronous, Narrow mode.
15425 */
15426 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
15427 {
15428 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
15429 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
15430 }
15431
15432 /*
15433 * Set microcode operating variables for DISC and SDTR_SPEED1,
15434 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15435 * configuration values.
15436 *
15437 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15438 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15439 * without determining here whether the device supports SDTR.
15440 */
15441 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
15442 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15443 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15444 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15445 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15446
15447 /*
15448 * Set SCSI_CFG0 Microcode Default Value.
15449 *
15450 * The microcode will set the SCSI_CFG0 register using this value
15451 * after it is started below.
15452 */
15453 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15454 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15455 asc_dvc->chip_scsi_id);
15456
15457 /*
15458 * Determine SCSI_CFG1 Microcode Default Value.
15459 *
15460 * The microcode will set the SCSI_CFG1 register using this value
15461 * after it is started below.
15462 */
15463
15464 /* Read current SCSI_CFG1 Register value. */
15465 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15466
15467 /*
15468 * If the internal narrow cable is reversed all of the SCSI_CTRL
15469 * register signals will be set. Check for and return an error if
15470 * this condition is found.
15471 */
15472 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
15473 {
15474 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15475 return ADV_ERROR;
15476 }
15477
15478 /*
15479 * All kind of combinations of devices attached to one of four connectors
15480 * are acceptable except HVD device attached. For example, LVD device can
15481 * be attached to SE connector while SE device attached to LVD connector.
15482 * If LVD device attached to SE connector, it only runs up to Ultra speed.
15483 *
15484 * If an HVD device is attached to one of LVD connectors, return an error.
15485 * However, there is no way to detect HVD device attached to SE connectors.
15486 */
15487 if (scsi_cfg1 & HVD)
15488 {
15489 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15490 return ADV_ERROR;
15491 }
15492
15493 /*
15494 * If either SE or LVD automatic termination control is enabled, then
15495 * set the termination value based on a table listed in a_condor.h.
15496 *
15497 * If manual termination was specified with an EEPROM setting then
15498 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
15499 * be 'ored' into SCSI_CFG1.
15500 */
15501 if ((asc_dvc->cfg->termination & TERM_SE) == 0)
15502 {
15503 /* SE automatic termination control is enabled. */
15504 switch(scsi_cfg1 & C_DET_SE)
15505 {
15506 /* TERM_SE_HI: on, TERM_SE_LO: on */
15507 case 0x1: case 0x2: case 0x3:
15508 asc_dvc->cfg->termination |= TERM_SE;
15509 break;
15510
15511 /* TERM_SE_HI: on, TERM_SE_LO: off */
15512 case 0x0:
15513 asc_dvc->cfg->termination |= TERM_SE_HI;
15514 break;
15515 }
15516 }
15517
15518 if ((asc_dvc->cfg->termination & TERM_LVD) == 0)
15519 {
15520 /* LVD automatic termination control is enabled. */
15521 switch(scsi_cfg1 & C_DET_LVD)
15522 {
15523 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
15524 case 0x4: case 0x8: case 0xC:
15525 asc_dvc->cfg->termination |= TERM_LVD;
15526 break;
15527
15528 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
15529 case 0x0:
15530 break;
15531 }
15532 }
15533
15534 /*
15535 * Clear any set TERM_SE and TERM_LVD bits.
15536 */
15537 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
15538
15539 /*
15540 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
15541 */
15542 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
15543
15544 /*
15545 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
15546 * and set possibly modified termination control bits in the Microcode
15547 * SCSI_CFG1 Register Value.
15548 */
15549 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
15550
15551 /*
15552 * Set SCSI_CFG1 Microcode Default Value
15553 *
15554 * Set possibly modified termination control and reset DIS_TERM_DRV
15555 * bits in the Microcode SCSI_CFG1 Register Value.
15556 *
15557 * The microcode will set the SCSI_CFG1 register using this value
15558 * after it is started below.
15559 */
15560 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15561
15562 /*
15563 * Set MEM_CFG Microcode Default Value
15564 *
15565 * The microcode will set the MEM_CFG register using this value
15566 * after it is started below.
15567 *
15568 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15569 * are defined.
15570 *
15571 * ASC-38C0800 has 16KB internal memory.
15572 */
15573 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15574 BIOS_EN | RAM_SZ_16KB);
15575
15576 /*
15577 * Set SEL_MASK Microcode Default Value
15578 *
15579 * The microcode will set the SEL_MASK register using this value
15580 * after it is started below.
15581 */
15582 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15583 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15584
15585 /*
15586 * Build the carrier freelist.
15587 *
15588 * Driver must have already allocated memory and set 'carrier_buf'.
15589 */
15590 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15591
15592 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15593 asc_dvc->carr_freelist = NULL;
15594 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
15595 {
15596 buf_size = ADV_CARRIER_BUFSIZE;
15597 } else
15598 {
15599 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15600 }
15601
15602 do {
15603 /*
15604 * Get physical address for the carrier 'carrp'.
15605 */
15606 contig_len = sizeof(ADV_CARR_T);
15607 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
15608 (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
15609
15610 buf_size -= sizeof(ADV_CARR_T);
15611
15612 /*
15613 * If the current carrier is not physically contiguous, then
15614 * maybe there was a page crossing. Try the next carrier aligned
15615 * start address.
15616 */
15617 if (contig_len < sizeof(ADV_CARR_T))
15618 {
15619 carrp++;
15620 continue;
15621 }
15622
15623 carrp->carr_pa = carr_paddr;
15624 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15625
15626 /*
15627 * Insert the carrier at the beginning of the freelist.
15628 */
15629 carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15630 asc_dvc->carr_freelist = carrp;
15631
15632 carrp++;
15633 }
15634 while (buf_size > 0);
15635
15636 /*
15637 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15638 */
15639
15640 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
15641 {
15642 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15643 return ADV_ERROR;
15644 }
15645 asc_dvc->carr_freelist = (ADV_CARR_T *)
15646 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15647
15648 /*
15649 * The first command issued will be placed in the stopper carrier.
15650 */
15651 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15652
15653 /*
15654 * Set RISC ICQ physical address start value.
15655 * carr_pa is LE, must be native before write
15656 */
15657 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15658
15659 /*
15660 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15661 */
15662 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
15663 {
15664 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15665 return ADV_ERROR;
15666 }
15667 asc_dvc->carr_freelist = (ADV_CARR_T *)
15668 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15669
15670 /*
15671 * The first command completed by the RISC will be placed in
15672 * the stopper.
15673 *
15674 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15675 * completed the RISC will set the ASC_RQ_STOPPER bit.
15676 */
15677 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15678
15679 /*
15680 * Set RISC IRQ physical address start value.
15681 *
15682 * carr_pa is LE, must be native before write *
15683 */
15684 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15685 asc_dvc->carr_pending_cnt = 0;
15686
15687 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15688 (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
15689
15690 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15691 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15692
15693 /* finally, finally, gentlemen, start your engine */
15694 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15695
15696 /*
15697 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15698 * Resets should be performed. The RISC has to be running
15699 * to issue a SCSI Bus Reset.
15700 */
15701 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
15702 {
15703 /*
15704 * If the BIOS Signature is present in memory, restore the
15705 * BIOS Handshake Configuration Table and do not perform
15706 * a SCSI Bus Reset.
15707 */
15708 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
15709 {
15710 /*
15711 * Restore per TID negotiated values.
15712 */
15713 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15714 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15715 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15716 for (tid = 0; tid <= ADV_MAX_TID; tid++)
15717 {
15718 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15719 max_cmd[tid]);
15720 }
15721 } else
15722 {
15723 if (AdvResetSB(asc_dvc) != ADV_TRUE)
15724 {
15725 warn_code = ASC_WARN_BUSRESET_ERROR;
15726 }
15727 }
15728 }
15729
15730 return warn_code;
15731}
15732
15733/*
15734 * Initialize the ASC-38C1600.
15735 *
15736 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
15737 *
15738 * For a non-fatal error return a warning code. If there are no warnings
15739 * then 0 is returned.
15740 *
15741 * Needed after initialization for error recovery.
15742 */
15743STATIC int
15744AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
15745{
15746 AdvPortAddr iop_base;
15747 ushort warn_code;
15748 ADV_DCNT sum;
15749 int begin_addr;
15750 int end_addr;
15751 ushort code_sum;
15752 long word;
15753 int j;
15754 int adv_asc38C1600_expanded_size;
15755 ADV_CARR_T *carrp;
15756 ADV_DCNT contig_len;
15757 ADV_SDCNT buf_size;
15758 ADV_PADDR carr_paddr;
15759 int i;
15760 ushort scsi_cfg1;
15761 uchar byte;
15762 uchar tid;
15763 ushort bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
15764 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
15765 uchar max_cmd[ASC_MAX_TID + 1];
15766
15767 /* If there is already an error, don't continue. */
15768 if (asc_dvc->err_code != 0)
15769 {
15770 return ADV_ERROR;
15771 }
15772
15773 /*
15774 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
15775 */
15776 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600)
15777 {
15778 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
15779 return ADV_ERROR;
15780 }
15781
15782 warn_code = 0;
15783 iop_base = asc_dvc->iop_base;
15784
15785 /*
15786 * Save the RISC memory BIOS region before writing the microcode.
15787 * The BIOS may already be loaded and using its RISC LRAM region
15788 * so its region must be saved and restored.
15789 *
15790 * Note: This code makes the assumption, which is currently true,
15791 * that a chip reset does not clear RISC LRAM.
15792 */
15793 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15794 {
15795 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15796 }
15797
15798 /*
15799 * Save current per TID negotiated values.
15800 */
15801 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15802 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15803 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15804 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15805 for (tid = 0; tid <= ASC_MAX_TID; tid++)
15806 {
15807 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15808 max_cmd[tid]);
15809 }
15810
15811 /*
15812 * RAM BIST (Built-In Self Test)
15813 *
15814 * Address : I/O base + offset 0x38h register (byte).
15815 * Function: Bit 7-6(RW) : RAM mode
15816 * Normal Mode : 0x00
15817 * Pre-test Mode : 0x40
15818 * RAM Test Mode : 0x80
15819 * Bit 5 : unused
15820 * Bit 4(RO) : Done bit
15821 * Bit 3-0(RO) : Status
15822 * Host Error : 0x08
15823 * Int_RAM Error : 0x04
15824 * RISC Error : 0x02
15825 * SCSI Error : 0x01
15826 * No Error : 0x00
15827 *
15828 * Note: RAM BIST code should be put right here, before loading the
15829 * microcode and after saving the RISC memory BIOS region.
15830 */
15831
15832 /*
15833 * LRAM Pre-test
15834 *
15835 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15836 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15837 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15838 * to NORMAL_MODE, return an error too.
15839 */
15840 for (i = 0; i < 2; i++)
15841 {
15842 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15843 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15844 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15845 if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE)
15846 {
15847 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15848 return ADV_ERROR;
15849 }
15850
15851 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15852 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15853 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15854 != NORMAL_VALUE)
15855 {
15856 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15857 return ADV_ERROR;
15858 }
15859 }
15860
15861 /*
15862 * LRAM Test - It takes about 1.5 ms to run through the test.
15863 *
15864 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15865 * If Done bit not set or Status not 0, save register byte, set the
15866 * err_code, and return an error.
15867 */
15868 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15869 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
15870
15871 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15872 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0)
15873 {
15874 /* Get here if Done bit not set or Status not 0. */
15875 asc_dvc->bist_err_code = byte; /* for BIOS display message */
15876 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15877 return ADV_ERROR;
15878 }
15879
15880 /* We need to reset back to normal mode after LRAM test passes. */
15881 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15882
15883 /*
15884 * Load the Microcode
15885 *
15886 * Write the microcode image to RISC memory starting at address 0.
15887 *
15888 */
15889 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15890
15891 /*
15892 * Assume the following compressed format of the microcode buffer:
15893 *
15894 * 254 word (508 byte) table indexed by byte code followed
15895 * by the following byte codes:
15896 *
15897 * 1-Byte Code:
15898 * 00: Emit word 0 in table.
15899 * 01: Emit word 1 in table.
15900 * .
15901 * FD: Emit word 253 in table.
15902 *
15903 * Multi-Byte Code:
15904 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15905 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15906 */
15907 word = 0;
15908 for (i = 253 * 2; i < _adv_asc38C1600_size; i++)
15909 {
15910 if (_adv_asc38C1600_buf[i] == 0xff)
15911 {
15912 for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++)
15913 {
15914 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15915 _adv_asc38C1600_buf[i + 3] << 8) |
15916 _adv_asc38C1600_buf[i + 2]));
15917 word++;
15918 }
15919 i += 3;
15920 } else if (_adv_asc38C1600_buf[i] == 0xfe)
15921 {
15922 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15923 _adv_asc38C1600_buf[i + 2] << 8) |
15924 _adv_asc38C1600_buf[i + 1]));
15925 i += 2;
15926 word++;
15927 } else
15928 {
15929 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15930 _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) |
15931 _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
15932 word++;
15933 }
15934 }
15935
15936 /*
15937 * Set 'word' for later use to clear the rest of memory and save
15938 * the expanded mcode size.
15939 */
15940 word *= 2;
15941 adv_asc38C1600_expanded_size = word;
15942
15943 /*
15944 * Clear the rest of ASC-38C1600 Internal RAM (32KB).
15945 */
15946 for (; word < ADV_38C1600_MEMSIZE; word += 2)
15947 {
15948 AdvWriteWordAutoIncLram(iop_base, 0);
15949 }
15950
15951 /*
15952 * Verify the microcode checksum.
15953 */
15954 sum = 0;
15955 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15956
15957 for (word = 0; word < adv_asc38C1600_expanded_size; word += 2)
15958 {
15959 sum += AdvReadWordAutoIncLram(iop_base);
15960 }
15961
15962 if (sum != _adv_asc38C1600_chksum)
15963 {
15964 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15965 return ADV_ERROR;
15966 }
15967
15968 /*
15969 * Restore the RISC memory BIOS region.
15970 */
15971 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15972 {
15973 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15974 }
15975
15976 /*
15977 * Calculate and write the microcode code checksum to the microcode
15978 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15979 */
15980 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15981 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15982 code_sum = 0;
15983 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15984 for (word = begin_addr; word < end_addr; word += 2)
15985 {
15986 code_sum += AdvReadWordAutoIncLram(iop_base);
15987 }
15988 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15989
15990 /*
15991 * Read microcode version and date.
15992 */
15993 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
15994 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
15995
15996 /*
15997 * Set the chip type to indicate the ASC38C1600.
15998 */
15999 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
16000
16001 /*
16002 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
16003 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
16004 * cable detection and then we are able to read C_DET[3:0].
16005 *
16006 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
16007 * Microcode Default Value' section below.
16008 */
16009 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
16010 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV);
16011
16012 /*
16013 * If the PCI Configuration Command Register "Parity Error Response
16014 * Control" Bit was clear (0), then set the microcode variable
16015 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
16016 * to ignore DMA parity errors.
16017 */
16018 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
16019 {
16020 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16021 word |= CONTROL_FLAG_IGNORE_PERR;
16022 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16023 }
16024
16025 /*
16026 * If the BIOS control flag AIPP (Asynchronous Information
16027 * Phase Protection) disable bit is not set, then set the firmware
16028 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
16029 * AIPP checking and encoding.
16030 */
16031 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0)
16032 {
16033 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16034 word |= CONTROL_FLAG_ENABLE_AIPP;
16035 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16036 }
16037
16038 /*
16039 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
16040 * and START_CTL_TH [3:2].
16041 */
16042 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
16043 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
16044
16045 /*
16046 * Microcode operating variables for WDTR, SDTR, and command tag
16047 * queuing will be set in AdvInquiryHandling() based on what a
16048 * device reports it is capable of in Inquiry byte 7.
16049 *
16050 * If SCSI Bus Resets have been disabled, then directly set
16051 * SDTR and WDTR from the EEPROM configuration. This will allow
16052 * the BIOS and warm boot to work without a SCSI bus hang on
16053 * the Inquiry caused by host and target mismatched DTR values.
16054 * Without the SCSI Bus Reset, before an Inquiry a device can't
16055 * be assumed to be in Asynchronous, Narrow mode.
16056 */
16057 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
16058 {
16059 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
16060 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
16061 }
16062
16063 /*
16064 * Set microcode operating variables for DISC and SDTR_SPEED1,
16065 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
16066 * configuration values.
16067 *
16068 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
16069 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
16070 * without determining here whether the device supports SDTR.
16071 */
16072 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
16073 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
16074 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
16075 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
16076 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
16077
16078 /*
16079 * Set SCSI_CFG0 Microcode Default Value.
16080 *
16081 * The microcode will set the SCSI_CFG0 register using this value
16082 * after it is started below.
16083 */
16084 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
16085 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
16086 asc_dvc->chip_scsi_id);
16087
16088 /*
16089 * Calculate SCSI_CFG1 Microcode Default Value.
16090 *
16091 * The microcode will set the SCSI_CFG1 register using this value
16092 * after it is started below.
16093 *
16094 * Each ASC-38C1600 function has only two cable detect bits.
16095 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
16096 */
16097 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
16098
16099 /*
16100 * If the cable is reversed all of the SCSI_CTRL register signals
16101 * will be set. Check for and return an error if this condition is
16102 * found.
16103 */
16104 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
16105 {
16106 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
16107 return ADV_ERROR;
16108 }
16109
16110 /*
16111 * Each ASC-38C1600 function has two connectors. Only an HVD device
16112 * can not be connected to either connector. An LVD device or SE device
16113 * may be connected to either connecor. If an SE device is connected,
16114 * then at most Ultra speed (20 Mhz) can be used on both connectors.
16115 *
16116 * If an HVD device is attached, return an error.
16117 */
16118 if (scsi_cfg1 & HVD)
16119 {
16120 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
16121 return ADV_ERROR;
16122 }
16123
16124 /*
16125 * Each function in the ASC-38C1600 uses only the SE cable detect and
16126 * termination because there are two connectors for each function. Each
16127 * function may use either LVD or SE mode. Corresponding the SE automatic
16128 * termination control EEPROM bits are used for each function. Each
16129 * function has its own EEPROM. If SE automatic control is enabled for
16130 * the function, then set the termination value based on a table listed
16131 * in a_condor.h.
16132 *
16133 * If manual termination is specified in the EEPROM for the function,
16134 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
16135 * ready to be 'ored' into SCSI_CFG1.
16136 */
16137 if ((asc_dvc->cfg->termination & TERM_SE) == 0)
16138 {
16139 /* SE automatic termination control is enabled. */
16140 switch(scsi_cfg1 & C_DET_SE)
16141 {
16142 /* TERM_SE_HI: on, TERM_SE_LO: on */
16143 case 0x1: case 0x2: case 0x3:
16144 asc_dvc->cfg->termination |= TERM_SE;
16145 break;
16146
16147 case 0x0:
16148 if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0)
16149 {
16150 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
16151 }
16152 else
16153 {
16154 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
16155 asc_dvc->cfg->termination |= TERM_SE_HI;
16156 }
16157 break;
16158 }
16159 }
16160
16161 /*
16162 * Clear any set TERM_SE bits.
16163 */
16164 scsi_cfg1 &= ~TERM_SE;
16165
16166 /*
16167 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
16168 */
16169 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
16170
16171 /*
16172 * Clear Big Endian and Terminator Polarity bits and set possibly
16173 * modified termination control bits in the Microcode SCSI_CFG1
16174 * Register Value.
16175 *
16176 * Big Endian bit is not used even on big endian machines.
16177 */
16178 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
16179
16180 /*
16181 * Set SCSI_CFG1 Microcode Default Value
16182 *
16183 * Set possibly modified termination control bits in the Microcode
16184 * SCSI_CFG1 Register Value.
16185 *
16186 * The microcode will set the SCSI_CFG1 register using this value
16187 * after it is started below.
16188 */
16189 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
16190
16191 /*
16192 * Set MEM_CFG Microcode Default Value
16193 *
16194 * The microcode will set the MEM_CFG register using this value
16195 * after it is started below.
16196 *
16197 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
16198 * are defined.
16199 *
16200 * ASC-38C1600 has 32KB internal memory.
16201 *
16202 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
16203 * out a special 16K Adv Library and Microcode version. After the issue
16204 * resolved, we should turn back to the 32K support. Both a_condor.h and
16205 * mcode.sas files also need to be updated.
16206 *
16207 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
16208 * BIOS_EN | RAM_SZ_32KB);
16209 */
16210 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, BIOS_EN | RAM_SZ_16KB);
16211
16212 /*
16213 * Set SEL_MASK Microcode Default Value
16214 *
16215 * The microcode will set the SEL_MASK register using this value
16216 * after it is started below.
16217 */
16218 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
16219 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
16220
16221 /*
16222 * Build the carrier freelist.
16223 *
16224 * Driver must have already allocated memory and set 'carrier_buf'.
16225 */
16226
16227 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
16228
16229 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
16230 asc_dvc->carr_freelist = NULL;
16231 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
16232 {
16233 buf_size = ADV_CARRIER_BUFSIZE;
16234 } else
16235 {
16236 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
16237 }
16238
16239 do {
16240 /*
16241 * Get physical address for the carrier 'carrp'.
16242 */
16243 contig_len = sizeof(ADV_CARR_T);
16244 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
16245 (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
16246
16247 buf_size -= sizeof(ADV_CARR_T);
16248
16249 /*
16250 * If the current carrier is not physically contiguous, then
16251 * maybe there was a page crossing. Try the next carrier aligned
16252 * start address.
16253 */
16254 if (contig_len < sizeof(ADV_CARR_T))
16255 {
16256 carrp++;
16257 continue;
16258 }
16259
16260 carrp->carr_pa = carr_paddr;
16261 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
16262
16263 /*
16264 * Insert the carrier at the beginning of the freelist.
16265 */
16266 carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
16267 asc_dvc->carr_freelist = carrp;
16268
16269 carrp++;
16270 }
16271 while (buf_size > 0);
16272
16273 /*
16274 * Set-up the Host->RISC Initiator Command Queue (ICQ).
16275 */
16276 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
16277 {
16278 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16279 return ADV_ERROR;
16280 }
16281 asc_dvc->carr_freelist = (ADV_CARR_T *)
16282 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
16283
16284 /*
16285 * The first command issued will be placed in the stopper carrier.
16286 */
16287 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16288
16289 /*
16290 * Set RISC ICQ physical address start value. Initialize the
16291 * COMMA register to the same value otherwise the RISC will
16292 * prematurely detect a command is available.
16293 */
16294 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
16295 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
16296 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
16297
16298 /*
16299 * Set-up the RISC->Host Initiator Response Queue (IRQ).
16300 */
16301 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
16302 {
16303 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16304 return ADV_ERROR;
16305 }
16306 asc_dvc->carr_freelist = (ADV_CARR_T *)
16307 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
16308
16309 /*
16310 * The first command completed by the RISC will be placed in
16311 * the stopper.
16312 *
16313 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
16314 * completed the RISC will set the ASC_RQ_STOPPER bit.
16315 */
16316 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16317
16318 /*
16319 * Set RISC IRQ physical address start value.
16320 */
16321 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
16322 asc_dvc->carr_pending_cnt = 0;
16323
16324 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
16325 (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
16326 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
16327 AdvWriteWordRegister(iop_base, IOPW_PC, word);
16328
16329 /* finally, finally, gentlemen, start your engine */
16330 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
16331
16332 /*
16333 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
16334 * Resets should be performed. The RISC has to be running
16335 * to issue a SCSI Bus Reset.
16336 */
16337 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
16338 {
16339 /*
16340 * If the BIOS Signature is present in memory, restore the
16341 * per TID microcode operating variables.
16342 */
16343 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
16344 {
16345 /*
16346 * Restore per TID negotiated values.
16347 */
16348 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16349 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16350 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16351 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16352 for (tid = 0; tid <= ASC_MAX_TID; tid++)
16353 {
16354 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16355 max_cmd[tid]);
16356 }
16357 } else
16358 {
16359 if (AdvResetSB(asc_dvc) != ADV_TRUE)
16360 {
16361 warn_code = ASC_WARN_BUSRESET_ERROR;
16362 }
16363 }
16364 }
16365
16366 return warn_code;
16367}
16368
16369/*
16370 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16371 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16372 * all of this is done.
16373 *
16374 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16375 *
16376 * For a non-fatal error return a warning code. If there are no warnings
16377 * then 0 is returned.
16378 *
16379 * Note: Chip is stopped on entry.
16380 */
16381STATIC int __init
16382AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
16383{
16384 AdvPortAddr iop_base;
16385 ushort warn_code;
16386 ADVEEP_3550_CONFIG eep_config;
16387 int i;
16388
16389 iop_base = asc_dvc->iop_base;
16390
16391 warn_code = 0;
16392
16393 /*
16394 * Read the board's EEPROM configuration.
16395 *
16396 * Set default values if a bad checksum is found.
16397 */
16398 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16399 {
16400 warn_code |= ASC_WARN_EEPROM_CHKSUM;
16401
16402 /*
16403 * Set EEPROM default values.
16404 */
16405 for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++)
16406 {
16407 *((uchar *) &eep_config + i) =
16408 *((uchar *) &Default_3550_EEPROM_Config + i);
16409 }
16410
16411 /*
16412 * Assume the 6 byte board serial number that was read
16413 * from EEPROM is correct even if the EEPROM checksum
16414 * failed.
16415 */
16416 eep_config.serial_number_word3 =
16417 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16418
16419 eep_config.serial_number_word2 =
16420 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16421
16422 eep_config.serial_number_word1 =
16423 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16424
16425 AdvSet3550EEPConfig(iop_base, &eep_config);
16426 }
16427 /*
16428 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16429 * EEPROM configuration that was read.
16430 *
16431 * This is the mapping of EEPROM fields to Adv Library fields.
16432 */
16433 asc_dvc->wdtr_able = eep_config.wdtr_able;
16434 asc_dvc->sdtr_able = eep_config.sdtr_able;
16435 asc_dvc->ultra_able = eep_config.ultra_able;
16436 asc_dvc->tagqng_able = eep_config.tagqng_able;
16437 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16438 asc_dvc->max_host_qng = eep_config.max_host_qng;
16439 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16440 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16441 asc_dvc->start_motor = eep_config.start_motor;
16442 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16443 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16444 asc_dvc->no_scam = eep_config.scam_tolerant;
16445 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16446 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16447 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16448
16449 /*
16450 * Set the host maximum queuing (max. 253, min. 16) and the per device
16451 * maximum queuing (max. 63, min. 4).
16452 */
16453 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
16454 {
16455 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16456 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
16457 {
16458 /* If the value is zero, assume it is uninitialized. */
16459 if (eep_config.max_host_qng == 0)
16460 {
16461 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16462 } else
16463 {
16464 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16465 }
16466 }
16467
16468 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
16469 {
16470 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16471 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
16472 {
16473 /* If the value is zero, assume it is uninitialized. */
16474 if (eep_config.max_dvc_qng == 0)
16475 {
16476 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16477 } else
16478 {
16479 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16480 }
16481 }
16482
16483 /*
16484 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16485 * set 'max_dvc_qng' to 'max_host_qng'.
16486 */
16487 if (eep_config.max_dvc_qng > eep_config.max_host_qng)
16488 {
16489 eep_config.max_dvc_qng = eep_config.max_host_qng;
16490 }
16491
16492 /*
16493 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16494 * values based on possibly adjusted EEPROM values.
16495 */
16496 asc_dvc->max_host_qng = eep_config.max_host_qng;
16497 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16498
16499
16500 /*
16501 * If the EEPROM 'termination' field is set to automatic (0), then set
16502 * the ADV_DVC_CFG 'termination' field to automatic also.
16503 *
16504 * If the termination is specified with a non-zero 'termination'
16505 * value check that a legal value is set and set the ADV_DVC_CFG
16506 * 'termination' field appropriately.
16507 */
16508 if (eep_config.termination == 0)
16509 {
16510 asc_dvc->cfg->termination = 0; /* auto termination */
16511 } else
16512 {
16513 /* Enable manual control with low off / high off. */
16514 if (eep_config.termination == 1)
16515 {
16516 asc_dvc->cfg->termination = TERM_CTL_SEL;
16517
16518 /* Enable manual control with low off / high on. */
16519 } else if (eep_config.termination == 2)
16520 {
16521 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
16522
16523 /* Enable manual control with low on / high on. */
16524 } else if (eep_config.termination == 3)
16525 {
16526 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
16527 } else
16528 {
16529 /*
16530 * The EEPROM 'termination' field contains a bad value. Use
16531 * automatic termination instead.
16532 */
16533 asc_dvc->cfg->termination = 0;
16534 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16535 }
16536 }
16537
16538 return warn_code;
16539}
16540
16541/*
16542 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16543 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16544 * all of this is done.
16545 *
16546 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16547 *
16548 * For a non-fatal error return a warning code. If there are no warnings
16549 * then 0 is returned.
16550 *
16551 * Note: Chip is stopped on entry.
16552 */
16553STATIC int __init
16554AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
16555{
16556 AdvPortAddr iop_base;
16557 ushort warn_code;
16558 ADVEEP_38C0800_CONFIG eep_config;
16559 int i;
16560 uchar tid, termination;
16561 ushort sdtr_speed = 0;
16562
16563 iop_base = asc_dvc->iop_base;
16564
16565 warn_code = 0;
16566
16567 /*
16568 * Read the board's EEPROM configuration.
16569 *
16570 * Set default values if a bad checksum is found.
16571 */
16572 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16573 {
16574 warn_code |= ASC_WARN_EEPROM_CHKSUM;
16575
16576 /*
16577 * Set EEPROM default values.
16578 */
16579 for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++)
16580 {
16581 *((uchar *) &eep_config + i) =
16582 *((uchar *) &Default_38C0800_EEPROM_Config + i);
16583 }
16584
16585 /*
16586 * Assume the 6 byte board serial number that was read
16587 * from EEPROM is correct even if the EEPROM checksum
16588 * failed.
16589 */
16590 eep_config.serial_number_word3 =
16591 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16592
16593 eep_config.serial_number_word2 =
16594 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16595
16596 eep_config.serial_number_word1 =
16597 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16598
16599 AdvSet38C0800EEPConfig(iop_base, &eep_config);
16600 }
16601 /*
16602 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
16603 * EEPROM configuration that was read.
16604 *
16605 * This is the mapping of EEPROM fields to Adv Library fields.
16606 */
16607 asc_dvc->wdtr_able = eep_config.wdtr_able;
16608 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16609 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16610 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16611 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16612 asc_dvc->tagqng_able = eep_config.tagqng_able;
16613 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16614 asc_dvc->max_host_qng = eep_config.max_host_qng;
16615 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16616 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16617 asc_dvc->start_motor = eep_config.start_motor;
16618 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16619 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16620 asc_dvc->no_scam = eep_config.scam_tolerant;
16621 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16622 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16623 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16624
16625 /*
16626 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16627 * are set, then set an 'sdtr_able' bit for it.
16628 */
16629 asc_dvc->sdtr_able = 0;
16630 for (tid = 0; tid <= ADV_MAX_TID; tid++)
16631 {
16632 if (tid == 0)
16633 {
16634 sdtr_speed = asc_dvc->sdtr_speed1;
16635 } else if (tid == 4)
16636 {
16637 sdtr_speed = asc_dvc->sdtr_speed2;
16638 } else if (tid == 8)
16639 {
16640 sdtr_speed = asc_dvc->sdtr_speed3;
16641 } else if (tid == 12)
16642 {
16643 sdtr_speed = asc_dvc->sdtr_speed4;
16644 }
16645 if (sdtr_speed & ADV_MAX_TID)
16646 {
16647 asc_dvc->sdtr_able |= (1 << tid);
16648 }
16649 sdtr_speed >>= 4;
16650 }
16651
16652 /*
16653 * Set the host maximum queuing (max. 253, min. 16) and the per device
16654 * maximum queuing (max. 63, min. 4).
16655 */
16656 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
16657 {
16658 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16659 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
16660 {
16661 /* If the value is zero, assume it is uninitialized. */
16662 if (eep_config.max_host_qng == 0)
16663 {
16664 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16665 } else
16666 {
16667 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16668 }
16669 }
16670
16671 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
16672 {
16673 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16674 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
16675 {
16676 /* If the value is zero, assume it is uninitialized. */
16677 if (eep_config.max_dvc_qng == 0)
16678 {
16679 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16680 } else
16681 {
16682 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16683 }
16684 }
16685
16686 /*
16687 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16688 * set 'max_dvc_qng' to 'max_host_qng'.
16689 */
16690 if (eep_config.max_dvc_qng > eep_config.max_host_qng)
16691 {
16692 eep_config.max_dvc_qng = eep_config.max_host_qng;
16693 }
16694
16695 /*
16696 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16697 * values based on possibly adjusted EEPROM values.
16698 */
16699 asc_dvc->max_host_qng = eep_config.max_host_qng;
16700 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16701
16702 /*
16703 * If the EEPROM 'termination' field is set to automatic (0), then set
16704 * the ADV_DVC_CFG 'termination' field to automatic also.
16705 *
16706 * If the termination is specified with a non-zero 'termination'
16707 * value check that a legal value is set and set the ADV_DVC_CFG
16708 * 'termination' field appropriately.
16709 */
16710 if (eep_config.termination_se == 0)
16711 {
16712 termination = 0; /* auto termination for SE */
16713 } else
16714 {
16715 /* Enable manual control with low off / high off. */
16716 if (eep_config.termination_se == 1)
16717 {
16718 termination = 0;
16719
16720 /* Enable manual control with low off / high on. */
16721 } else if (eep_config.termination_se == 2)
16722 {
16723 termination = TERM_SE_HI;
16724
16725 /* Enable manual control with low on / high on. */
16726 } else if (eep_config.termination_se == 3)
16727 {
16728 termination = TERM_SE;
16729 } else
16730 {
16731 /*
16732 * The EEPROM 'termination_se' field contains a bad value.
16733 * Use automatic termination instead.
16734 */
16735 termination = 0;
16736 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16737 }
16738 }
16739
16740 if (eep_config.termination_lvd == 0)
16741 {
16742 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
16743 } else
16744 {
16745 /* Enable manual control with low off / high off. */
16746 if (eep_config.termination_lvd == 1)
16747 {
16748 asc_dvc->cfg->termination = termination;
16749
16750 /* Enable manual control with low off / high on. */
16751 } else if (eep_config.termination_lvd == 2)
16752 {
16753 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16754
16755 /* Enable manual control with low on / high on. */
16756 } else if (eep_config.termination_lvd == 3)
16757 {
16758 asc_dvc->cfg->termination =
16759 termination | TERM_LVD;
16760 } else
16761 {
16762 /*
16763 * The EEPROM 'termination_lvd' field contains a bad value.
16764 * Use automatic termination instead.
16765 */
16766 asc_dvc->cfg->termination = termination;
16767 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16768 }
16769 }
16770
16771 return warn_code;
16772}
16773
16774/*
16775 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
16776 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
16777 * all of this is done.
16778 *
16779 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
16780 *
16781 * For a non-fatal error return a warning code. If there are no warnings
16782 * then 0 is returned.
16783 *
16784 * Note: Chip is stopped on entry.
16785 */
16786STATIC int __init
16787AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
16788{
16789 AdvPortAddr iop_base;
16790 ushort warn_code;
16791 ADVEEP_38C1600_CONFIG eep_config;
16792 int i;
16793 uchar tid, termination;
16794 ushort sdtr_speed = 0;
16795
16796 iop_base = asc_dvc->iop_base;
16797
16798 warn_code = 0;
16799
16800 /*
16801 * Read the board's EEPROM configuration.
16802 *
16803 * Set default values if a bad checksum is found.
16804 */
16805 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16806 {
16807 warn_code |= ASC_WARN_EEPROM_CHKSUM;
16808
16809 /*
16810 * Set EEPROM default values.
16811 */
16812 for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++)
16813 {
16814 if (i == 1 && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) != 0)
16815 {
16816 /*
16817 * Set Function 1 EEPROM Word 0 MSB
16818 *
16819 * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11)
16820 * EEPROM bits.
16821 *
16822 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and
16823 * old Mac system booting problem. The Expansion ROM must
16824 * be disabled in Function 1 for these systems.
16825 *
16826 */
16827 *((uchar *) &eep_config + i) =
16828 ((*((uchar *) &Default_38C1600_EEPROM_Config + i)) &
16829 (~(((ADV_EEPROM_BIOS_ENABLE | ADV_EEPROM_INTAB) >> 8) &
16830 0xFF)));
16831
16832 /*
16833 * Set the INTAB (bit 11) if the GPIO 0 input indicates
16834 * the Function 1 interrupt line is wired to INTA.
16835 *
16836 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
16837 * 1 - Function 1 interrupt line wired to INT A.
16838 * 0 - Function 1 interrupt line wired to INT B.
16839 *
16840 * Note: Adapter boards always have Function 0 wired to INTA.
16841 * Put all 5 GPIO bits in input mode and then read
16842 * their input values.
16843 */
16844 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
16845 if (AdvReadByteRegister(iop_base, IOPB_GPIO_DATA) & 0x01)
16846 {
16847 /* Function 1 interrupt wired to INTA; Set EEPROM bit. */
16848 *((uchar *) &eep_config + i) |=
16849 ((ADV_EEPROM_INTAB >> 8) & 0xFF);
16850 }
16851 }
16852 else
16853 {
16854 *((uchar *) &eep_config + i) =
16855 *((uchar *) &Default_38C1600_EEPROM_Config + i);
16856 }
16857 }
16858
16859 /*
16860 * Assume the 6 byte board serial number that was read
16861 * from EEPROM is correct even if the EEPROM checksum
16862 * failed.
16863 */
16864 eep_config.serial_number_word3 =
16865 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16866
16867 eep_config.serial_number_word2 =
16868 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16869
16870 eep_config.serial_number_word1 =
16871 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16872
16873 AdvSet38C1600EEPConfig(iop_base, &eep_config);
16874 }
16875
16876 /*
16877 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16878 * EEPROM configuration that was read.
16879 *
16880 * This is the mapping of EEPROM fields to Adv Library fields.
16881 */
16882 asc_dvc->wdtr_able = eep_config.wdtr_able;
16883 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16884 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16885 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16886 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16887 asc_dvc->ppr_able = 0;
16888 asc_dvc->tagqng_able = eep_config.tagqng_able;
16889 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16890 asc_dvc->max_host_qng = eep_config.max_host_qng;
16891 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16892 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
16893 asc_dvc->start_motor = eep_config.start_motor;
16894 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16895 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16896 asc_dvc->no_scam = eep_config.scam_tolerant;
16897
16898 /*
16899 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16900 * are set, then set an 'sdtr_able' bit for it.
16901 */
16902 asc_dvc->sdtr_able = 0;
16903 for (tid = 0; tid <= ASC_MAX_TID; tid++)
16904 {
16905 if (tid == 0)
16906 {
16907 sdtr_speed = asc_dvc->sdtr_speed1;
16908 } else if (tid == 4)
16909 {
16910 sdtr_speed = asc_dvc->sdtr_speed2;
16911 } else if (tid == 8)
16912 {
16913 sdtr_speed = asc_dvc->sdtr_speed3;
16914 } else if (tid == 12)
16915 {
16916 sdtr_speed = asc_dvc->sdtr_speed4;
16917 }
16918 if (sdtr_speed & ASC_MAX_TID)
16919 {
16920 asc_dvc->sdtr_able |= (1 << tid);
16921 }
16922 sdtr_speed >>= 4;
16923 }
16924
16925 /*
16926 * Set the host maximum queuing (max. 253, min. 16) and the per device
16927 * maximum queuing (max. 63, min. 4).
16928 */
16929 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
16930 {
16931 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16932 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
16933 {
16934 /* If the value is zero, assume it is uninitialized. */
16935 if (eep_config.max_host_qng == 0)
16936 {
16937 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16938 } else
16939 {
16940 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16941 }
16942 }
16943
16944 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
16945 {
16946 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16947 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
16948 {
16949 /* If the value is zero, assume it is uninitialized. */
16950 if (eep_config.max_dvc_qng == 0)
16951 {
16952 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16953 } else
16954 {
16955 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16956 }
16957 }
16958
16959 /*
16960 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16961 * set 'max_dvc_qng' to 'max_host_qng'.
16962 */
16963 if (eep_config.max_dvc_qng > eep_config.max_host_qng)
16964 {
16965 eep_config.max_dvc_qng = eep_config.max_host_qng;
16966 }
16967
16968 /*
16969 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
16970 * values based on possibly adjusted EEPROM values.
16971 */
16972 asc_dvc->max_host_qng = eep_config.max_host_qng;
16973 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16974
16975 /*
16976 * If the EEPROM 'termination' field is set to automatic (0), then set
16977 * the ASC_DVC_CFG 'termination' field to automatic also.
16978 *
16979 * If the termination is specified with a non-zero 'termination'
16980 * value check that a legal value is set and set the ASC_DVC_CFG
16981 * 'termination' field appropriately.
16982 */
16983 if (eep_config.termination_se == 0)
16984 {
16985 termination = 0; /* auto termination for SE */
16986 } else
16987 {
16988 /* Enable manual control with low off / high off. */
16989 if (eep_config.termination_se == 1)
16990 {
16991 termination = 0;
16992
16993 /* Enable manual control with low off / high on. */
16994 } else if (eep_config.termination_se == 2)
16995 {
16996 termination = TERM_SE_HI;
16997
16998 /* Enable manual control with low on / high on. */
16999 } else if (eep_config.termination_se == 3)
17000 {
17001 termination = TERM_SE;
17002 } else
17003 {
17004 /*
17005 * The EEPROM 'termination_se' field contains a bad value.
17006 * Use automatic termination instead.
17007 */
17008 termination = 0;
17009 warn_code |= ASC_WARN_EEPROM_TERMINATION;
17010 }
17011 }
17012
17013 if (eep_config.termination_lvd == 0)
17014 {
17015 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
17016 } else
17017 {
17018 /* Enable manual control with low off / high off. */
17019 if (eep_config.termination_lvd == 1)
17020 {
17021 asc_dvc->cfg->termination = termination;
17022
17023 /* Enable manual control with low off / high on. */
17024 } else if (eep_config.termination_lvd == 2)
17025 {
17026 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
17027
17028 /* Enable manual control with low on / high on. */
17029 } else if (eep_config.termination_lvd == 3)
17030 {
17031 asc_dvc->cfg->termination =
17032 termination | TERM_LVD;
17033 } else
17034 {
17035 /*
17036 * The EEPROM 'termination_lvd' field contains a bad value.
17037 * Use automatic termination instead.
17038 */
17039 asc_dvc->cfg->termination = termination;
17040 warn_code |= ASC_WARN_EEPROM_TERMINATION;
17041 }
17042 }
17043
17044 return warn_code;
17045}
17046
17047/*
17048 * Read EEPROM configuration into the specified buffer.
17049 *
17050 * Return a checksum based on the EEPROM configuration read.
17051 */
17052STATIC ushort __init
17053AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
17054{
17055 ushort wval, chksum;
17056 ushort *wbuf;
17057 int eep_addr;
17058 ushort *charfields;
17059
17060 charfields = (ushort *) &ADVEEP_3550_Config_Field_IsChar;
17061 wbuf = (ushort *) cfg_buf;
17062 chksum = 0;
17063
17064 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17065 eep_addr < ADV_EEP_DVC_CFG_END;
17066 eep_addr++, wbuf++)
17067 {
17068 wval = AdvReadEEPWord(iop_base, eep_addr);
17069 chksum += wval; /* Checksum is calculated from word values. */
17070 if (*charfields++) {
17071 *wbuf = le16_to_cpu(wval);
17072 } else {
17073 *wbuf = wval;
17074 }
17075 }
17076 /* Read checksum word. */
17077 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17078 wbuf++; charfields++;
17079
17080 /* Read rest of EEPROM not covered by the checksum. */
17081 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17082 eep_addr < ADV_EEP_MAX_WORD_ADDR;
17083 eep_addr++, wbuf++)
17084 {
17085 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17086 if (*charfields++) {
17087 *wbuf = le16_to_cpu(*wbuf);
17088 }
17089 }
17090 return chksum;
17091}
17092
17093/*
17094 * Read EEPROM configuration into the specified buffer.
17095 *
17096 * Return a checksum based on the EEPROM configuration read.
17097 */
17098STATIC ushort __init
17099AdvGet38C0800EEPConfig(AdvPortAddr iop_base,
17100 ADVEEP_38C0800_CONFIG *cfg_buf)
17101{
17102 ushort wval, chksum;
17103 ushort *wbuf;
17104 int eep_addr;
17105 ushort *charfields;
17106
17107 charfields = (ushort *) &ADVEEP_38C0800_Config_Field_IsChar;
17108 wbuf = (ushort *) cfg_buf;
17109 chksum = 0;
17110
17111 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17112 eep_addr < ADV_EEP_DVC_CFG_END;
17113 eep_addr++, wbuf++)
17114 {
17115 wval = AdvReadEEPWord(iop_base, eep_addr);
17116 chksum += wval; /* Checksum is calculated from word values. */
17117 if (*charfields++) {
17118 *wbuf = le16_to_cpu(wval);
17119 } else {
17120 *wbuf = wval;
17121 }
17122 }
17123 /* Read checksum word. */
17124 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17125 wbuf++; charfields++;
17126
17127 /* Read rest of EEPROM not covered by the checksum. */
17128 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17129 eep_addr < ADV_EEP_MAX_WORD_ADDR;
17130 eep_addr++, wbuf++)
17131 {
17132 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17133 if (*charfields++) {
17134 *wbuf = le16_to_cpu(*wbuf);
17135 }
17136 }
17137 return chksum;
17138}
17139
17140/*
17141 * Read EEPROM configuration into the specified buffer.
17142 *
17143 * Return a checksum based on the EEPROM configuration read.
17144 */
17145STATIC ushort __init
17146AdvGet38C1600EEPConfig(AdvPortAddr iop_base,
17147 ADVEEP_38C1600_CONFIG *cfg_buf)
17148{
17149 ushort wval, chksum;
17150 ushort *wbuf;
17151 int eep_addr;
17152 ushort *charfields;
17153
17154 charfields = (ushort*) &ADVEEP_38C1600_Config_Field_IsChar;
17155 wbuf = (ushort *) cfg_buf;
17156 chksum = 0;
17157
17158 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17159 eep_addr < ADV_EEP_DVC_CFG_END;
17160 eep_addr++, wbuf++)
17161 {
17162 wval = AdvReadEEPWord(iop_base, eep_addr);
17163 chksum += wval; /* Checksum is calculated from word values. */
17164 if (*charfields++) {
17165 *wbuf = le16_to_cpu(wval);
17166 } else {
17167 *wbuf = wval;
17168 }
17169 }
17170 /* Read checksum word. */
17171 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17172 wbuf++; charfields++;
17173
17174 /* Read rest of EEPROM not covered by the checksum. */
17175 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17176 eep_addr < ADV_EEP_MAX_WORD_ADDR;
17177 eep_addr++, wbuf++)
17178 {
17179 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17180 if (*charfields++) {
17181 *wbuf = le16_to_cpu(*wbuf);
17182 }
17183 }
17184 return chksum;
17185}
17186
17187/*
17188 * Read the EEPROM from specified location
17189 */
17190STATIC ushort __init
17191AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
17192{
17193 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
17194 ASC_EEP_CMD_READ | eep_word_addr);
17195 AdvWaitEEPCmd(iop_base);
17196 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
17197}
17198
17199/*
17200 * Wait for EEPROM command to complete
17201 */
17202STATIC void __init
17203AdvWaitEEPCmd(AdvPortAddr iop_base)
17204{
17205 int eep_delay_ms;
17206
17207 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++)
17208 {
17209 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE)
17210 {
17211 break;
17212 }
17213 DvcSleepMilliSecond(1);
17214 }
17215 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == 0)
17216 {
17217 ASC_ASSERT(0);
17218 }
17219 return;
17220}
17221
17222/*
17223 * Write the EEPROM from 'cfg_buf'.
17224 */
c836043e 17225void __init
1da177e4
LT
17226AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
17227{
17228 ushort *wbuf;
17229 ushort addr, chksum;
17230 ushort *charfields;
17231
17232 wbuf = (ushort *) cfg_buf;
17233 charfields = (ushort *) &ADVEEP_3550_Config_Field_IsChar;
17234 chksum = 0;
17235
17236 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17237 AdvWaitEEPCmd(iop_base);
17238
17239 /*
17240 * Write EEPROM from word 0 to word 20.
17241 */
17242 for (addr = ADV_EEP_DVC_CFG_BEGIN;
17243 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17244 {
17245 ushort word;
17246
17247 if (*charfields++) {
17248 word = cpu_to_le16(*wbuf);
17249 } else {
17250 word = *wbuf;
17251 }
17252 chksum += *wbuf; /* Checksum is calculated from word values. */
17253 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17254 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17255 AdvWaitEEPCmd(iop_base);
17256 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17257 }
17258
17259 /*
17260 * Write EEPROM checksum at word 21.
17261 */
17262 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17263 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17264 AdvWaitEEPCmd(iop_base);
17265 wbuf++; charfields++;
17266
17267 /*
17268 * Write EEPROM OEM name at words 22 to 29.
17269 */
17270 for (addr = ADV_EEP_DVC_CTL_BEGIN;
17271 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17272 {
17273 ushort word;
17274
17275 if (*charfields++) {
17276 word = cpu_to_le16(*wbuf);
17277 } else {
17278 word = *wbuf;
17279 }
17280 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17281 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17282 AdvWaitEEPCmd(iop_base);
17283 }
17284 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17285 AdvWaitEEPCmd(iop_base);
17286 return;
17287}
17288
17289/*
17290 * Write the EEPROM from 'cfg_buf'.
17291 */
c836043e 17292void __init
1da177e4
LT
17293AdvSet38C0800EEPConfig(AdvPortAddr iop_base,
17294 ADVEEP_38C0800_CONFIG *cfg_buf)
17295{
17296 ushort *wbuf;
17297 ushort *charfields;
17298 ushort addr, chksum;
17299
17300 wbuf = (ushort *) cfg_buf;
17301 charfields = (ushort *) &ADVEEP_38C0800_Config_Field_IsChar;
17302 chksum = 0;
17303
17304 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17305 AdvWaitEEPCmd(iop_base);
17306
17307 /*
17308 * Write EEPROM from word 0 to word 20.
17309 */
17310 for (addr = ADV_EEP_DVC_CFG_BEGIN;
17311 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17312 {
17313 ushort word;
17314
17315 if (*charfields++) {
17316 word = cpu_to_le16(*wbuf);
17317 } else {
17318 word = *wbuf;
17319 }
17320 chksum += *wbuf; /* Checksum is calculated from word values. */
17321 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17322 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17323 AdvWaitEEPCmd(iop_base);
17324 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17325 }
17326
17327 /*
17328 * Write EEPROM checksum at word 21.
17329 */
17330 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17331 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17332 AdvWaitEEPCmd(iop_base);
17333 wbuf++; charfields++;
17334
17335 /*
17336 * Write EEPROM OEM name at words 22 to 29.
17337 */
17338 for (addr = ADV_EEP_DVC_CTL_BEGIN;
17339 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17340 {
17341 ushort word;
17342
17343 if (*charfields++) {
17344 word = cpu_to_le16(*wbuf);
17345 } else {
17346 word = *wbuf;
17347 }
17348 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17349 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17350 AdvWaitEEPCmd(iop_base);
17351 }
17352 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17353 AdvWaitEEPCmd(iop_base);
17354 return;
17355}
17356
17357/*
17358 * Write the EEPROM from 'cfg_buf'.
17359 */
c836043e 17360void __init
1da177e4
LT
17361AdvSet38C1600EEPConfig(AdvPortAddr iop_base,
17362 ADVEEP_38C1600_CONFIG *cfg_buf)
17363{
17364 ushort *wbuf;
17365 ushort *charfields;
17366 ushort addr, chksum;
17367
17368 wbuf = (ushort *) cfg_buf;
17369 charfields = (ushort *) &ADVEEP_38C1600_Config_Field_IsChar;
17370 chksum = 0;
17371
17372 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17373 AdvWaitEEPCmd(iop_base);
17374
17375 /*
17376 * Write EEPROM from word 0 to word 20.
17377 */
17378 for (addr = ADV_EEP_DVC_CFG_BEGIN;
17379 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17380 {
17381 ushort word;
17382
17383 if (*charfields++) {
17384 word = cpu_to_le16(*wbuf);
17385 } else {
17386 word = *wbuf;
17387 }
17388 chksum += *wbuf; /* Checksum is calculated from word values. */
17389 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17390 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17391 AdvWaitEEPCmd(iop_base);
17392 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17393 }
17394
17395 /*
17396 * Write EEPROM checksum at word 21.
17397 */
17398 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17399 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17400 AdvWaitEEPCmd(iop_base);
17401 wbuf++; charfields++;
17402
17403 /*
17404 * Write EEPROM OEM name at words 22 to 29.
17405 */
17406 for (addr = ADV_EEP_DVC_CTL_BEGIN;
17407 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17408 {
17409 ushort word;
17410
17411 if (*charfields++) {
17412 word = cpu_to_le16(*wbuf);
17413 } else {
17414 word = *wbuf;
17415 }
17416 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17417 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17418 AdvWaitEEPCmd(iop_base);
17419 }
17420 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17421 AdvWaitEEPCmd(iop_base);
17422 return;
17423}
17424
17425/* a_advlib.c */
17426/*
17427 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
17428 *
17429 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
17430 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
17431 * RISC to notify it a new command is ready to be executed.
17432 *
17433 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
17434 * set to SCSI_MAX_RETRY.
17435 *
17436 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
17437 * for DMA addresses or math operations are byte swapped to little-endian
17438 * order.
17439 *
17440 * Return:
17441 * ADV_SUCCESS(1) - The request was successfully queued.
17442 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
17443 * request completes.
17444 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
17445 * host IC error.
17446 */
17447STATIC int
17448AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc,
17449 ADV_SCSI_REQ_Q *scsiq)
17450{
17451 ulong last_int_level;
17452 AdvPortAddr iop_base;
17453 ADV_DCNT req_size;
17454 ADV_PADDR req_paddr;
17455 ADV_CARR_T *new_carrp;
17456
17457 ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
17458
17459 /*
17460 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
17461 */
17462 if (scsiq->target_id > ADV_MAX_TID)
17463 {
17464 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
17465 scsiq->done_status = QD_WITH_ERROR;
17466 return ADV_ERROR;
17467 }
17468
17469 iop_base = asc_dvc->iop_base;
17470
17471 last_int_level = DvcEnterCritical();
17472
17473 /*
17474 * Allocate a carrier ensuring at least one carrier always
17475 * remains on the freelist and initialize fields.
17476 */
17477 if ((new_carrp = asc_dvc->carr_freelist) == NULL)
17478 {
17479 DvcLeaveCritical(last_int_level);
17480 return ADV_BUSY;
17481 }
17482 asc_dvc->carr_freelist = (ADV_CARR_T *)
17483 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
17484 asc_dvc->carr_pending_cnt++;
17485
17486 /*
17487 * Set the carrier to be a stopper by setting 'next_vpa'
17488 * to the stopper value. The current stopper will be changed
17489 * below to point to the new stopper.
17490 */
17491 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
17492
17493 /*
17494 * Clear the ADV_SCSI_REQ_Q done flag.
17495 */
17496 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
17497
17498 req_size = sizeof(ADV_SCSI_REQ_Q);
17499 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *) scsiq,
17500 (ADV_SDCNT *) &req_size, ADV_IS_SCSIQ_FLAG);
17501
17502 ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
17503 ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
17504
17505 /* Wait for assertion before making little-endian */
17506 req_paddr = cpu_to_le32(req_paddr);
17507
17508 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
17509 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
17510 scsiq->scsiq_rptr = req_paddr;
17511
17512 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
17513 /*
17514 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
17515 * order during initialization.
17516 */
17517 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
17518
17519 /*
17520 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
17521 * the microcode. The newly allocated stopper will become the new
17522 * stopper.
17523 */
17524 asc_dvc->icq_sp->areq_vpa = req_paddr;
17525
17526 /*
17527 * Set the 'next_vpa' pointer for the old stopper to be the
17528 * physical address of the new stopper. The RISC can only
17529 * follow physical addresses.
17530 */
17531 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
17532
17533 /*
17534 * Set the host adapter stopper pointer to point to the new carrier.
17535 */
17536 asc_dvc->icq_sp = new_carrp;
17537
17538 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17539 asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
17540 {
17541 /*
17542 * Tickle the RISC to tell it to read its Command Queue Head pointer.
17543 */
17544 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
17545 if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
17546 {
17547 /*
17548 * Clear the tickle value. In the ASC-3550 the RISC flag
17549 * command 'clr_tickle_a' does not work unless the host
17550 * value is cleared.
17551 */
17552 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17553 }
17554 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17555 {
17556 /*
17557 * Notify the RISC a carrier is ready by writing the physical
17558 * address of the new carrier stopper to the COMMA register.
17559 */
17560 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
17561 le32_to_cpu(new_carrp->carr_pa));
17562 }
17563
17564 DvcLeaveCritical(last_int_level);
17565
17566 return ADV_SUCCESS;
17567}
17568
17569/*
17570 * Reset SCSI Bus and purge all outstanding requests.
17571 *
17572 * Return Value:
17573 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
17574 * ADV_FALSE(0) - Microcode command failed.
17575 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
17576 * may be hung which requires driver recovery.
17577 */
17578STATIC int
17579AdvResetSB(ADV_DVC_VAR *asc_dvc)
17580{
17581 int status;
17582
17583 /*
17584 * Send the SCSI Bus Reset idle start idle command which asserts
17585 * the SCSI Bus Reset signal.
17586 */
17587 status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_START, 0L);
17588 if (status != ADV_TRUE)
17589 {
17590 return status;
17591 }
17592
17593 /*
17594 * Delay for the specified SCSI Bus Reset hold time.
17595 *
17596 * The hold time delay is done on the host because the RISC has no
17597 * microsecond accurate timer.
17598 */
17599 DvcDelayMicroSecond(asc_dvc, (ushort) ASC_SCSI_RESET_HOLD_TIME_US);
17600
17601 /*
17602 * Send the SCSI Bus Reset end idle command which de-asserts
17603 * the SCSI Bus Reset signal and purges any pending requests.
17604 */
17605 status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_END, 0L);
17606 if (status != ADV_TRUE)
17607 {
17608 return status;
17609 }
17610
17611 DvcSleepMilliSecond((ADV_DCNT) asc_dvc->scsi_reset_wait * 1000);
17612
17613 return status;
17614}
17615
17616/*
17617 * Reset chip and SCSI Bus.
17618 *
17619 * Return Value:
17620 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
17621 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
17622 */
17623STATIC int
17624AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
17625{
17626 int status;
17627 ushort wdtr_able, sdtr_able, tagqng_able;
17628 ushort ppr_able = 0;
17629 uchar tid, max_cmd[ADV_MAX_TID + 1];
17630 AdvPortAddr iop_base;
17631 ushort bios_sig;
17632
17633 iop_base = asc_dvc->iop_base;
17634
17635 /*
17636 * Save current per TID negotiated values.
17637 */
17638 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17639 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17640 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17641 {
17642 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17643 }
17644 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17645 for (tid = 0; tid <= ADV_MAX_TID; tid++)
17646 {
17647 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17648 max_cmd[tid]);
17649 }
17650
17651 /*
17652 * Force the AdvInitAsc3550/38C0800Driver() function to
17653 * perform a SCSI Bus Reset by clearing the BIOS signature word.
17654 * The initialization functions assumes a SCSI Bus Reset is not
17655 * needed if the BIOS signature word is present.
17656 */
17657 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17658 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
17659
17660 /*
17661 * Stop chip and reset it.
17662 */
17663 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
17664 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
17665 DvcSleepMilliSecond(100);
17666 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG);
17667
17668 /*
17669 * Reset Adv Library error code, if any, and try
17670 * re-initializing the chip.
17671 */
17672 asc_dvc->err_code = 0;
17673 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17674 {
17675 status = AdvInitAsc38C1600Driver(asc_dvc);
17676 }
17677 else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
17678 {
17679 status = AdvInitAsc38C0800Driver(asc_dvc);
17680 } else
17681 {
17682 status = AdvInitAsc3550Driver(asc_dvc);
17683 }
17684
17685 /* Translate initialization return value to status value. */
17686 if (status == 0)
17687 {
17688 status = ADV_TRUE;
17689 } else
17690 {
17691 status = ADV_FALSE;
17692 }
17693
17694 /*
17695 * Restore the BIOS signature word.
17696 */
17697 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17698
17699 /*
17700 * Restore per TID negotiated values.
17701 */
17702 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17703 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17704 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17705 {
17706 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17707 }
17708 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17709 for (tid = 0; tid <= ADV_MAX_TID; tid++)
17710 {
17711 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17712 max_cmd[tid]);
17713 }
17714
17715 return status;
17716}
17717
17718/*
17719 * Adv Library Interrupt Service Routine
17720 *
17721 * This function is called by a driver's interrupt service routine.
17722 * The function disables and re-enables interrupts.
17723 *
17724 * When a microcode idle command is completed, the ADV_DVC_VAR
17725 * 'idle_cmd_done' field is set to ADV_TRUE.
17726 *
17727 * Note: AdvISR() can be called when interrupts are disabled or even
17728 * when there is no hardware interrupt condition present. It will
17729 * always check for completed idle commands and microcode requests.
17730 * This is an important feature that shouldn't be changed because it
17731 * allows commands to be completed from polling mode loops.
17732 *
17733 * Return:
17734 * ADV_TRUE(1) - interrupt was pending
17735 * ADV_FALSE(0) - no interrupt was pending
17736 */
17737STATIC int
17738AdvISR(ADV_DVC_VAR *asc_dvc)
17739{
17740 AdvPortAddr iop_base;
17741 uchar int_stat;
17742 ushort target_bit;
17743 ADV_CARR_T *free_carrp;
17744 ADV_VADDR irq_next_vpa;
17745 int flags;
17746 ADV_SCSI_REQ_Q *scsiq;
17747
17748 flags = DvcEnterCritical();
17749
17750 iop_base = asc_dvc->iop_base;
17751
17752 /* Reading the register clears the interrupt. */
17753 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
17754
17755 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
17756 ADV_INTR_STATUS_INTRC)) == 0)
17757 {
17758 DvcLeaveCritical(flags);
17759 return ADV_FALSE;
17760 }
17761
17762 /*
17763 * Notify the driver of an asynchronous microcode condition by
17764 * calling the ADV_DVC_VAR.async_callback function. The function
17765 * is passed the microcode ASC_MC_INTRB_CODE byte value.
17766 */
17767 if (int_stat & ADV_INTR_STATUS_INTRB)
17768 {
17769 uchar intrb_code;
17770
17771 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
17772
17773 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17774 asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
17775 {
17776 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
17777 asc_dvc->carr_pending_cnt != 0)
17778 {
17779 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
17780 if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
17781 {
17782 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17783 }
17784 }
17785 }
17786
17787 if (asc_dvc->async_callback != 0)
17788 {
17789 (*asc_dvc->async_callback)(asc_dvc, intrb_code);
17790 }
17791 }
17792
17793 /*
17794 * Check if the IRQ stopper carrier contains a completed request.
17795 */
17796 while (((irq_next_vpa =
17797 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0)
17798 {
17799 /*
17800 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
17801 * The RISC will have set 'areq_vpa' to a virtual address.
17802 *
17803 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
17804 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
17805 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
17806 * in AdvExeScsiQueue().
17807 */
17808 scsiq = (ADV_SCSI_REQ_Q *)
17809 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
17810
17811 /*
17812 * Request finished with good status and the queue was not
17813 * DMAed to host memory by the firmware. Set all status fields
17814 * to indicate good status.
17815 */
17816 if ((irq_next_vpa & ASC_RQ_GOOD) != 0)
17817 {
17818 scsiq->done_status = QD_NO_ERROR;
17819 scsiq->host_status = scsiq->scsi_status = 0;
17820 scsiq->data_cnt = 0L;
17821 }
17822
17823 /*
17824 * Advance the stopper pointer to the next carrier
17825 * ignoring the lower four bits. Free the previous
17826 * stopper carrier.
17827 */
17828 free_carrp = asc_dvc->irq_sp;
17829 asc_dvc->irq_sp = (ADV_CARR_T *)
17830 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
17831
17832 free_carrp->next_vpa =
17833 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
17834 asc_dvc->carr_freelist = free_carrp;
17835 asc_dvc->carr_pending_cnt--;
17836
17837 ASC_ASSERT(scsiq != NULL);
17838 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
17839
17840 /*
17841 * Clear request microcode control flag.
17842 */
17843 scsiq->cntl = 0;
17844
17845 /*
17846 * If the command that completed was a SCSI INQUIRY and
17847 * LUN 0 was sent the command, then process the INQUIRY
17848 * command information for the device.
17849 *
17850 * Note: If data returned were either VPD or CmdDt data,
17851 * don't process the INQUIRY command information for
17852 * the device, otherwise may erroneously set *_able bits.
17853 */
17854 if (scsiq->done_status == QD_NO_ERROR &&
17855 scsiq->cdb[0] == INQUIRY &&
17856 scsiq->target_lun == 0 &&
17857 (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
17858 == ADV_INQ_RTN_STD_INQUIRY_DATA)
17859 {
17860 AdvInquiryHandling(asc_dvc, scsiq);
17861 }
17862
17863 /*
17864 * Notify the driver of the completed request by passing
17865 * the ADV_SCSI_REQ_Q pointer to its callback function.
17866 */
17867 scsiq->a_flag |= ADV_SCSIQ_DONE;
17868 (*asc_dvc->isr_callback)(asc_dvc, scsiq);
17869 /*
17870 * Note: After the driver callback function is called, 'scsiq'
17871 * can no longer be referenced.
17872 *
17873 * Fall through and continue processing other completed
17874 * requests...
17875 */
17876
17877 /*
17878 * Disable interrupts again in case the driver inadvertently
17879 * enabled interrupts in its callback function.
17880 *
17881 * The DvcEnterCritical() return value is ignored, because
17882 * the 'flags' saved when AdvISR() was first entered will be
17883 * used to restore the interrupt flag on exit.
17884 */
17885 (void) DvcEnterCritical();
17886 }
17887 DvcLeaveCritical(flags);
17888 return ADV_TRUE;
17889}
17890
17891/*
17892 * Send an idle command to the chip and wait for completion.
17893 *
17894 * Command completion is polled for once per microsecond.
17895 *
17896 * The function can be called from anywhere including an interrupt handler.
17897 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
17898 * functions to prevent reentrancy.
17899 *
17900 * Return Values:
17901 * ADV_TRUE - command completed successfully
17902 * ADV_FALSE - command failed
17903 * ADV_ERROR - command timed out
17904 */
17905STATIC int
17906AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
17907 ushort idle_cmd,
17908 ADV_DCNT idle_cmd_parameter)
17909{
17910 ulong last_int_level;
17911 int result;
17912 ADV_DCNT i, j;
17913 AdvPortAddr iop_base;
17914
17915 last_int_level = DvcEnterCritical();
17916
17917 iop_base = asc_dvc->iop_base;
17918
17919 /*
17920 * Clear the idle command status which is set by the microcode
17921 * to a non-zero value to indicate when the command is completed.
17922 * The non-zero result is one of the IDLE_CMD_STATUS_* values
17923 * defined in a_advlib.h.
17924 */
17925 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort) 0);
17926
17927 /*
17928 * Write the idle command value after the idle command parameter
17929 * has been written to avoid a race condition. If the order is not
17930 * followed, the microcode may process the idle command before the
17931 * parameters have been written to LRAM.
17932 */
17933 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
17934 cpu_to_le32(idle_cmd_parameter));
17935 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
17936
17937 /*
17938 * Tickle the RISC to tell it to process the idle command.
17939 */
17940 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
17941 if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
17942 {
17943 /*
17944 * Clear the tickle value. In the ASC-3550 the RISC flag
17945 * command 'clr_tickle_b' does not work unless the host
17946 * value is cleared.
17947 */
17948 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17949 }
17950
17951 /* Wait for up to 100 millisecond for the idle command to timeout. */
17952 for (i = 0; i < SCSI_WAIT_100_MSEC; i++)
17953 {
17954 /* Poll once each microsecond for command completion. */
17955 for (j = 0; j < SCSI_US_PER_MSEC; j++)
17956 {
17957 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, result);
17958 if (result != 0)
17959 {
17960 DvcLeaveCritical(last_int_level);
17961 return result;
17962 }
17963 DvcDelayMicroSecond(asc_dvc, (ushort) 1);
17964 }
17965 }
17966
17967 ASC_ASSERT(0); /* The idle command should never timeout. */
17968 DvcLeaveCritical(last_int_level);
17969 return ADV_ERROR;
17970}
17971
17972/*
17973 * Inquiry Information Byte 7 Handling
17974 *
17975 * Handle SCSI Inquiry Command information for a device by setting
17976 * microcode operating variables that affect WDTR, SDTR, and Tag
17977 * Queuing.
17978 */
17979STATIC void
17980AdvInquiryHandling(
17981 ADV_DVC_VAR *asc_dvc,
17982 ADV_SCSI_REQ_Q *scsiq)
17983{
17984 AdvPortAddr iop_base;
17985 uchar tid;
17986 ADV_SCSI_INQUIRY *inq;
17987 ushort tidmask;
17988 ushort cfg_word;
17989
17990 /*
17991 * AdvInquiryHandling() requires up to INQUIRY information Byte 7
17992 * to be available.
17993 *
17994 * If less than 8 bytes of INQUIRY information were requested or less
17995 * than 8 bytes were transferred, then return. cdb[4] is the request
17996 * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
17997 * microcode to the transfer residual count.
17998 */
17999
18000 if (scsiq->cdb[4] < 8 ||
18001 (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8)
18002 {
18003 return;
18004 }
18005
18006 iop_base = asc_dvc->iop_base;
18007 tid = scsiq->target_id;
18008
18009 inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr;
18010
18011 /*
18012 * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
18013 */
18014 if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2)
18015 {
18016 return;
18017 } else
18018 {
18019 /*
18020 * INQUIRY Byte 7 Handling
18021 *
18022 * Use a device's INQUIRY byte 7 to determine whether it
18023 * supports WDTR, SDTR, and Tag Queuing. If the feature
18024 * is enabled in the EEPROM and the device supports the
18025 * feature, then enable it in the microcode.
18026 */
18027
18028 tidmask = ADV_TID_TO_TIDMASK(tid);
18029
18030 /*
18031 * Wide Transfers
18032 *
18033 * If the EEPROM enabled WDTR for the device and the device
18034 * supports wide bus (16 bit) transfers, then turn on the
18035 * device's 'wdtr_able' bit and write the new value to the
18036 * microcode.
18037 */
18038 if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq))
18039 {
18040 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
18041 if ((cfg_word & tidmask) == 0)
18042 {
18043 cfg_word |= tidmask;
18044 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
18045
18046 /*
18047 * Clear the microcode "SDTR negotiation" and "WDTR
18048 * negotiation" done indicators for the target to cause
18049 * it to negotiate with the new setting set above.
18050 * WDTR when accepted causes the target to enter
18051 * asynchronous mode, so SDTR must be negotiated.
18052 */
18053 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18054 cfg_word &= ~tidmask;
18055 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18056 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
18057 cfg_word &= ~tidmask;
18058 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
18059 }
18060 }
18061
18062 /*
18063 * Synchronous Transfers
18064 *
18065 * If the EEPROM enabled SDTR for the device and the device
18066 * supports synchronous transfers, then turn on the device's
18067 * 'sdtr_able' bit. Write the new value to the microcode.
18068 */
18069 if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq))
18070 {
18071 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
18072 if ((cfg_word & tidmask) == 0)
18073 {
18074 cfg_word |= tidmask;
18075 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
18076
18077 /*
18078 * Clear the microcode "SDTR negotiation" done indicator
18079 * for the target to cause it to negotiate with the new
18080 * setting set above.
18081 */
18082 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18083 cfg_word &= ~tidmask;
18084 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18085 }
18086 }
18087 /*
18088 * If the Inquiry data included enough space for the SPI-3
18089 * Clocking field, then check if DT mode is supported.
18090 */
18091 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 &&
18092 (scsiq->cdb[4] >= 57 ||
18093 (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57))
18094 {
18095 /*
18096 * PPR (Parallel Protocol Request) Capable
18097 *
18098 * If the device supports DT mode, then it must be PPR capable.
18099 * The PPR message will be used in place of the SDTR and WDTR
18100 * messages to negotiate synchronous speed and offset, transfer
18101 * width, and protocol options.
18102 */
18103 if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY)
18104 {
18105 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, asc_dvc->ppr_able);
18106 asc_dvc->ppr_able |= tidmask;
18107 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, asc_dvc->ppr_able);
18108 }
18109 }
18110
18111 /*
18112 * If the EEPROM enabled Tag Queuing for the device and the
18113 * device supports Tag Queueing, then turn on the device's
18114 * 'tagqng_enable' bit in the microcode and set the microcode
18115 * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
18116 * value.
18117 *
18118 * Tag Queuing is disabled for the BIOS which runs in polled
18119 * mode and would see no benefit from Tag Queuing. Also by
18120 * disabling Tag Queuing in the BIOS devices with Tag Queuing
18121 * bugs will at least work with the BIOS.
18122 */
18123 if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq))
18124 {
18125 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
18126 cfg_word |= tidmask;
18127 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
18128
18129 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
18130 asc_dvc->max_dvc_qng);
18131 }
18132 }
18133}
18134MODULE_LICENSE("Dual BSD/GPL");
2672ea86 18135
d8dafd8c 18136#ifdef CONFIG_PCI
2672ea86
DJ
18137/* PCI Devices supported by this driver */
18138static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
18139 { PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
18140 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18141 { PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
18142 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18143 { PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
18144 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18145 { PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
18146 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18147 { PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
18148 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18149 { PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
18150 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18151 { }
18152};
18153MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
d8dafd8c 18154#endif /* CONFIG_PCI */