[SCSI] advansys: delete AscGetChipBusType
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / scsi / advansys.c
1 #define ASC_VERSION "3.4" /* 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 * Copyright (c) 2007 Matthew Wilcox <matthew@wil.cx>
9 * All Rights Reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17 /*
18 * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
19 * changed its name to ConnectCom Solutions, Inc.
20 * On June 18, 2001 Initio Corp. acquired ConnectCom's SCSI assets
21 */
22
23 /*
24
25 Documentation for the AdvanSys Driver
26
27 A. Linux Kernels Supported by this Driver
28 B. Adapters Supported by this Driver
29 C. Linux source files modified by AdvanSys Driver
30 D. Source Comments
31 E. Driver Compile Time Options and Debugging
32 F. Driver LILO Option
33 G. Tests to run before releasing new driver
34 H. Release History
35 I. Known Problems/Fix List
36 J. Credits (Chronological Order)
37
38 A. Linux Kernels Supported by this Driver
39
40 This driver has been tested in the following Linux kernels: v2.2.18
41 v2.4.0. The driver is supported on v2.2 and v2.4 kernels and on x86,
42 alpha, and PowerPC platforms.
43
44 B. Adapters Supported by this Driver
45
46 AdvanSys (Advanced System Products, Inc.) manufactures the following
47 RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow
48 (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI
49 buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit
50 transfer) SCSI Host Adapters for the PCI bus.
51
52 The CDB counts below indicate the number of SCSI CDB (Command
53 Descriptor Block) requests that can be stored in the RISC chip
54 cache and board LRAM. A CDB is a single SCSI command. The driver
55 detect routine will display the number of CDBs available for each
56 adapter detected. The number of CDBs used by the driver can be
57 lowered in the BIOS by changing the 'Host Queue Size' adapter setting.
58
59 Laptop Products:
60 ABP-480 - Bus-Master CardBus (16 CDB) (2.4 kernel and greater)
61
62 Connectivity Products:
63 ABP510/5150 - Bus-Master ISA (240 CDB)
64 ABP5140 - Bus-Master ISA PnP (16 CDB)
65 ABP5142 - Bus-Master ISA PnP with floppy (16 CDB)
66 ABP902/3902 - Bus-Master PCI (16 CDB)
67 ABP3905 - Bus-Master PCI (16 CDB)
68 ABP915 - Bus-Master PCI (16 CDB)
69 ABP920 - Bus-Master PCI (16 CDB)
70 ABP3922 - Bus-Master PCI (16 CDB)
71 ABP3925 - Bus-Master PCI (16 CDB)
72 ABP930 - Bus-Master PCI (16 CDB)
73 ABP930U - Bus-Master PCI Ultra (16 CDB)
74 ABP930UA - Bus-Master PCI Ultra (16 CDB)
75 ABP960 - Bus-Master PCI MAC/PC (16 CDB)
76 ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
77
78 Single Channel Products:
79 ABP542 - Bus-Master ISA with floppy (240 CDB)
80 ABP742 - Bus-Master EISA (240 CDB)
81 ABP842 - Bus-Master VL (240 CDB)
82 ABP940 - Bus-Master PCI (240 CDB)
83 ABP940U - Bus-Master PCI Ultra (240 CDB)
84 ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB)
85 ABP970 - Bus-Master PCI MAC/PC (240 CDB)
86 ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
87 ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB)
88 ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB)
89 ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB)
90 ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB)
91
92 Multi-Channel Products:
93 ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
94 ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
95 ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
96 ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel)
97 ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
98 ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
99 ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.)
100 ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB)
101 ABP3950U3W - Bus-Master PCI Dual LVD2/Ultra3-Wide (253 CDB)
102
103 C. Linux source files modified by AdvanSys Driver
104
105 This section for historical purposes documents the changes
106 originally made to the Linux kernel source to add the advansys
107 driver. As Linux has changed some of these files have also
108 been modified.
109
110 1. linux/arch/i386/config.in:
111
112 bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
113
114 2. linux/drivers/scsi/hosts.c:
115
116 #ifdef CONFIG_SCSI_ADVANSYS
117 #include "advansys.h"
118 #endif
119
120 and after "static struct scsi_host_template builtin_scsi_hosts[] =":
121
122 #ifdef CONFIG_SCSI_ADVANSYS
123 ADVANSYS,
124 #endif
125
126 3. linux/drivers/scsi/Makefile:
127
128 ifdef CONFIG_SCSI_ADVANSYS
129 SCSI_SRCS := $(SCSI_SRCS) advansys.c
130 SCSI_OBJS := $(SCSI_OBJS) advansys.o
131 else
132 SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
133 endif
134
135 4. linux/init/main.c:
136
137 extern void advansys_setup(char *str, int *ints);
138
139 and add the following lines to the bootsetups[] array.
140
141 #ifdef CONFIG_SCSI_ADVANSYS
142 { "advansys=", advansys_setup },
143 #endif
144
145 D. Source Comments
146
147 1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
148
149 2. This driver should be maintained in multiple files. But to make
150 it easier to include with Linux and to follow Linux conventions,
151 the whole driver is maintained in the source files advansys.h and
152 advansys.c. In this file logical sections of the driver begin with
153 a comment that contains '---'. The following are the logical sections
154 of the driver below.
155
156 --- Linux Version
157 --- Linux Include File
158 --- Driver Options
159 --- Debugging Header
160 --- Asc Library Constants and Macros
161 --- Adv Library Constants and Macros
162 --- Driver Constants and Macros
163 --- Driver Structures
164 --- Driver Data
165 --- Driver Function Prototypes
166 --- Linux 'struct scsi_host_template' and advansys_setup() Functions
167 --- Loadable Driver Support
168 --- Miscellaneous Driver Functions
169 --- Functions Required by the Asc Library
170 --- Functions Required by the Adv Library
171 --- Tracing and Debugging Functions
172 --- Asc Library Functions
173 --- Adv Library Functions
174
175 3. The string 'XXX' is used to flag code that needs to be re-written
176 or that contains a problem that needs to be addressed.
177
178 4. I have stripped comments from and reformatted the source for the
179 Asc Library and Adv Library to reduce the size of this file. This
180 source can be found under the following headings. The Asc Library
181 is used to support Narrow Boards. The Adv Library is used to
182 support Wide Boards.
183
184 --- Asc Library Constants and Macros
185 --- Adv Library Constants and Macros
186 --- Asc Library Functions
187 --- Adv Library Functions
188
189 E. Driver Compile Time Options and Debugging
190
191 In this source file the following constants can be defined. They are
192 defined in the source below. Both of these options are enabled by
193 default.
194
195 1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled)
196
197 Enabling this option adds assertion logic statements to the
198 driver. If an assertion fails a message will be displayed to
199 the console, but the system will continue to operate. Any
200 assertions encountered should be reported to the person
201 responsible for the driver. Assertion statements may proactively
202 detect problems with the driver and facilitate fixing these
203 problems. Enabling assertions will add a small overhead to the
204 execution of the driver.
205
206 2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled)
207
208 Enabling this option adds tracing functions to the driver and
209 the ability to set a driver tracing level at boot time. This
210 option will also export symbols not required outside the driver to
211 the kernel name space. This option is very useful for debugging
212 the driver, but it will add to the size of the driver execution
213 image and add overhead to the execution of the driver.
214
215 The amount of debugging output can be controlled with the global
216 variable 'asc_dbglvl'. The higher the number the more output. By
217 default the debug level is 0.
218
219 If the driver is loaded at boot time and the LILO Driver Option
220 is included in the system, the debug level can be changed by
221 specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
222 first three hex digits of the pseudo I/O Port must be set to
223 'deb' and the fourth hex digit specifies the debug level: 0 - F.
224 The following command line will look for an adapter at 0x330
225 and set the debug level to 2.
226
227 linux advansys=0x330,0,0,0,0xdeb2
228
229 If the driver is built as a loadable module this variable can be
230 defined when the driver is loaded. The following insmod command
231 will set the debug level to one.
232
233 insmod advansys.o asc_dbglvl=1
234
235 Debugging Message Levels:
236 0: Errors Only
237 1: High-Level Tracing
238 2-N: Verbose Tracing
239
240 To enable debug output to console, please make sure that:
241
242 a. System and kernel logging is enabled (syslogd, klogd running).
243 b. Kernel messages are routed to console output. Check
244 /etc/syslog.conf for an entry similar to this:
245
246 kern.* /dev/console
247
248 c. klogd is started with the appropriate -c parameter
249 (e.g. klogd -c 8)
250
251 This will cause printk() messages to be be displayed on the
252 current console. Refer to the klogd(8) and syslogd(8) man pages
253 for details.
254
255 Alternatively you can enable printk() to console with this
256 program. However, this is not the 'official' way to do this.
257 Debug output is logged in /var/log/messages.
258
259 main()
260 {
261 syscall(103, 7, 0, 0);
262 }
263
264 Increasing LOG_BUF_LEN in kernel/printk.c to something like
265 40960 allows more debug messages to be buffered in the kernel
266 and written to the console or log file.
267
268 3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0)
269
270 Enabling this option adds statistics collection and display
271 through /proc to the driver. The information is useful for
272 monitoring driver and device performance. It will add to the
273 size of the driver execution image and add minor overhead to
274 the execution of the driver.
275
276 Statistics are maintained on a per adapter basis. Driver entry
277 point call counts and transfer size counts are maintained.
278 Statistics are only available for kernels greater than or equal
279 to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured.
280
281 AdvanSys SCSI adapter files have the following path name format:
282
283 /proc/scsi/advansys/{0,1,2,3,...}
284
285 This information can be displayed with cat. For example:
286
287 cat /proc/scsi/advansys/0
288
289 When ADVANSYS_STATS is not defined the AdvanSys /proc files only
290 contain adapter and device configuration information.
291
292 F. Driver LILO Option
293
294 If init/main.c is modified as described in the 'Directions for Adding
295 the AdvanSys Driver to Linux' section (B.4.) above, the driver will
296 recognize the 'advansys' LILO command line and /etc/lilo.conf option.
297 This option can be used to either disable I/O port scanning or to limit
298 scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
299 PCI boards will still be searched for and detected. This option only
300 affects searching for ISA and VL boards.
301
302 Examples:
303 1. Eliminate I/O port scanning:
304 boot: linux advansys=
305 or
306 boot: linux advansys=0x0
307 2. Limit I/O port scanning to one I/O port:
308 boot: linux advansys=0x110
309 3. Limit I/O port scanning to four I/O ports:
310 boot: linux advansys=0x110,0x210,0x230,0x330
311
312 For a loadable module the same effect can be achieved by setting
313 the 'asc_iopflag' variable and 'asc_ioport' array when loading
314 the driver, e.g.
315
316 insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
317
318 If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1)
319 I/O Port may be added to specify the driver debug level. Refer to
320 the 'Driver Compile Time Options and Debugging' section above for
321 more information.
322
323 G. Tests to run before releasing new driver
324
325 1. In the supported kernels verify there are no warning or compile
326 errors when the kernel is built as both a driver and as a module
327 and with the following options:
328
329 ADVANSYS_DEBUG - enabled and disabled
330 CONFIG_SMP - enabled and disabled
331 CONFIG_PROC_FS - enabled and disabled
332
333 2. Run tests on an x86, alpha, and PowerPC with at least one narrow
334 card and one wide card attached to a hard disk and CD-ROM drive:
335 fdisk, mkfs, fsck, bonnie, copy/compare test from the
336 CD-ROM to the hard drive.
337
338 H. Release History
339
340 BETA-1.0 (12/23/95):
341 First Release
342
343 BETA-1.1 (12/28/95):
344 1. Prevent advansys_detect() from being called twice.
345 2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
346
347 1.2 (1/12/96):
348 1. Prevent re-entrancy in the interrupt handler which
349 resulted in the driver hanging Linux.
350 2. Fix problem that prevented ABP-940 cards from being
351 recognized on some PCI motherboards.
352 3. Add support for the ABP-5140 PnP ISA card.
353 4. Fix check condition return status.
354 5. Add conditionally compiled code for Linux v1.3.X.
355
356 1.3 (2/23/96):
357 1. Fix problem in advansys_biosparam() that resulted in the
358 wrong drive geometry being returned for drives > 1GB with
359 extended translation enabled.
360 2. Add additional tracing during device initialization.
361 3. Change code that only applies to ISA PnP adapter.
362 4. Eliminate 'make dep' warning.
363 5. Try to fix problem with handling resets by increasing their
364 timeout value.
365
366 1.4 (5/8/96):
367 1. Change definitions to eliminate conflicts with other subsystems.
368 2. Add versioning code for the shared interrupt changes.
369 3. Eliminate problem in asc_rmqueue() with iterating after removing
370 a request.
371 4. Remove reset request loop problem from the "Known Problems or
372 Issues" section. This problem was isolated and fixed in the
373 mid-level SCSI driver.
374
375 1.5 (8/8/96):
376 1. Add support for ABP-940U (PCI Ultra) adapter.
377 2. Add support for IRQ sharing by setting the IRQF_SHARED flag for
378 request_irq and supplying a dev_id pointer to both request_irq()
379 and free_irq().
380 3. In AscSearchIOPortAddr11() restore a call to check_region() which
381 should be used before I/O port probing.
382 4. Fix bug in asc_prt_hex() which resulted in the displaying
383 the wrong data.
384 5. Incorporate miscellaneous Asc Library bug fixes and new microcode.
385 6. Change driver versioning to be specific to each Linux sub-level.
386 7. Change statistics gathering to be per adapter instead of global
387 to the driver.
388 8. Add more information and statistics to the adapter /proc file:
389 /proc/scsi/advansys[0...].
390 9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list.
391 This problem has been addressed with the SCSI mid-level changes
392 made in v1.3.89. The advansys_select_queue_depths() function
393 was added for the v1.3.89 changes.
394
395 1.6 (9/10/96):
396 1. Incorporate miscellaneous Asc Library bug fixes and new microcode.
397
398 1.7 (9/25/96):
399 1. Enable clustering and optimize the setting of the maximum number
400 of scatter gather elements for any particular board. Clustering
401 increases CPU utilization, but results in a relatively larger
402 increase in I/O throughput.
403 2. Improve the performance of the request queuing functions by
404 adding a last pointer to the queue structure.
405 3. Correct problems with reset and abort request handling that
406 could have hung or crashed Linux.
407 4. Add more information to the adapter /proc file:
408 /proc/scsi/advansys[0...].
409 5. Remove the request timeout issue form the driver issues list.
410 6. Miscellaneous documentation additions and changes.
411
412 1.8 (10/4/96):
413 1. Make changes to handle the new v2.1.0 kernel memory mapping
414 in which a kernel virtual address may not be equivalent to its
415 bus or DMA memory address.
416 2. Change abort and reset request handling to make it yet even
417 more robust.
418 3. Try to mitigate request starvation by sending ordered requests
419 to heavily loaded, tag queuing enabled devices.
420 4. Maintain statistics on request response time.
421 5. Add request response time statistics and other information to
422 the adapter /proc file: /proc/scsi/advansys[0...].
423
424 1.9 (10/21/96):
425 1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to
426 make use of mid-level SCSI driver device queue depth flow
427 control mechanism. This will eliminate aborts caused by a
428 device being unable to keep up with requests and eliminate
429 repeat busy or QUEUE FULL status returned by a device.
430 2. Incorporate miscellaneous Asc Library bug fixes.
431 3. To allow the driver to work in kernels with broken module
432 support set 'cmd_per_lun' if the driver is compiled as a
433 module. This change affects kernels v1.3.89 to present.
434 4. Remove PCI BIOS address from the driver banner. The PCI BIOS
435 is relocated by the motherboard BIOS and its new address can
436 not be determined by the driver.
437 5. Add mid-level SCSI queue depth information to the adapter
438 /proc file: /proc/scsi/advansys[0...].
439
440 2.0 (11/14/96):
441 1. Change allocation of global structures used for device
442 initialization to guarantee they are in DMA-able memory.
443 Previously when the driver was loaded as a module these
444 structures might not have been in DMA-able memory, causing
445 device initialization to fail.
446
447 2.1 (12/30/96):
448 1. In advansys_reset(), if the request is a synchronous reset
449 request, even if the request serial number has changed, then
450 complete the request.
451 2. Add Asc Library bug fixes including new microcode.
452 3. Clear inquiry buffer before using it.
453 4. Correct ifdef typo.
454
455 2.2 (1/15/97):
456 1. Add Asc Library bug fixes including new microcode.
457 2. Add synchronous data transfer rate information to the
458 adapter /proc file: /proc/scsi/advansys[0...].
459 3. Change ADVANSYS_DEBUG to be disabled by default. This
460 will reduce the size of the driver image, eliminate execution
461 overhead, and remove unneeded symbols from the kernel symbol
462 space that were previously added by the driver.
463 4. Add new compile-time option ADVANSYS_ASSERT for assertion
464 code that used to be defined within ADVANSYS_DEBUG. This
465 option is enabled by default.
466
467 2.8 (5/26/97):
468 1. Change version number to 2.8 to synchronize the Linux driver
469 version numbering with other AdvanSys drivers.
470 2. Reformat source files without tabs to present the same view
471 of the file to everyone regardless of the editor tab setting
472 being used.
473 3. Add Asc Library bug fixes.
474
475 3.1A (1/8/98):
476 1. Change version number to 3.1 to indicate that support for
477 Ultra-Wide adapters (ABP-940UW) is included in this release.
478 2. Add Asc Library (Narrow Board) bug fixes.
479 3. Report an underrun condition with the host status byte set
480 to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which
481 causes the underrun condition to be ignored. When Linux defines
482 its own DID_UNDERRUN the constant defined in this file can be
483 removed.
484 4. Add patch to AscWaitTixISRDone().
485 5. Add support for up to 16 different AdvanSys host adapter SCSI
486 channels in one system. This allows four cards with four channels
487 to be used in one system.
488
489 3.1B (1/9/98):
490 1. Handle that PCI register base addresses are not always page
491 aligned even though ioremap() requires that the address argument
492 be page aligned.
493
494 3.1C (1/10/98):
495 1. Update latest BIOS version checked for from the /proc file.
496 2. Don't set microcode SDTR variable at initialization. Instead
497 wait until device capabilities have been detected from an Inquiry
498 command.
499
500 3.1D (1/21/98):
501 1. Improve performance when the driver is compiled as module by
502 allowing up to 64 scatter-gather elements instead of 8.
503
504 3.1E (5/1/98):
505 1. Set time delay in AscWaitTixISRDone() to 1000 ms.
506 2. Include SMP locking changes.
507 3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS
508 access functions.
509 4. Update board serial number printing.
510 5. Try allocating an IRQ both with and without the IRQF_DISABLED
511 flag set to allow IRQ sharing with drivers that do not set
512 the IRQF_DISABLED flag. Also display a more descriptive error
513 message if request_irq() fails.
514 6. Update to latest Asc and Adv Libraries.
515
516 3.2A (7/22/99):
517 1. Update Adv Library to 4.16 which includes support for
518 the ASC38C0800 (Ultra2/LVD) IC.
519
520 3.2B (8/23/99):
521 1. Correct PCI compile time option for v2.1.93 and greater
522 kernels, advansys_info() string, and debug compile time
523 option.
524 2. Correct DvcSleepMilliSecond() for v2.1.0 and greater
525 kernels. This caused an LVD detection/BIST problem problem
526 among other things.
527 3. Sort PCI cards by PCI Bus, Slot, Function ascending order
528 to be consistent with the BIOS.
529 4. Update to Asc Library S121 and Adv Library 5.2.
530
531 3.2C (8/24/99):
532 1. Correct PCI card detection bug introduced in 3.2B that
533 prevented PCI cards from being detected in kernels older
534 than v2.1.93.
535
536 3.2D (8/26/99):
537 1. Correct /proc device synchronous speed information display.
538 Also when re-negotiation is pending for a target device
539 note this condition with an * and footnote.
540 2. Correct initialization problem with Ultra-Wide cards that
541 have a pre-3.2 BIOS. A microcode variable changed locations
542 in 3.2 and greater BIOSes which caused WDTR to be attempted
543 erroneously with drives that don't support WDTR.
544
545 3.2E (8/30/99):
546 1. Fix compile error caused by v2.3.13 PCI structure change.
547 2. Remove field from ASCEEP_CONFIG that resulted in an EEPROM
548 checksum error for ISA cards.
549 3. Remove ASC_QUEUE_FLOW_CONTROL conditional code. The mid-level
550 SCSI changes that it depended on were never included in Linux.
551
552 3.2F (9/3/99):
553 1. Handle new initial function code added in v2.3.16 for all
554 driver versions.
555
556 3.2G (9/8/99):
557 1. Fix PCI board detection in v2.3.13 and greater kernels.
558 2. Fix comiple errors in v2.3.X with debugging enabled.
559
560 3.2H (9/13/99):
561 1. Add 64-bit address, long support for Alpha and UltraSPARC.
562 The driver has been verified to work on an Alpha system.
563 2. Add partial byte order handling support for Power PC and
564 other big-endian platforms. This support has not yet been
565 completed or verified.
566 3. For wide boards replace block zeroing of request and
567 scatter-gather structures with individual field initialization
568 to improve performance.
569 4. Correct and clarify ROM BIOS version detection.
570
571 3.2I (10/8/99):
572 1. Update to Adv Library 5.4.
573 2. Add v2.3.19 underrun reporting to asc_isr_callback() and
574 adv_isr_callback(). Remove DID_UNDERRUN constant and other
575 no longer needed code that previously documented the lack
576 of underrun handling.
577
578 3.2J (10/14/99):
579 1. Eliminate compile errors for v2.0 and earlier kernels.
580
581 3.2K (11/15/99):
582 1. Correct debug compile error in asc_prt_adv_scsi_req_q().
583 2. Update Adv Library to 5.5.
584 3. Add ifdef handling for /proc changes added in v2.3.28.
585 4. Increase Wide board scatter-gather list maximum length to
586 255 when the driver is compiled into the kernel.
587
588 3.2L (11/18/99):
589 1. Fix bug in adv_get_sglist() that caused an assertion failure
590 at line 7475. The reqp->sgblkp pointer must be initialized
591 to NULL in adv_get_sglist().
592
593 3.2M (11/29/99):
594 1. Really fix bug in adv_get_sglist().
595 2. Incorporate v2.3.29 changes into driver.
596
597 3.2N (4/1/00):
598 1. Add CONFIG_ISA ifdef code.
599 2. Include advansys_interrupts_enabled name change patch.
600 3. For >= v2.3.28 use new SCSI error handling with new function
601 advansys_eh_bus_reset(). Don't include an abort function
602 because of base library limitations.
603 4. For >= v2.3.28 use per board lock instead of io_request_lock.
604 5. For >= v2.3.28 eliminate advansys_command() and
605 advansys_command_done().
606 6. Add some changes for PowerPC (Big Endian) support, but it isn't
607 working yet.
608 7. Fix "nonexistent resource free" problem that occurred on a module
609 unload for boards with an I/O space >= 255. The 'n_io_port' field
610 is only one byte and can not be used to hold an ioport length more
611 than 255.
612
613 3.3A (4/4/00):
614 1. Update to Adv Library 5.8.
615 2. For wide cards add support for CDBs up to 16 bytes.
616 3. Eliminate warnings when CONFIG_PROC_FS is not defined.
617
618 3.3B (5/1/00):
619 1. Support for PowerPC (Big Endian) wide cards. Narrow cards
620 still need work.
621 2. Change bitfields to shift and mask access for endian
622 portability.
623
624 3.3C (10/13/00):
625 1. Update for latest 2.4 kernel.
626 2. Test ABP-480 CardBus support in 2.4 kernel - works!
627 3. Update to Asc Library S123.
628 4. Update to Adv Library 5.12.
629
630 3.3D (11/22/00):
631 1. Update for latest 2.4 kernel.
632 2. Create patches for 2.2 and 2.4 kernels.
633
634 3.3E (1/9/01):
635 1. Now that 2.4 is released remove ifdef code for kernel versions
636 less than 2.2. The driver is now only supported in kernels 2.2,
637 2.4, and greater.
638 2. Add code to release and acquire the io_request_lock in
639 the driver entrypoint functions: advansys_detect and
640 advansys_queuecommand. In kernel 2.4 the SCSI mid-level driver
641 still holds the io_request_lock on entry to SCSI low-level drivers.
642 This was supposed to be removed before 2.4 was released but never
643 happened. When the mid-level SCSI driver is changed all references
644 to the io_request_lock should be removed from the driver.
645 3. Simplify error handling by removing advansys_abort(),
646 AscAbortSRB(), AscResetDevice(). SCSI bus reset requests are
647 now handled by resetting the SCSI bus and fully re-initializing
648 the chip. This simple method of error recovery has proven to work
649 most reliably after attempts at different methods. Also now only
650 support the "new" error handling method and remove the obsolete
651 error handling interface.
652 4. Fix debug build errors.
653
654 3.3F (1/24/01):
655 1. Merge with ConnectCom version from Andy Kellner which
656 updates Adv Library to 5.14.
657 2. Make PowerPC (Big Endian) work for narrow cards and
658 fix problems writing EEPROM for wide cards.
659 3. Remove interrupts_enabled assertion function.
660
661 3.3G (2/16/01):
662 1. Return an error from narrow boards if passed a 16 byte
663 CDB. The wide board can already handle 16 byte CDBs.
664
665 3.3GJ (4/15/02):
666 1. hacks for lk 2.5 series (D. Gilbert)
667
668 3.3GJD (10/14/02):
669 1. change select_queue_depths to slave_configure
670 2. make cmd_per_lun be sane again
671
672 3.3K [2004/06/24]:
673 1. continuing cleanup for lk 2.6 series
674 2. Fix problem in lk 2.6.7-bk2 that broke PCI wide cards
675 3. Fix problem that oopsed ISA cards
676
677 I. Known Problems/Fix List (XXX)
678
679 1. Need to add memory mapping workaround. Test the memory mapping.
680 If it doesn't work revert to I/O port access. Can a test be done
681 safely?
682 2. Handle an interrupt not working. Keep an interrupt counter in
683 the interrupt handler. In the timeout function if the interrupt
684 has not occurred then print a message and run in polled mode.
685 3. Allow bus type scanning order to be changed.
686 4. Need to add support for target mode commands, cf. CAM XPT.
687
688 J. Credits (Chronological Order)
689
690 Bob Frey <bfrey@turbolinux.com.cn> wrote the AdvanSys SCSI driver
691 and maintained it up to 3.3F. He continues to answer questions
692 and help maintain the driver.
693
694 Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and
695 basis for the Linux v1.3.X changes which were included in the
696 1.2 release.
697
698 Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug
699 in advansys_biosparam() which was fixed in the 1.3 release.
700
701 Erik Ratcliffe <erik@caldera.com> has done testing of the
702 AdvanSys driver in the Caldera releases.
703
704 Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to
705 AscWaitTixISRDone() which he found necessary to make the
706 driver work with a SCSI-1 disk.
707
708 Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide
709 support in the 3.1A driver.
710
711 Doug Gilbert <dgilbert@interlog.com> has made changes and
712 suggestions to improve the driver and done a lot of testing.
713
714 Ken Mort <ken@mort.net> reported a DEBUG compile bug fixed
715 in 3.2K.
716
717 Tom Rini <trini@kernel.crashing.org> provided the CONFIG_ISA
718 patch and helped with PowerPC wide and narrow board support.
719
720 Philip Blundell <philb@gnu.org> provided an
721 advansys_interrupts_enabled patch.
722
723 Dave Jones <dave@denial.force9.co.uk> reported the compiler
724 warnings generated when CONFIG_PROC_FS was not defined in
725 the 3.2M driver.
726
727 Jerry Quinn <jlquinn@us.ibm.com> fixed PowerPC support (endian
728 problems) for wide cards.
729
730 Bryan Henderson <bryanh@giraffe-data.com> helped debug narrow
731 card error handling.
732
733 Manuel Veloso <veloso@pobox.com> worked hard on PowerPC narrow
734 board support and fixed a bug in AscGetEEPConfig().
735
736 Arnaldo Carvalho de Melo <acme@conectiva.com.br> made
737 save_flags/restore_flags changes.
738
739 Andy Kellner <AKellner@connectcom.net> continues the Advansys SCSI
740 driver development for ConnectCom (Version > 3.3F).
741
742 K. ConnectCom (AdvanSys) Contact Information
743
744 Mail: ConnectCom Solutions, Inc.
745 1150 Ringwood Court
746 San Jose, CA 95131
747 Operator/Sales: 1-408-383-9400
748 FAX: 1-408-383-9612
749 Tech Support: 1-408-467-2930
750 Tech Support E-Mail: linux@connectcom.net
751 FTP Site: ftp.connectcom.net (login: anonymous)
752 Web Site: http://www.connectcom.net
753
754 */
755
756 /*
757 * --- Linux Include Files
758 */
759
760 #include <linux/module.h>
761 #include <linux/string.h>
762 #include <linux/kernel.h>
763 #include <linux/types.h>
764 #include <linux/ioport.h>
765 #include <linux/interrupt.h>
766 #include <linux/delay.h>
767 #include <linux/slab.h>
768 #include <linux/mm.h>
769 #include <linux/proc_fs.h>
770 #include <linux/init.h>
771 #include <linux/blkdev.h>
772 #include <linux/isa.h>
773 #include <linux/eisa.h>
774 #include <linux/pci.h>
775 #include <linux/spinlock.h>
776 #include <linux/dma-mapping.h>
777
778 #include <asm/io.h>
779 #include <asm/system.h>
780 #include <asm/dma.h>
781
782 #include <scsi/scsi_cmnd.h>
783 #include <scsi/scsi_device.h>
784 #include <scsi/scsi_tcq.h>
785 #include <scsi/scsi.h>
786 #include <scsi/scsi_host.h>
787
788 /* FIXME: (by jejb@steeleye.com)
789 *
790 * Although all of the necessary command mapping places have the
791 * appropriate dma_map.. APIs, the driver still processes its internal
792 * queue using bus_to_virt() and virt_to_bus() which are illegal under
793 * the API. The entire queue processing structure will need to be
794 * altered to fix this.
795 */
796 #warning this driver is still not properly converted to the DMA API
797
798 /*
799 * --- Driver Options
800 */
801
802 /* Enable driver assertions. */
803 #define ADVANSYS_ASSERT
804
805 /* Enable driver /proc statistics. */
806 #define ADVANSYS_STATS
807
808 /* Enable driver tracing. */
809 /* #define ADVANSYS_DEBUG */
810
811 /*
812 * --- Asc Library Constants and Macros
813 */
814
815 #define ASC_LIB_VERSION_MAJOR 1
816 #define ASC_LIB_VERSION_MINOR 24
817 #define ASC_LIB_SERIAL_NUMBER 123
818
819 /*
820 * Portable Data Types
821 *
822 * Any instance where a 32-bit long or pointer type is assumed
823 * for precision or HW defined structures, the following define
824 * types must be used. In Linux the char, short, and int types
825 * are all consistent at 8, 16, and 32 bits respectively. Pointers
826 * and long types are 64 bits on Alpha and UltraSPARC.
827 */
828 #define ASC_PADDR __u32 /* Physical/Bus address data type. */
829 #define ASC_VADDR __u32 /* Virtual address data type. */
830 #define ASC_DCNT __u32 /* Unsigned Data count type. */
831 #define ASC_SDCNT __s32 /* Signed Data count type. */
832
833 /*
834 * These macros are used to convert a virtual address to a
835 * 32-bit value. This currently can be used on Linux Alpha
836 * which uses 64-bit virtual address but a 32-bit bus address.
837 * This is likely to break in the future, but doing this now
838 * will give us time to change the HW and FW to handle 64-bit
839 * addresses.
840 */
841 #define ASC_VADDR_TO_U32 virt_to_bus
842 #define ASC_U32_TO_VADDR bus_to_virt
843
844 typedef unsigned char uchar;
845
846 #ifndef TRUE
847 #define TRUE (1)
848 #endif
849 #ifndef FALSE
850 #define FALSE (0)
851 #endif
852
853 #define EOF (-1)
854 #define ERR (-1)
855 #define UW_ERR (uint)(0xFFFF)
856 #define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
857 #define ASC_PCI_ID2FUNC(id) (((id) >> 8) & 0x7)
858 #define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
859
860 #define ASC_DVCLIB_CALL_DONE (1)
861 #define ASC_DVCLIB_CALL_FAILED (0)
862 #define ASC_DVCLIB_CALL_ERROR (-1)
863
864 #define PCI_VENDOR_ID_ASP 0x10cd
865 #define PCI_DEVICE_ID_ASP_1200A 0x1100
866 #define PCI_DEVICE_ID_ASP_ABP940 0x1200
867 #define PCI_DEVICE_ID_ASP_ABP940U 0x1300
868 #define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
869 #define PCI_DEVICE_ID_38C0800_REV1 0x2500
870 #define PCI_DEVICE_ID_38C1600_REV1 0x2700
871
872 /*
873 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
874 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
875 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
876 * SRB structure.
877 */
878 #define CC_VERY_LONG_SG_LIST 0
879 #define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
880
881 #define PortAddr unsigned short /* port address size */
882 #define inp(port) inb(port)
883 #define outp(port, byte) outb((byte), (port))
884
885 #define inpw(port) inw(port)
886 #define outpw(port, word) outw((word), (port))
887
888 #define ASC_MAX_SG_QUEUE 7
889 #define ASC_MAX_SG_LIST 255
890
891 #define ASC_CS_TYPE unsigned short
892
893 #define ASC_IS_ISA (0x0001)
894 #define ASC_IS_ISAPNP (0x0081)
895 #define ASC_IS_EISA (0x0002)
896 #define ASC_IS_PCI (0x0004)
897 #define ASC_IS_PCI_ULTRA (0x0104)
898 #define ASC_IS_PCMCIA (0x0008)
899 #define ASC_IS_MCA (0x0020)
900 #define ASC_IS_VL (0x0040)
901 #define ASC_ISA_PNP_PORT_ADDR (0x279)
902 #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
903 #define ASC_IS_WIDESCSI_16 (0x0100)
904 #define ASC_IS_WIDESCSI_32 (0x0200)
905 #define ASC_IS_BIG_ENDIAN (0x8000)
906 #define ASC_CHIP_MIN_VER_VL (0x01)
907 #define ASC_CHIP_MAX_VER_VL (0x07)
908 #define ASC_CHIP_MIN_VER_PCI (0x09)
909 #define ASC_CHIP_MAX_VER_PCI (0x0F)
910 #define ASC_CHIP_VER_PCI_BIT (0x08)
911 #define ASC_CHIP_MIN_VER_ISA (0x11)
912 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
913 #define ASC_CHIP_MAX_VER_ISA (0x27)
914 #define ASC_CHIP_VER_ISA_BIT (0x30)
915 #define ASC_CHIP_VER_ISAPNP_BIT (0x20)
916 #define ASC_CHIP_VER_ASYN_BUG (0x21)
917 #define ASC_CHIP_VER_PCI 0x08
918 #define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
919 #define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
920 #define ASC_CHIP_MIN_VER_EISA (0x41)
921 #define ASC_CHIP_MAX_VER_EISA (0x47)
922 #define ASC_CHIP_VER_EISA_BIT (0x40)
923 #define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
924 #define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER 0x21
925 #define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER 0x0A
926 #define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL)
927 #define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
928 #define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL)
929 #define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
930 #define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL)
931 #define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
932 #define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL)
933 #define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL)
934
935 #define ASC_SCSI_ID_BITS 3
936 #define ASC_SCSI_TIX_TYPE uchar
937 #define ASC_ALL_DEVICE_BIT_SET 0xFF
938 #define ASC_SCSI_BIT_ID_TYPE uchar
939 #define ASC_MAX_TID 7
940 #define ASC_MAX_LUN 7
941 #define ASC_SCSI_WIDTH_BIT_SET 0xFF
942 #define ASC_MAX_SENSE_LEN 32
943 #define ASC_MIN_SENSE_LEN 14
944 #define ASC_MAX_CDB_LEN 12
945 #define ASC_SCSI_RESET_HOLD_TIME_US 60
946
947 /*
948 * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
949 * and CmdDt (Command Support Data) field bit definitions.
950 */
951 #define ADV_INQ_RTN_VPD_AND_CMDDT 0x3
952 #define ADV_INQ_RTN_CMDDT_FOR_OP_CODE 0x2
953 #define ADV_INQ_RTN_VPD_FOR_PG_CODE 0x1
954 #define ADV_INQ_RTN_STD_INQUIRY_DATA 0x0
955
956 #define ASC_SCSIDIR_NOCHK 0x00
957 #define ASC_SCSIDIR_T2H 0x08
958 #define ASC_SCSIDIR_H2T 0x10
959 #define ASC_SCSIDIR_NODATA 0x18
960 #define SCSI_ASC_NOMEDIA 0x3A
961 #define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4))
962 #define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F))
963 #define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13))
964 #define PUT_CDB1(x) ((uchar)((uint)(x) >> 8))
965 #define MS_SDTR_LEN 0x03
966 #define MS_WDTR_LEN 0x02
967
968 #define ASC_SG_LIST_PER_Q 7
969 #define QS_FREE 0x00
970 #define QS_READY 0x01
971 #define QS_DISC1 0x02
972 #define QS_DISC2 0x04
973 #define QS_BUSY 0x08
974 #define QS_ABORTED 0x40
975 #define QS_DONE 0x80
976 #define QC_NO_CALLBACK 0x01
977 #define QC_SG_SWAP_QUEUE 0x02
978 #define QC_SG_HEAD 0x04
979 #define QC_DATA_IN 0x08
980 #define QC_DATA_OUT 0x10
981 #define QC_URGENT 0x20
982 #define QC_MSG_OUT 0x40
983 #define QC_REQ_SENSE 0x80
984 #define QCSG_SG_XFER_LIST 0x02
985 #define QCSG_SG_XFER_MORE 0x04
986 #define QCSG_SG_XFER_END 0x08
987 #define QD_IN_PROGRESS 0x00
988 #define QD_NO_ERROR 0x01
989 #define QD_ABORTED_BY_HOST 0x02
990 #define QD_WITH_ERROR 0x04
991 #define QD_INVALID_REQUEST 0x80
992 #define QD_INVALID_HOST_NUM 0x81
993 #define QD_INVALID_DEVICE 0x82
994 #define QD_ERR_INTERNAL 0xFF
995 #define QHSTA_NO_ERROR 0x00
996 #define QHSTA_M_SEL_TIMEOUT 0x11
997 #define QHSTA_M_DATA_OVER_RUN 0x12
998 #define QHSTA_M_DATA_UNDER_RUN 0x12
999 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
1000 #define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
1001 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1002 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
1003 #define QHSTA_D_HOST_ABORT_FAILED 0x23
1004 #define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
1005 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1006 #define QHSTA_D_ASPI_NO_BUF_POOL 0x26
1007 #define QHSTA_M_WTM_TIMEOUT 0x41
1008 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
1009 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
1010 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1011 #define QHSTA_M_TARGET_STATUS_BUSY 0x45
1012 #define QHSTA_M_BAD_TAG_CODE 0x46
1013 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
1014 #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1015 #define QHSTA_D_LRAM_CMP_ERROR 0x81
1016 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1017 #define ASC_FLAG_SCSIQ_REQ 0x01
1018 #define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
1019 #define ASC_FLAG_BIOS_ASYNC_IO 0x04
1020 #define ASC_FLAG_SRB_LINEAR_ADDR 0x08
1021 #define ASC_FLAG_WIN16 0x10
1022 #define ASC_FLAG_WIN32 0x20
1023 #define ASC_FLAG_ISA_OVER_16MB 0x40
1024 #define ASC_FLAG_DOS_VM_CALLBACK 0x80
1025 #define ASC_TAG_FLAG_EXTRA_BYTES 0x10
1026 #define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
1027 #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
1028 #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1029 #define ASC_SCSIQ_CPY_BEG 4
1030 #define ASC_SCSIQ_SGHD_CPY_BEG 2
1031 #define ASC_SCSIQ_B_FWD 0
1032 #define ASC_SCSIQ_B_BWD 1
1033 #define ASC_SCSIQ_B_STATUS 2
1034 #define ASC_SCSIQ_B_QNO 3
1035 #define ASC_SCSIQ_B_CNTL 4
1036 #define ASC_SCSIQ_B_SG_QUEUE_CNT 5
1037 #define ASC_SCSIQ_D_DATA_ADDR 8
1038 #define ASC_SCSIQ_D_DATA_CNT 12
1039 #define ASC_SCSIQ_B_SENSE_LEN 20
1040 #define ASC_SCSIQ_DONE_INFO_BEG 22
1041 #define ASC_SCSIQ_D_SRBPTR 22
1042 #define ASC_SCSIQ_B_TARGET_IX 26
1043 #define ASC_SCSIQ_B_CDB_LEN 28
1044 #define ASC_SCSIQ_B_TAG_CODE 29
1045 #define ASC_SCSIQ_W_VM_ID 30
1046 #define ASC_SCSIQ_DONE_STATUS 32
1047 #define ASC_SCSIQ_HOST_STATUS 33
1048 #define ASC_SCSIQ_SCSI_STATUS 34
1049 #define ASC_SCSIQ_CDB_BEG 36
1050 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1051 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
1052 #define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
1053 #define ASC_SCSIQ_B_SG_WK_QP 49
1054 #define ASC_SCSIQ_B_SG_WK_IX 50
1055 #define ASC_SCSIQ_W_ALT_DC1 52
1056 #define ASC_SCSIQ_B_LIST_CNT 6
1057 #define ASC_SCSIQ_B_CUR_LIST_CNT 7
1058 #define ASC_SGQ_B_SG_CNTL 4
1059 #define ASC_SGQ_B_SG_HEAD_QP 5
1060 #define ASC_SGQ_B_SG_LIST_CNT 6
1061 #define ASC_SGQ_B_SG_CUR_LIST_CNT 7
1062 #define ASC_SGQ_LIST_BEG 8
1063 #define ASC_DEF_SCSI1_QNG 4
1064 #define ASC_MAX_SCSI1_QNG 4
1065 #define ASC_DEF_SCSI2_QNG 16
1066 #define ASC_MAX_SCSI2_QNG 32
1067 #define ASC_TAG_CODE_MASK 0x23
1068 #define ASC_STOP_REQ_RISC_STOP 0x01
1069 #define ASC_STOP_ACK_RISC_STOP 0x03
1070 #define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
1071 #define ASC_STOP_CLEAN_UP_DISC_Q 0x20
1072 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1073 #define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1074 #define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1075 #define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
1076 #define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
1077 #define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
1078 #define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1079 #define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
1080
1081 typedef struct asc_scsiq_1 {
1082 uchar status;
1083 uchar q_no;
1084 uchar cntl;
1085 uchar sg_queue_cnt;
1086 uchar target_id;
1087 uchar target_lun;
1088 ASC_PADDR data_addr;
1089 ASC_DCNT data_cnt;
1090 ASC_PADDR sense_addr;
1091 uchar sense_len;
1092 uchar extra_bytes;
1093 } ASC_SCSIQ_1;
1094
1095 typedef struct asc_scsiq_2 {
1096 ASC_VADDR srb_ptr;
1097 uchar target_ix;
1098 uchar flag;
1099 uchar cdb_len;
1100 uchar tag_code;
1101 ushort vm_id;
1102 } ASC_SCSIQ_2;
1103
1104 typedef struct asc_scsiq_3 {
1105 uchar done_stat;
1106 uchar host_stat;
1107 uchar scsi_stat;
1108 uchar scsi_msg;
1109 } ASC_SCSIQ_3;
1110
1111 typedef struct asc_scsiq_4 {
1112 uchar cdb[ASC_MAX_CDB_LEN];
1113 uchar y_first_sg_list_qp;
1114 uchar y_working_sg_qp;
1115 uchar y_working_sg_ix;
1116 uchar y_res;
1117 ushort x_req_count;
1118 ushort x_reconnect_rtn;
1119 ASC_PADDR x_saved_data_addr;
1120 ASC_DCNT x_saved_data_cnt;
1121 } ASC_SCSIQ_4;
1122
1123 typedef struct asc_q_done_info {
1124 ASC_SCSIQ_2 d2;
1125 ASC_SCSIQ_3 d3;
1126 uchar q_status;
1127 uchar q_no;
1128 uchar cntl;
1129 uchar sense_len;
1130 uchar extra_bytes;
1131 uchar res;
1132 ASC_DCNT remain_bytes;
1133 } ASC_QDONE_INFO;
1134
1135 typedef struct asc_sg_list {
1136 ASC_PADDR addr;
1137 ASC_DCNT bytes;
1138 } ASC_SG_LIST;
1139
1140 typedef struct asc_sg_head {
1141 ushort entry_cnt;
1142 ushort queue_cnt;
1143 ushort entry_to_copy;
1144 ushort res;
1145 ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1146 } ASC_SG_HEAD;
1147
1148 #define ASC_MIN_SG_LIST 2
1149
1150 typedef struct asc_min_sg_head {
1151 ushort entry_cnt;
1152 ushort queue_cnt;
1153 ushort entry_to_copy;
1154 ushort res;
1155 ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
1156 } ASC_MIN_SG_HEAD;
1157
1158 #define QCX_SORT (0x0001)
1159 #define QCX_COALEASE (0x0002)
1160
1161 typedef struct asc_scsi_q {
1162 ASC_SCSIQ_1 q1;
1163 ASC_SCSIQ_2 q2;
1164 uchar *cdbptr;
1165 ASC_SG_HEAD *sg_head;
1166 ushort remain_sg_entry_cnt;
1167 ushort next_sg_index;
1168 } ASC_SCSI_Q;
1169
1170 typedef struct asc_scsi_req_q {
1171 ASC_SCSIQ_1 r1;
1172 ASC_SCSIQ_2 r2;
1173 uchar *cdbptr;
1174 ASC_SG_HEAD *sg_head;
1175 uchar *sense_ptr;
1176 ASC_SCSIQ_3 r3;
1177 uchar cdb[ASC_MAX_CDB_LEN];
1178 uchar sense[ASC_MIN_SENSE_LEN];
1179 } ASC_SCSI_REQ_Q;
1180
1181 typedef struct asc_scsi_bios_req_q {
1182 ASC_SCSIQ_1 r1;
1183 ASC_SCSIQ_2 r2;
1184 uchar *cdbptr;
1185 ASC_SG_HEAD *sg_head;
1186 uchar *sense_ptr;
1187 ASC_SCSIQ_3 r3;
1188 uchar cdb[ASC_MAX_CDB_LEN];
1189 uchar sense[ASC_MIN_SENSE_LEN];
1190 } ASC_SCSI_BIOS_REQ_Q;
1191
1192 typedef struct asc_risc_q {
1193 uchar fwd;
1194 uchar bwd;
1195 ASC_SCSIQ_1 i1;
1196 ASC_SCSIQ_2 i2;
1197 ASC_SCSIQ_3 i3;
1198 ASC_SCSIQ_4 i4;
1199 } ASC_RISC_Q;
1200
1201 typedef struct asc_sg_list_q {
1202 uchar seq_no;
1203 uchar q_no;
1204 uchar cntl;
1205 uchar sg_head_qp;
1206 uchar sg_list_cnt;
1207 uchar sg_cur_list_cnt;
1208 } ASC_SG_LIST_Q;
1209
1210 typedef struct asc_risc_sg_list_q {
1211 uchar fwd;
1212 uchar bwd;
1213 ASC_SG_LIST_Q sg;
1214 ASC_SG_LIST sg_list[7];
1215 } ASC_RISC_SG_LIST_Q;
1216
1217 #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL
1218 #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024
1219 #define ASCQ_ERR_NO_ERROR 0
1220 #define ASCQ_ERR_IO_NOT_FOUND 1
1221 #define ASCQ_ERR_LOCAL_MEM 2
1222 #define ASCQ_ERR_CHKSUM 3
1223 #define ASCQ_ERR_START_CHIP 4
1224 #define ASCQ_ERR_INT_TARGET_ID 5
1225 #define ASCQ_ERR_INT_LOCAL_MEM 6
1226 #define ASCQ_ERR_HALT_RISC 7
1227 #define ASCQ_ERR_GET_ASPI_ENTRY 8
1228 #define ASCQ_ERR_CLOSE_ASPI 9
1229 #define ASCQ_ERR_HOST_INQUIRY 0x0A
1230 #define ASCQ_ERR_SAVED_SRB_BAD 0x0B
1231 #define ASCQ_ERR_QCNTL_SG_LIST 0x0C
1232 #define ASCQ_ERR_Q_STATUS 0x0D
1233 #define ASCQ_ERR_WR_SCSIQ 0x0E
1234 #define ASCQ_ERR_PC_ADDR 0x0F
1235 #define ASCQ_ERR_SYN_OFFSET 0x10
1236 #define ASCQ_ERR_SYN_XFER_TIME 0x11
1237 #define ASCQ_ERR_LOCK_DMA 0x12
1238 #define ASCQ_ERR_UNLOCK_DMA 0x13
1239 #define ASCQ_ERR_VDS_CHK_INSTALL 0x14
1240 #define ASCQ_ERR_MICRO_CODE_HALT 0x15
1241 #define ASCQ_ERR_SET_LRAM_ADDR 0x16
1242 #define ASCQ_ERR_CUR_QNG 0x17
1243 #define ASCQ_ERR_SG_Q_LINKS 0x18
1244 #define ASCQ_ERR_SCSIQ_PTR 0x19
1245 #define ASCQ_ERR_ISR_RE_ENTRY 0x1A
1246 #define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
1247 #define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
1248 #define ASCQ_ERR_SG_LIST_ODD_ADDRESS 0x1D
1249 #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1250 #define ASCQ_ERR_SCSIQ_NULL_PTR 0x1F
1251 #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR 0x20
1252 #define ASCQ_ERR_GET_NUM_OF_FREE_Q 0x21
1253 #define ASCQ_ERR_SEND_SCSI_Q 0x22
1254 #define ASCQ_ERR_HOST_REQ_RISC_HALT 0x23
1255 #define ASCQ_ERR_RESET_SDTR 0x24
1256
1257 /*
1258 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
1259 */
1260 #define ASC_WARN_NO_ERROR 0x0000
1261 #define ASC_WARN_IO_PORT_ROTATE 0x0001
1262 #define ASC_WARN_EEPROM_CHKSUM 0x0002
1263 #define ASC_WARN_IRQ_MODIFIED 0x0004
1264 #define ASC_WARN_AUTO_CONFIG 0x0008
1265 #define ASC_WARN_CMD_QNG_CONFLICT 0x0010
1266 #define ASC_WARN_EEPROM_RECOVER 0x0020
1267 #define ASC_WARN_CFG_MSW_RECOVER 0x0040
1268 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1269
1270 /*
1271 * Error code values are set in ASC_DVC_VAR 'err_code'.
1272 */
1273 #define ASC_IERR_WRITE_EEPROM 0x0001
1274 #define ASC_IERR_MCODE_CHKSUM 0x0002
1275 #define ASC_IERR_SET_PC_ADDR 0x0004
1276 #define ASC_IERR_START_STOP_CHIP 0x0008
1277 #define ASC_IERR_IRQ_NO 0x0010
1278 #define ASC_IERR_SET_IRQ_NO 0x0020
1279 #define ASC_IERR_CHIP_VERSION 0x0040
1280 #define ASC_IERR_SET_SCSI_ID 0x0080
1281 #define ASC_IERR_GET_PHY_ADDR 0x0100
1282 #define ASC_IERR_BAD_SIGNATURE 0x0200
1283 #define ASC_IERR_NO_BUS_TYPE 0x0400
1284 #define ASC_IERR_SCAM 0x0800
1285 #define ASC_IERR_SET_SDTR 0x1000
1286 #define ASC_IERR_RW_LRAM 0x8000
1287
1288 #define ASC_DEF_IRQ_NO 10
1289 #define ASC_MAX_IRQ_NO 15
1290 #define ASC_MIN_IRQ_NO 10
1291 #define ASC_MIN_REMAIN_Q (0x02)
1292 #define ASC_DEF_MAX_TOTAL_QNG (0xF0)
1293 #define ASC_MIN_TAG_Q_PER_DVC (0x04)
1294 #define ASC_DEF_TAG_Q_PER_DVC (0x04)
1295 #define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q
1296 #define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1297 #define ASC_MAX_TOTAL_QNG 240
1298 #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1299 #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
1300 #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
1301 #define ASC_MAX_INRAM_TAG_QNG 16
1302 #define ASC_IOADR_TABLE_MAX_IX 11
1303 #define ASC_IOADR_GAP 0x10
1304 #define ASC_LIB_SCSIQ_WK_SP 256
1305 #define ASC_MAX_SYN_XFER_NO 16
1306 #define ASC_SYN_MAX_OFFSET 0x0F
1307 #define ASC_DEF_SDTR_OFFSET 0x0F
1308 #define ASC_DEF_SDTR_INDEX 0x00
1309 #define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
1310 #define SYN_XFER_NS_0 25
1311 #define SYN_XFER_NS_1 30
1312 #define SYN_XFER_NS_2 35
1313 #define SYN_XFER_NS_3 40
1314 #define SYN_XFER_NS_4 50
1315 #define SYN_XFER_NS_5 60
1316 #define SYN_XFER_NS_6 70
1317 #define SYN_XFER_NS_7 85
1318 #define SYN_ULTRA_XFER_NS_0 12
1319 #define SYN_ULTRA_XFER_NS_1 19
1320 #define SYN_ULTRA_XFER_NS_2 25
1321 #define SYN_ULTRA_XFER_NS_3 32
1322 #define SYN_ULTRA_XFER_NS_4 38
1323 #define SYN_ULTRA_XFER_NS_5 44
1324 #define SYN_ULTRA_XFER_NS_6 50
1325 #define SYN_ULTRA_XFER_NS_7 57
1326 #define SYN_ULTRA_XFER_NS_8 63
1327 #define SYN_ULTRA_XFER_NS_9 69
1328 #define SYN_ULTRA_XFER_NS_10 75
1329 #define SYN_ULTRA_XFER_NS_11 82
1330 #define SYN_ULTRA_XFER_NS_12 88
1331 #define SYN_ULTRA_XFER_NS_13 94
1332 #define SYN_ULTRA_XFER_NS_14 100
1333 #define SYN_ULTRA_XFER_NS_15 107
1334
1335 typedef struct ext_msg {
1336 uchar msg_type;
1337 uchar msg_len;
1338 uchar msg_req;
1339 union {
1340 struct {
1341 uchar sdtr_xfer_period;
1342 uchar sdtr_req_ack_offset;
1343 } sdtr;
1344 struct {
1345 uchar wdtr_width;
1346 } wdtr;
1347 struct {
1348 uchar mdp_b3;
1349 uchar mdp_b2;
1350 uchar mdp_b1;
1351 uchar mdp_b0;
1352 } mdp;
1353 } u_ext_msg;
1354 uchar res;
1355 } EXT_MSG;
1356
1357 #define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
1358 #define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
1359 #define wdtr_width u_ext_msg.wdtr.wdtr_width
1360 #define mdp_b3 u_ext_msg.mdp_b3
1361 #define mdp_b2 u_ext_msg.mdp_b2
1362 #define mdp_b1 u_ext_msg.mdp_b1
1363 #define mdp_b0 u_ext_msg.mdp_b0
1364
1365 typedef struct asc_dvc_cfg {
1366 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1367 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1368 ASC_SCSI_BIT_ID_TYPE disc_enable;
1369 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1370 uchar chip_scsi_id;
1371 uchar isa_dma_speed;
1372 uchar isa_dma_channel;
1373 uchar chip_version;
1374 ushort lib_serial_no;
1375 ushort lib_version;
1376 ushort mcode_date;
1377 ushort mcode_version;
1378 uchar max_tag_qng[ASC_MAX_TID + 1];
1379 uchar *overrun_buf;
1380 uchar sdtr_period_offset[ASC_MAX_TID + 1];
1381 ushort pci_slot_info;
1382 uchar adapter_info[6];
1383 struct device *dev;
1384 } ASC_DVC_CFG;
1385
1386 #define ASC_DEF_DVC_CNTL 0xFFFF
1387 #define ASC_DEF_CHIP_SCSI_ID 7
1388 #define ASC_DEF_ISA_DMA_SPEED 4
1389 #define ASC_INIT_STATE_NULL 0x0000
1390 #define ASC_INIT_STATE_BEG_GET_CFG 0x0001
1391 #define ASC_INIT_STATE_END_GET_CFG 0x0002
1392 #define ASC_INIT_STATE_BEG_SET_CFG 0x0004
1393 #define ASC_INIT_STATE_END_SET_CFG 0x0008
1394 #define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
1395 #define ASC_INIT_STATE_END_LOAD_MC 0x0020
1396 #define ASC_INIT_STATE_BEG_INQUIRY 0x0040
1397 #define ASC_INIT_STATE_END_INQUIRY 0x0080
1398 #define ASC_INIT_RESET_SCSI_DONE 0x0100
1399 #define ASC_INIT_STATE_WITHOUT_EEP 0x8000
1400 #define ASC_BUG_FIX_IF_NOT_DWB 0x0001
1401 #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
1402 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1403 #define ASC_MIN_TAGGED_CMD 7
1404 #define ASC_MAX_SCSI_RESET_WAIT 30
1405
1406 struct asc_dvc_var; /* Forward Declaration. */
1407
1408 typedef void (*ASC_ISR_CALLBACK) (struct asc_dvc_var *, ASC_QDONE_INFO *);
1409 typedef int (*ASC_EXE_CALLBACK) (struct asc_dvc_var *, ASC_SCSI_Q *);
1410
1411 typedef struct asc_dvc_var {
1412 PortAddr iop_base;
1413 ushort err_code;
1414 ushort dvc_cntl;
1415 ushort bug_fix_cntl;
1416 ushort bus_type;
1417 ASC_ISR_CALLBACK isr_callback;
1418 ASC_EXE_CALLBACK exe_callback;
1419 ASC_SCSI_BIT_ID_TYPE init_sdtr;
1420 ASC_SCSI_BIT_ID_TYPE sdtr_done;
1421 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1422 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1423 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1424 ASC_SCSI_BIT_ID_TYPE start_motor;
1425 uchar scsi_reset_wait;
1426 uchar chip_no;
1427 char is_in_int;
1428 uchar max_total_qng;
1429 uchar cur_total_qng;
1430 uchar in_critical_cnt;
1431 uchar irq_no;
1432 uchar last_q_shortage;
1433 ushort init_state;
1434 uchar cur_dvc_qng[ASC_MAX_TID + 1];
1435 uchar max_dvc_qng[ASC_MAX_TID + 1];
1436 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
1437 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
1438 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1439 ASC_DVC_CFG *cfg;
1440 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1441 char redo_scam;
1442 ushort res2;
1443 uchar dos_int13_table[ASC_MAX_TID + 1];
1444 ASC_DCNT max_dma_count;
1445 ASC_SCSI_BIT_ID_TYPE no_scam;
1446 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1447 uchar max_sdtr_index;
1448 uchar host_init_sdtr_index;
1449 struct asc_board *drv_ptr;
1450 ASC_DCNT uc_break;
1451 } ASC_DVC_VAR;
1452
1453 typedef struct asc_dvc_inq_info {
1454 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1455 } ASC_DVC_INQ_INFO;
1456
1457 typedef struct asc_cap_info {
1458 ASC_DCNT lba;
1459 ASC_DCNT blk_size;
1460 } ASC_CAP_INFO;
1461
1462 typedef struct asc_cap_info_array {
1463 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1464 } ASC_CAP_INFO_ARRAY;
1465
1466 #define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
1467 #define ASC_MCNTL_NULL_TARGET (ushort)0x0002
1468 #define ASC_CNTL_INITIATOR (ushort)0x0001
1469 #define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
1470 #define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
1471 #define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
1472 #define ASC_CNTL_NO_SCAM (ushort)0x0010
1473 #define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
1474 #define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
1475 #define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
1476 #define ASC_CNTL_RESET_SCSI (ushort)0x0200
1477 #define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
1478 #define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
1479 #define ASC_CNTL_SCSI_PARITY (ushort)0x1000
1480 #define ASC_CNTL_BURST_MODE (ushort)0x2000
1481 #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1482 #define ASC_EEP_DVC_CFG_BEG_VL 2
1483 #define ASC_EEP_MAX_DVC_ADDR_VL 15
1484 #define ASC_EEP_DVC_CFG_BEG 32
1485 #define ASC_EEP_MAX_DVC_ADDR 45
1486 #define ASC_EEP_DEFINED_WORDS 10
1487 #define ASC_EEP_MAX_ADDR 63
1488 #define ASC_EEP_RES_WORDS 0
1489 #define ASC_EEP_MAX_RETRY 20
1490 #define ASC_MAX_INIT_BUSY_RETRY 8
1491 #define ASC_EEP_ISA_PNP_WSIZE 16
1492
1493 /*
1494 * These macros keep the chip SCSI id and ISA DMA speed
1495 * bitfields in board order. C bitfields aren't portable
1496 * between big and little-endian platforms so they are
1497 * not used.
1498 */
1499
1500 #define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
1501 #define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
1502 #define ASC_EEP_SET_CHIP_ID(cfg, sid) \
1503 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
1504 #define ASC_EEP_SET_DMA_SPD(cfg, spd) \
1505 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
1506
1507 typedef struct asceep_config {
1508 ushort cfg_lsw;
1509 ushort cfg_msw;
1510 uchar init_sdtr;
1511 uchar disc_enable;
1512 uchar use_cmd_qng;
1513 uchar start_motor;
1514 uchar max_total_qng;
1515 uchar max_tag_qng;
1516 uchar bios_scan;
1517 uchar power_up_wait;
1518 uchar no_scam;
1519 uchar id_speed; /* low order 4 bits is chip scsi id */
1520 /* high order 4 bits is isa dma speed */
1521 uchar dos_int13_table[ASC_MAX_TID + 1];
1522 uchar adapter_info[6];
1523 ushort cntl;
1524 ushort chksum;
1525 } ASCEEP_CONFIG;
1526
1527 #define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800
1528 #define ASC_PCI_CFG_LSW_BURST_MODE 0x0080
1529 #define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020
1530
1531 #define ASC_EEP_CMD_READ 0x80
1532 #define ASC_EEP_CMD_WRITE 0x40
1533 #define ASC_EEP_CMD_WRITE_ABLE 0x30
1534 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
1535 #define ASC_OVERRUN_BSIZE 0x00000048UL
1536 #define ASC_CTRL_BREAK_ONCE 0x0001
1537 #define ASC_CTRL_BREAK_STAY_IDLE 0x0002
1538 #define ASCV_MSGOUT_BEG 0x0000
1539 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1540 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1541 #define ASCV_BREAK_SAVED_CODE (ushort)0x0006
1542 #define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
1543 #define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
1544 #define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
1545 #define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
1546 #define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
1547 #define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
1548 #define ASCV_BREAK_ADDR (ushort)0x0028
1549 #define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
1550 #define ASCV_BREAK_CONTROL (ushort)0x002C
1551 #define ASCV_BREAK_HIT_COUNT (ushort)0x002E
1552
1553 #define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
1554 #define ASCV_MCODE_CHKSUM_W (ushort)0x0032
1555 #define ASCV_MCODE_SIZE_W (ushort)0x0034
1556 #define ASCV_STOP_CODE_B (ushort)0x0036
1557 #define ASCV_DVC_ERR_CODE_B (ushort)0x0037
1558 #define ASCV_OVERRUN_PADDR_D (ushort)0x0038
1559 #define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
1560 #define ASCV_HALTCODE_W (ushort)0x0040
1561 #define ASCV_CHKSUM_W (ushort)0x0042
1562 #define ASCV_MC_DATE_W (ushort)0x0044
1563 #define ASCV_MC_VER_W (ushort)0x0046
1564 #define ASCV_NEXTRDY_B (ushort)0x0048
1565 #define ASCV_DONENEXT_B (ushort)0x0049
1566 #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1567 #define ASCV_SCSIBUSY_B (ushort)0x004B
1568 #define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
1569 #define ASCV_CURCDB_B (ushort)0x004D
1570 #define ASCV_RCLUN_B (ushort)0x004E
1571 #define ASCV_BUSY_QHEAD_B (ushort)0x004F
1572 #define ASCV_DISC1_QHEAD_B (ushort)0x0050
1573 #define ASCV_DISC_ENABLE_B (ushort)0x0052
1574 #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1575 #define ASCV_HOSTSCSI_ID_B (ushort)0x0055
1576 #define ASCV_MCODE_CNTL_B (ushort)0x0056
1577 #define ASCV_NULL_TARGET_B (ushort)0x0057
1578 #define ASCV_FREE_Q_HEAD_W (ushort)0x0058
1579 #define ASCV_DONE_Q_TAIL_W (ushort)0x005A
1580 #define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
1581 #define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
1582 #define ASCV_HOST_FLAG_B (ushort)0x005D
1583 #define ASCV_TOTAL_READY_Q_B (ushort)0x0064
1584 #define ASCV_VER_SERIAL_B (ushort)0x0065
1585 #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1586 #define ASCV_WTM_FLAG_B (ushort)0x0068
1587 #define ASCV_RISC_FLAG_B (ushort)0x006A
1588 #define ASCV_REQ_SG_LIST_QP (ushort)0x006B
1589 #define ASC_HOST_FLAG_IN_ISR 0x01
1590 #define ASC_HOST_FLAG_ACK_INT 0x02
1591 #define ASC_RISC_FLAG_GEN_INT 0x01
1592 #define ASC_RISC_FLAG_REQ_SG_LIST 0x02
1593 #define IOP_CTRL (0x0F)
1594 #define IOP_STATUS (0x0E)
1595 #define IOP_INT_ACK IOP_STATUS
1596 #define IOP_REG_IFC (0x0D)
1597 #define IOP_SYN_OFFSET (0x0B)
1598 #define IOP_EXTRA_CONTROL (0x0D)
1599 #define IOP_REG_PC (0x0C)
1600 #define IOP_RAM_ADDR (0x0A)
1601 #define IOP_RAM_DATA (0x08)
1602 #define IOP_EEP_DATA (0x06)
1603 #define IOP_EEP_CMD (0x07)
1604 #define IOP_VERSION (0x03)
1605 #define IOP_CONFIG_HIGH (0x04)
1606 #define IOP_CONFIG_LOW (0x02)
1607 #define IOP_SIG_BYTE (0x01)
1608 #define IOP_SIG_WORD (0x00)
1609 #define IOP_REG_DC1 (0x0E)
1610 #define IOP_REG_DC0 (0x0C)
1611 #define IOP_REG_SB (0x0B)
1612 #define IOP_REG_DA1 (0x0A)
1613 #define IOP_REG_DA0 (0x08)
1614 #define IOP_REG_SC (0x09)
1615 #define IOP_DMA_SPEED (0x07)
1616 #define IOP_REG_FLAG (0x07)
1617 #define IOP_FIFO_H (0x06)
1618 #define IOP_FIFO_L (0x04)
1619 #define IOP_REG_ID (0x05)
1620 #define IOP_REG_QP (0x03)
1621 #define IOP_REG_IH (0x02)
1622 #define IOP_REG_IX (0x01)
1623 #define IOP_REG_AX (0x00)
1624 #define IFC_REG_LOCK (0x00)
1625 #define IFC_REG_UNLOCK (0x09)
1626 #define IFC_WR_EN_FILTER (0x10)
1627 #define IFC_RD_NO_EEPROM (0x10)
1628 #define IFC_SLEW_RATE (0x20)
1629 #define IFC_ACT_NEG (0x40)
1630 #define IFC_INP_FILTER (0x80)
1631 #define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
1632 #define SC_SEL (uchar)(0x80)
1633 #define SC_BSY (uchar)(0x40)
1634 #define SC_ACK (uchar)(0x20)
1635 #define SC_REQ (uchar)(0x10)
1636 #define SC_ATN (uchar)(0x08)
1637 #define SC_IO (uchar)(0x04)
1638 #define SC_CD (uchar)(0x02)
1639 #define SC_MSG (uchar)(0x01)
1640 #define SEC_SCSI_CTL (uchar)(0x80)
1641 #define SEC_ACTIVE_NEGATE (uchar)(0x40)
1642 #define SEC_SLEW_RATE (uchar)(0x20)
1643 #define SEC_ENABLE_FILTER (uchar)(0x10)
1644 #define ASC_HALT_EXTMSG_IN (ushort)0x8000
1645 #define ASC_HALT_CHK_CONDITION (ushort)0x8100
1646 #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1647 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
1648 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
1649 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1650 #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1651 #define ASC_MAX_QNO 0xF8
1652 #define ASC_DATA_SEC_BEG (ushort)0x0080
1653 #define ASC_DATA_SEC_END (ushort)0x0080
1654 #define ASC_CODE_SEC_BEG (ushort)0x0080
1655 #define ASC_CODE_SEC_END (ushort)0x0080
1656 #define ASC_QADR_BEG (0x4000)
1657 #define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
1658 #define ASC_QADR_END (ushort)0x7FFF
1659 #define ASC_QLAST_ADR (ushort)0x7FC0
1660 #define ASC_QBLK_SIZE 0x40
1661 #define ASC_BIOS_DATA_QBEG 0xF8
1662 #define ASC_MIN_ACTIVE_QNO 0x01
1663 #define ASC_QLINK_END 0xFF
1664 #define ASC_EEPROM_WORDS 0x10
1665 #define ASC_MAX_MGS_LEN 0x10
1666 #define ASC_BIOS_ADDR_DEF 0xDC00
1667 #define ASC_BIOS_SIZE 0x3800
1668 #define ASC_BIOS_RAM_OFF 0x3800
1669 #define ASC_BIOS_RAM_SIZE 0x800
1670 #define ASC_BIOS_MIN_ADDR 0xC000
1671 #define ASC_BIOS_MAX_ADDR 0xEC00
1672 #define ASC_BIOS_BANK_SIZE 0x0400
1673 #define ASC_MCODE_START_ADDR 0x0080
1674 #define ASC_CFG0_HOST_INT_ON 0x0020
1675 #define ASC_CFG0_BIOS_ON 0x0040
1676 #define ASC_CFG0_VERA_BURST_ON 0x0080
1677 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
1678 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
1679 #define ASC_CFG1_LRAM_8BITS_ON 0x0800
1680 #define ASC_CFG_MSW_CLR_MASK 0x3080
1681 #define CSW_TEST1 (ASC_CS_TYPE)0x8000
1682 #define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
1683 #define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
1684 #define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
1685 #define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
1686 #define CSW_TEST2 (ASC_CS_TYPE)0x0400
1687 #define CSW_TEST3 (ASC_CS_TYPE)0x0200
1688 #define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
1689 #define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
1690 #define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
1691 #define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
1692 #define CSW_HALTED (ASC_CS_TYPE)0x0010
1693 #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1694 #define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
1695 #define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
1696 #define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
1697 #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1698 #define CIW_INT_ACK (ASC_CS_TYPE)0x0100
1699 #define CIW_TEST1 (ASC_CS_TYPE)0x0200
1700 #define CIW_TEST2 (ASC_CS_TYPE)0x0400
1701 #define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
1702 #define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
1703 #define CC_CHIP_RESET (uchar)0x80
1704 #define CC_SCSI_RESET (uchar)0x40
1705 #define CC_HALT (uchar)0x20
1706 #define CC_SINGLE_STEP (uchar)0x10
1707 #define CC_DMA_ABLE (uchar)0x08
1708 #define CC_TEST (uchar)0x04
1709 #define CC_BANK_ONE (uchar)0x02
1710 #define CC_DIAG (uchar)0x01
1711 #define ASC_1000_ID0W 0x04C1
1712 #define ASC_1000_ID0W_FIX 0x00C1
1713 #define ASC_1000_ID1B 0x25
1714 #define ASC_EISA_REV_IOP_MASK (0x0C83)
1715 #define ASC_EISA_PID_IOP_MASK (0x0C80)
1716 #define ASC_EISA_CFG_IOP_MASK (0x0C86)
1717 #define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
1718 #define INS_HALTINT (ushort)0x6281
1719 #define INS_HALT (ushort)0x6280
1720 #define INS_SINT (ushort)0x6200
1721 #define INS_RFLAG_WTM (ushort)0x7380
1722 #define ASC_MC_SAVE_CODE_WSIZE 0x500
1723 #define ASC_MC_SAVE_DATA_WSIZE 0x40
1724
1725 typedef struct asc_mc_saved {
1726 ushort data[ASC_MC_SAVE_DATA_WSIZE];
1727 ushort code[ASC_MC_SAVE_CODE_WSIZE];
1728 } ASC_MC_SAVED;
1729
1730 #define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1731 #define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1732 #define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1733 #define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1734 #define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1735 #define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1736 #define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
1737 #define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
1738 #define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1739 #define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1740 #define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1741 #define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1742 #define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1743 #define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1744 #define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1745 #define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
1746 #define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
1747 #define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
1748 #define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
1749 #define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
1750 #define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
1751 #define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
1752 #define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
1753 #define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
1754 #define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
1755 #define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
1756 #define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1757 #define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1758 #define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
1759 #define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
1760 #define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
1761 #define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
1762 #define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1763 #define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
1764 #define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
1765 #define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
1766 #define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
1767 #define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
1768 #define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
1769 #define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
1770 #define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1771 #define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1772 #define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
1773 #define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
1774 #define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
1775 #define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
1776 #define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
1777 #define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
1778 #define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
1779 #define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
1780 #define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
1781 #define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
1782 #define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
1783 #define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
1784 #define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
1785 #define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
1786 #define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
1787 #define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
1788 #define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
1789 #define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
1790 #define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
1791 #define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
1792 #define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
1793 #define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
1794 #define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
1795 #define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
1796 #define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
1797 #define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
1798
1799 static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1800 static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1801 static void AscWaitEEPRead(void);
1802 static void AscWaitEEPWrite(void);
1803 static ushort AscReadEEPWord(PortAddr, uchar);
1804 static ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1805 static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1806 static int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1807 static int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1808 static int AscStartChip(PortAddr);
1809 static int AscStopChip(PortAddr);
1810 static void AscSetChipIH(PortAddr, ushort);
1811 static int AscIsChipHalted(PortAddr);
1812 static void AscAckInterrupt(PortAddr);
1813 static void AscDisableInterrupt(PortAddr);
1814 static void AscEnableInterrupt(PortAddr);
1815 static void AscSetBank(PortAddr, uchar);
1816 static int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1817 #ifdef CONFIG_ISA
1818 static uchar AscGetIsaDmaSpeed(PortAddr);
1819 #endif /* CONFIG_ISA */
1820 static uchar AscReadLramByte(PortAddr, ushort);
1821 static ushort AscReadLramWord(PortAddr, ushort);
1822 #if CC_VERY_LONG_SG_LIST
1823 static ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1824 #endif /* CC_VERY_LONG_SG_LIST */
1825 static void AscWriteLramWord(PortAddr, ushort, ushort);
1826 static void AscWriteLramByte(PortAddr, ushort, uchar);
1827 static ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
1828 static void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1829 static void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1830 static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1831 static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
1832 static ushort AscInitAscDvcVar(ASC_DVC_VAR *);
1833 static ushort AscInitFromEEP(ASC_DVC_VAR *);
1834 static ushort AscInitFromAscDvcVar(ASC_DVC_VAR *);
1835 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1836 static int AscTestExternalLram(ASC_DVC_VAR *);
1837 static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1838 static uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1839 static void AscSetChipSDTR(PortAddr, uchar, uchar);
1840 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1841 static uchar AscAllocFreeQueue(PortAddr, uchar);
1842 static uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1843 static int AscHostReqRiscHalt(PortAddr);
1844 static int AscStopQueueExe(PortAddr);
1845 static int AscSendScsiQueue(ASC_DVC_VAR *,
1846 ASC_SCSI_Q *scsiq, uchar n_q_required);
1847 static int AscPutReadyQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1848 static int AscPutReadySgListQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1849 static int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1850 static int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1851 static ushort AscInitLram(ASC_DVC_VAR *);
1852 static ushort AscInitQLinkVar(ASC_DVC_VAR *);
1853 static int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1854 static int AscIsrChipHalted(ASC_DVC_VAR *);
1855 static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1856 ASC_QDONE_INFO *, ASC_DCNT);
1857 static int AscIsrQDone(ASC_DVC_VAR *);
1858 #ifdef CONFIG_ISA
1859 static ushort AscGetEisaChipCfg(PortAddr);
1860 #endif /* CONFIG_ISA */
1861 static uchar AscGetChipScsiCtrl(PortAddr);
1862 static uchar AscGetChipVersion(PortAddr, ushort);
1863 static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
1864 static void AscToggleIRQAct(PortAddr);
1865 static inline ulong DvcEnterCritical(void);
1866 static inline void DvcLeaveCritical(ulong);
1867 static void DvcSleepMilliSecond(ASC_DCNT);
1868 static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
1869 static void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1870 static void DvcGetQinfo(PortAddr, ushort, uchar *, int);
1871 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
1872 static void AscAsyncFix(ASC_DVC_VAR *, struct scsi_device *);
1873 static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
1874 static int AscISR(ASC_DVC_VAR *);
1875 static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar);
1876 static int AscSgListToQueue(int);
1877 #ifdef CONFIG_ISA
1878 static void AscEnableIsaDma(uchar);
1879 #endif /* CONFIG_ISA */
1880 static const char *advansys_info(struct Scsi_Host *shost);
1881
1882 /*
1883 * --- Adv Library Constants and Macros
1884 */
1885
1886 #define ADV_LIB_VERSION_MAJOR 5
1887 #define ADV_LIB_VERSION_MINOR 14
1888
1889 /*
1890 * Define Adv Library required special types.
1891 */
1892
1893 /*
1894 * Portable Data Types
1895 *
1896 * Any instance where a 32-bit long or pointer type is assumed
1897 * for precision or HW defined structures, the following define
1898 * types must be used. In Linux the char, short, and int types
1899 * are all consistent at 8, 16, and 32 bits respectively. Pointers
1900 * and long types are 64 bits on Alpha and UltraSPARC.
1901 */
1902 #define ADV_PADDR __u32 /* Physical address data type. */
1903 #define ADV_VADDR __u32 /* Virtual address data type. */
1904 #define ADV_DCNT __u32 /* Unsigned Data count type. */
1905 #define ADV_SDCNT __s32 /* Signed Data count type. */
1906
1907 /*
1908 * These macros are used to convert a virtual address to a
1909 * 32-bit value. This currently can be used on Linux Alpha
1910 * which uses 64-bit virtual address but a 32-bit bus address.
1911 * This is likely to break in the future, but doing this now
1912 * will give us time to change the HW and FW to handle 64-bit
1913 * addresses.
1914 */
1915 #define ADV_VADDR_TO_U32 virt_to_bus
1916 #define ADV_U32_TO_VADDR bus_to_virt
1917
1918 #define AdvPortAddr void __iomem * /* Virtual memory address size */
1919
1920 /*
1921 * Define Adv Library required memory access macros.
1922 */
1923 #define ADV_MEM_READB(addr) readb(addr)
1924 #define ADV_MEM_READW(addr) readw(addr)
1925 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
1926 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
1927 #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
1928
1929 #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
1930
1931 /*
1932 * For wide boards a CDB length maximum of 16 bytes
1933 * is supported.
1934 */
1935 #define ADV_MAX_CDB_LEN 16
1936
1937 /*
1938 * Define total number of simultaneous maximum element scatter-gather
1939 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
1940 * maximum number of outstanding commands per wide host adapter. Each
1941 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
1942 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
1943 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
1944 * structures or 255 scatter-gather elements.
1945 *
1946 */
1947 #define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
1948
1949 /*
1950 * Define Adv Library required maximum number of scatter-gather
1951 * elements per request.
1952 */
1953 #define ADV_MAX_SG_LIST 255
1954
1955 /* Number of SG blocks needed. */
1956 #define ADV_NUM_SG_BLOCK \
1957 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
1958
1959 /* Total contiguous memory needed for SG blocks. */
1960 #define ADV_SG_TOTAL_MEM_SIZE \
1961 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
1962
1963 #define ADV_PAGE_SIZE PAGE_SIZE
1964
1965 #define ADV_NUM_PAGE_CROSSING \
1966 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1967
1968 #define ADV_EEP_DVC_CFG_BEGIN (0x00)
1969 #define ADV_EEP_DVC_CFG_END (0x15)
1970 #define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
1971 #define ADV_EEP_MAX_WORD_ADDR (0x1E)
1972
1973 #define ADV_EEP_DELAY_MS 100
1974
1975 #define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
1976 #define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
1977 /*
1978 * For the ASC3550 Bit 13 is Termination Polarity control bit.
1979 * For later ICs Bit 13 controls whether the CIS (Card Information
1980 * Service Section) is loaded from EEPROM.
1981 */
1982 #define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
1983 #define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
1984 /*
1985 * ASC38C1600 Bit 11
1986 *
1987 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
1988 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
1989 * Function 0 will specify INT B.
1990 *
1991 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
1992 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
1993 * Function 1 will specify INT A.
1994 */
1995 #define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
1996
1997 typedef struct adveep_3550_config {
1998 /* Word Offset, Description */
1999
2000 ushort cfg_lsw; /* 00 power up initialization */
2001 /* bit 13 set - Term Polarity Control */
2002 /* bit 14 set - BIOS Enable */
2003 /* bit 15 set - Big Endian Mode */
2004 ushort cfg_msw; /* 01 unused */
2005 ushort disc_enable; /* 02 disconnect enable */
2006 ushort wdtr_able; /* 03 Wide DTR able */
2007 ushort sdtr_able; /* 04 Synchronous DTR able */
2008 ushort start_motor; /* 05 send start up motor */
2009 ushort tagqng_able; /* 06 tag queuing able */
2010 ushort bios_scan; /* 07 BIOS device control */
2011 ushort scam_tolerant; /* 08 no scam */
2012
2013 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2014 uchar bios_boot_delay; /* power up wait */
2015
2016 uchar scsi_reset_delay; /* 10 reset delay */
2017 uchar bios_id_lun; /* first boot device scsi id & lun */
2018 /* high nibble is lun */
2019 /* low nibble is scsi id */
2020
2021 uchar termination; /* 11 0 - automatic */
2022 /* 1 - low off / high off */
2023 /* 2 - low off / high on */
2024 /* 3 - low on / high on */
2025 /* There is no low on / high off */
2026
2027 uchar reserved1; /* reserved byte (not used) */
2028
2029 ushort bios_ctrl; /* 12 BIOS control bits */
2030 /* bit 0 BIOS don't act as initiator. */
2031 /* bit 1 BIOS > 1 GB support */
2032 /* bit 2 BIOS > 2 Disk Support */
2033 /* bit 3 BIOS don't support removables */
2034 /* bit 4 BIOS support bootable CD */
2035 /* bit 5 BIOS scan enabled */
2036 /* bit 6 BIOS support multiple LUNs */
2037 /* bit 7 BIOS display of message */
2038 /* bit 8 SCAM disabled */
2039 /* bit 9 Reset SCSI bus during init. */
2040 /* bit 10 */
2041 /* bit 11 No verbose initialization. */
2042 /* bit 12 SCSI parity enabled */
2043 /* bit 13 */
2044 /* bit 14 */
2045 /* bit 15 */
2046 ushort ultra_able; /* 13 ULTRA speed able */
2047 ushort reserved2; /* 14 reserved */
2048 uchar max_host_qng; /* 15 maximum host queuing */
2049 uchar max_dvc_qng; /* maximum per device queuing */
2050 ushort dvc_cntl; /* 16 control bit for driver */
2051 ushort bug_fix; /* 17 control bit for bug fix */
2052 ushort serial_number_word1; /* 18 Board serial number word 1 */
2053 ushort serial_number_word2; /* 19 Board serial number word 2 */
2054 ushort serial_number_word3; /* 20 Board serial number word 3 */
2055 ushort check_sum; /* 21 EEP check sum */
2056 uchar oem_name[16]; /* 22 OEM name */
2057 ushort dvc_err_code; /* 30 last device driver error code */
2058 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2059 ushort adv_err_addr; /* 32 last uc error address */
2060 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2061 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2062 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2063 ushort num_of_err; /* 36 number of error */
2064 } ADVEEP_3550_CONFIG;
2065
2066 typedef struct adveep_38C0800_config {
2067 /* Word Offset, Description */
2068
2069 ushort cfg_lsw; /* 00 power up initialization */
2070 /* bit 13 set - Load CIS */
2071 /* bit 14 set - BIOS Enable */
2072 /* bit 15 set - Big Endian Mode */
2073 ushort cfg_msw; /* 01 unused */
2074 ushort disc_enable; /* 02 disconnect enable */
2075 ushort wdtr_able; /* 03 Wide DTR able */
2076 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2077 ushort start_motor; /* 05 send start up motor */
2078 ushort tagqng_able; /* 06 tag queuing able */
2079 ushort bios_scan; /* 07 BIOS device control */
2080 ushort scam_tolerant; /* 08 no scam */
2081
2082 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2083 uchar bios_boot_delay; /* power up wait */
2084
2085 uchar scsi_reset_delay; /* 10 reset delay */
2086 uchar bios_id_lun; /* first boot device scsi id & lun */
2087 /* high nibble is lun */
2088 /* low nibble is scsi id */
2089
2090 uchar termination_se; /* 11 0 - automatic */
2091 /* 1 - low off / high off */
2092 /* 2 - low off / high on */
2093 /* 3 - low on / high on */
2094 /* There is no low on / high off */
2095
2096 uchar termination_lvd; /* 11 0 - automatic */
2097 /* 1 - low off / high off */
2098 /* 2 - low off / high on */
2099 /* 3 - low on / high on */
2100 /* There is no low on / high off */
2101
2102 ushort bios_ctrl; /* 12 BIOS control bits */
2103 /* bit 0 BIOS don't act as initiator. */
2104 /* bit 1 BIOS > 1 GB support */
2105 /* bit 2 BIOS > 2 Disk Support */
2106 /* bit 3 BIOS don't support removables */
2107 /* bit 4 BIOS support bootable CD */
2108 /* bit 5 BIOS scan enabled */
2109 /* bit 6 BIOS support multiple LUNs */
2110 /* bit 7 BIOS display of message */
2111 /* bit 8 SCAM disabled */
2112 /* bit 9 Reset SCSI bus during init. */
2113 /* bit 10 */
2114 /* bit 11 No verbose initialization. */
2115 /* bit 12 SCSI parity enabled */
2116 /* bit 13 */
2117 /* bit 14 */
2118 /* bit 15 */
2119 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2120 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2121 uchar max_host_qng; /* 15 maximum host queueing */
2122 uchar max_dvc_qng; /* maximum per device queuing */
2123 ushort dvc_cntl; /* 16 control bit for driver */
2124 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2125 ushort serial_number_word1; /* 18 Board serial number word 1 */
2126 ushort serial_number_word2; /* 19 Board serial number word 2 */
2127 ushort serial_number_word3; /* 20 Board serial number word 3 */
2128 ushort check_sum; /* 21 EEP check sum */
2129 uchar oem_name[16]; /* 22 OEM name */
2130 ushort dvc_err_code; /* 30 last device driver error code */
2131 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2132 ushort adv_err_addr; /* 32 last uc error address */
2133 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2134 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2135 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2136 ushort reserved36; /* 36 reserved */
2137 ushort reserved37; /* 37 reserved */
2138 ushort reserved38; /* 38 reserved */
2139 ushort reserved39; /* 39 reserved */
2140 ushort reserved40; /* 40 reserved */
2141 ushort reserved41; /* 41 reserved */
2142 ushort reserved42; /* 42 reserved */
2143 ushort reserved43; /* 43 reserved */
2144 ushort reserved44; /* 44 reserved */
2145 ushort reserved45; /* 45 reserved */
2146 ushort reserved46; /* 46 reserved */
2147 ushort reserved47; /* 47 reserved */
2148 ushort reserved48; /* 48 reserved */
2149 ushort reserved49; /* 49 reserved */
2150 ushort reserved50; /* 50 reserved */
2151 ushort reserved51; /* 51 reserved */
2152 ushort reserved52; /* 52 reserved */
2153 ushort reserved53; /* 53 reserved */
2154 ushort reserved54; /* 54 reserved */
2155 ushort reserved55; /* 55 reserved */
2156 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2157 ushort cisprt_msw; /* 57 CIS PTR MSW */
2158 ushort subsysvid; /* 58 SubSystem Vendor ID */
2159 ushort subsysid; /* 59 SubSystem ID */
2160 ushort reserved60; /* 60 reserved */
2161 ushort reserved61; /* 61 reserved */
2162 ushort reserved62; /* 62 reserved */
2163 ushort reserved63; /* 63 reserved */
2164 } ADVEEP_38C0800_CONFIG;
2165
2166 typedef struct adveep_38C1600_config {
2167 /* Word Offset, Description */
2168
2169 ushort cfg_lsw; /* 00 power up initialization */
2170 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
2171 /* clear - Func. 0 INTA, Func. 1 INTB */
2172 /* bit 13 set - Load CIS */
2173 /* bit 14 set - BIOS Enable */
2174 /* bit 15 set - Big Endian Mode */
2175 ushort cfg_msw; /* 01 unused */
2176 ushort disc_enable; /* 02 disconnect enable */
2177 ushort wdtr_able; /* 03 Wide DTR able */
2178 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2179 ushort start_motor; /* 05 send start up motor */
2180 ushort tagqng_able; /* 06 tag queuing able */
2181 ushort bios_scan; /* 07 BIOS device control */
2182 ushort scam_tolerant; /* 08 no scam */
2183
2184 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2185 uchar bios_boot_delay; /* power up wait */
2186
2187 uchar scsi_reset_delay; /* 10 reset delay */
2188 uchar bios_id_lun; /* first boot device scsi id & lun */
2189 /* high nibble is lun */
2190 /* low nibble is scsi id */
2191
2192 uchar termination_se; /* 11 0 - automatic */
2193 /* 1 - low off / high off */
2194 /* 2 - low off / high on */
2195 /* 3 - low on / high on */
2196 /* There is no low on / high off */
2197
2198 uchar termination_lvd; /* 11 0 - automatic */
2199 /* 1 - low off / high off */
2200 /* 2 - low off / high on */
2201 /* 3 - low on / high on */
2202 /* There is no low on / high off */
2203
2204 ushort bios_ctrl; /* 12 BIOS control bits */
2205 /* bit 0 BIOS don't act as initiator. */
2206 /* bit 1 BIOS > 1 GB support */
2207 /* bit 2 BIOS > 2 Disk Support */
2208 /* bit 3 BIOS don't support removables */
2209 /* bit 4 BIOS support bootable CD */
2210 /* bit 5 BIOS scan enabled */
2211 /* bit 6 BIOS support multiple LUNs */
2212 /* bit 7 BIOS display of message */
2213 /* bit 8 SCAM disabled */
2214 /* bit 9 Reset SCSI bus during init. */
2215 /* bit 10 Basic Integrity Checking disabled */
2216 /* bit 11 No verbose initialization. */
2217 /* bit 12 SCSI parity enabled */
2218 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
2219 /* bit 14 */
2220 /* bit 15 */
2221 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2222 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2223 uchar max_host_qng; /* 15 maximum host queueing */
2224 uchar max_dvc_qng; /* maximum per device queuing */
2225 ushort dvc_cntl; /* 16 control bit for driver */
2226 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2227 ushort serial_number_word1; /* 18 Board serial number word 1 */
2228 ushort serial_number_word2; /* 19 Board serial number word 2 */
2229 ushort serial_number_word3; /* 20 Board serial number word 3 */
2230 ushort check_sum; /* 21 EEP check sum */
2231 uchar oem_name[16]; /* 22 OEM name */
2232 ushort dvc_err_code; /* 30 last device driver error code */
2233 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2234 ushort adv_err_addr; /* 32 last uc error address */
2235 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2236 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2237 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2238 ushort reserved36; /* 36 reserved */
2239 ushort reserved37; /* 37 reserved */
2240 ushort reserved38; /* 38 reserved */
2241 ushort reserved39; /* 39 reserved */
2242 ushort reserved40; /* 40 reserved */
2243 ushort reserved41; /* 41 reserved */
2244 ushort reserved42; /* 42 reserved */
2245 ushort reserved43; /* 43 reserved */
2246 ushort reserved44; /* 44 reserved */
2247 ushort reserved45; /* 45 reserved */
2248 ushort reserved46; /* 46 reserved */
2249 ushort reserved47; /* 47 reserved */
2250 ushort reserved48; /* 48 reserved */
2251 ushort reserved49; /* 49 reserved */
2252 ushort reserved50; /* 50 reserved */
2253 ushort reserved51; /* 51 reserved */
2254 ushort reserved52; /* 52 reserved */
2255 ushort reserved53; /* 53 reserved */
2256 ushort reserved54; /* 54 reserved */
2257 ushort reserved55; /* 55 reserved */
2258 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2259 ushort cisprt_msw; /* 57 CIS PTR MSW */
2260 ushort subsysvid; /* 58 SubSystem Vendor ID */
2261 ushort subsysid; /* 59 SubSystem ID */
2262 ushort reserved60; /* 60 reserved */
2263 ushort reserved61; /* 61 reserved */
2264 ushort reserved62; /* 62 reserved */
2265 ushort reserved63; /* 63 reserved */
2266 } ADVEEP_38C1600_CONFIG;
2267
2268 /*
2269 * EEPROM Commands
2270 */
2271 #define ASC_EEP_CMD_DONE 0x0200
2272 #define ASC_EEP_CMD_DONE_ERR 0x0001
2273
2274 /* cfg_word */
2275 #define EEP_CFG_WORD_BIG_ENDIAN 0x8000
2276
2277 /* bios_ctrl */
2278 #define BIOS_CTRL_BIOS 0x0001
2279 #define BIOS_CTRL_EXTENDED_XLAT 0x0002
2280 #define BIOS_CTRL_GT_2_DISK 0x0004
2281 #define BIOS_CTRL_BIOS_REMOVABLE 0x0008
2282 #define BIOS_CTRL_BOOTABLE_CD 0x0010
2283 #define BIOS_CTRL_MULTIPLE_LUN 0x0040
2284 #define BIOS_CTRL_DISPLAY_MSG 0x0080
2285 #define BIOS_CTRL_NO_SCAM 0x0100
2286 #define BIOS_CTRL_RESET_SCSI_BUS 0x0200
2287 #define BIOS_CTRL_INIT_VERBOSE 0x0800
2288 #define BIOS_CTRL_SCSI_PARITY 0x1000
2289 #define BIOS_CTRL_AIPP_DIS 0x2000
2290
2291 #define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
2292 #define ADV_3550_IOLEN 0x40 /* I/O Port Range in bytes */
2293
2294 #define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2295 #define ADV_38C0800_IOLEN 0x100 /* I/O Port Range in bytes */
2296
2297 /*
2298 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
2299 * a special 16K Adv Library and Microcode version. After the issue is
2300 * resolved, should restore 32K support.
2301 *
2302 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
2303 */
2304 #define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2305 #define ADV_38C1600_IOLEN 0x100 /* I/O Port Range 256 bytes */
2306 #define ADV_38C1600_MEMLEN 0x1000 /* Memory Range 4KB bytes */
2307
2308 /*
2309 * Byte I/O register address from base of 'iop_base'.
2310 */
2311 #define IOPB_INTR_STATUS_REG 0x00
2312 #define IOPB_CHIP_ID_1 0x01
2313 #define IOPB_INTR_ENABLES 0x02
2314 #define IOPB_CHIP_TYPE_REV 0x03
2315 #define IOPB_RES_ADDR_4 0x04
2316 #define IOPB_RES_ADDR_5 0x05
2317 #define IOPB_RAM_DATA 0x06
2318 #define IOPB_RES_ADDR_7 0x07
2319 #define IOPB_FLAG_REG 0x08
2320 #define IOPB_RES_ADDR_9 0x09
2321 #define IOPB_RISC_CSR 0x0A
2322 #define IOPB_RES_ADDR_B 0x0B
2323 #define IOPB_RES_ADDR_C 0x0C
2324 #define IOPB_RES_ADDR_D 0x0D
2325 #define IOPB_SOFT_OVER_WR 0x0E
2326 #define IOPB_RES_ADDR_F 0x0F
2327 #define IOPB_MEM_CFG 0x10
2328 #define IOPB_RES_ADDR_11 0x11
2329 #define IOPB_GPIO_DATA 0x12
2330 #define IOPB_RES_ADDR_13 0x13
2331 #define IOPB_FLASH_PAGE 0x14
2332 #define IOPB_RES_ADDR_15 0x15
2333 #define IOPB_GPIO_CNTL 0x16
2334 #define IOPB_RES_ADDR_17 0x17
2335 #define IOPB_FLASH_DATA 0x18
2336 #define IOPB_RES_ADDR_19 0x19
2337 #define IOPB_RES_ADDR_1A 0x1A
2338 #define IOPB_RES_ADDR_1B 0x1B
2339 #define IOPB_RES_ADDR_1C 0x1C
2340 #define IOPB_RES_ADDR_1D 0x1D
2341 #define IOPB_RES_ADDR_1E 0x1E
2342 #define IOPB_RES_ADDR_1F 0x1F
2343 #define IOPB_DMA_CFG0 0x20
2344 #define IOPB_DMA_CFG1 0x21
2345 #define IOPB_TICKLE 0x22
2346 #define IOPB_DMA_REG_WR 0x23
2347 #define IOPB_SDMA_STATUS 0x24
2348 #define IOPB_SCSI_BYTE_CNT 0x25
2349 #define IOPB_HOST_BYTE_CNT 0x26
2350 #define IOPB_BYTE_LEFT_TO_XFER 0x27
2351 #define IOPB_BYTE_TO_XFER_0 0x28
2352 #define IOPB_BYTE_TO_XFER_1 0x29
2353 #define IOPB_BYTE_TO_XFER_2 0x2A
2354 #define IOPB_BYTE_TO_XFER_3 0x2B
2355 #define IOPB_ACC_GRP 0x2C
2356 #define IOPB_RES_ADDR_2D 0x2D
2357 #define IOPB_DEV_ID 0x2E
2358 #define IOPB_RES_ADDR_2F 0x2F
2359 #define IOPB_SCSI_DATA 0x30
2360 #define IOPB_RES_ADDR_31 0x31
2361 #define IOPB_RES_ADDR_32 0x32
2362 #define IOPB_SCSI_DATA_HSHK 0x33
2363 #define IOPB_SCSI_CTRL 0x34
2364 #define IOPB_RES_ADDR_35 0x35
2365 #define IOPB_RES_ADDR_36 0x36
2366 #define IOPB_RES_ADDR_37 0x37
2367 #define IOPB_RAM_BIST 0x38
2368 #define IOPB_PLL_TEST 0x39
2369 #define IOPB_PCI_INT_CFG 0x3A
2370 #define IOPB_RES_ADDR_3B 0x3B
2371 #define IOPB_RFIFO_CNT 0x3C
2372 #define IOPB_RES_ADDR_3D 0x3D
2373 #define IOPB_RES_ADDR_3E 0x3E
2374 #define IOPB_RES_ADDR_3F 0x3F
2375
2376 /*
2377 * Word I/O register address from base of 'iop_base'.
2378 */
2379 #define IOPW_CHIP_ID_0 0x00 /* CID0 */
2380 #define IOPW_CTRL_REG 0x02 /* CC */
2381 #define IOPW_RAM_ADDR 0x04 /* LA */
2382 #define IOPW_RAM_DATA 0x06 /* LD */
2383 #define IOPW_RES_ADDR_08 0x08
2384 #define IOPW_RISC_CSR 0x0A /* CSR */
2385 #define IOPW_SCSI_CFG0 0x0C /* CFG0 */
2386 #define IOPW_SCSI_CFG1 0x0E /* CFG1 */
2387 #define IOPW_RES_ADDR_10 0x10
2388 #define IOPW_SEL_MASK 0x12 /* SM */
2389 #define IOPW_RES_ADDR_14 0x14
2390 #define IOPW_FLASH_ADDR 0x16 /* FA */
2391 #define IOPW_RES_ADDR_18 0x18
2392 #define IOPW_EE_CMD 0x1A /* EC */
2393 #define IOPW_EE_DATA 0x1C /* ED */
2394 #define IOPW_SFIFO_CNT 0x1E /* SFC */
2395 #define IOPW_RES_ADDR_20 0x20
2396 #define IOPW_Q_BASE 0x22 /* QB */
2397 #define IOPW_QP 0x24 /* QP */
2398 #define IOPW_IX 0x26 /* IX */
2399 #define IOPW_SP 0x28 /* SP */
2400 #define IOPW_PC 0x2A /* PC */
2401 #define IOPW_RES_ADDR_2C 0x2C
2402 #define IOPW_RES_ADDR_2E 0x2E
2403 #define IOPW_SCSI_DATA 0x30 /* SD */
2404 #define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
2405 #define IOPW_SCSI_CTRL 0x34 /* SC */
2406 #define IOPW_HSHK_CFG 0x36 /* HCFG */
2407 #define IOPW_SXFR_STATUS 0x36 /* SXS */
2408 #define IOPW_SXFR_CNTL 0x38 /* SXL */
2409 #define IOPW_SXFR_CNTH 0x3A /* SXH */
2410 #define IOPW_RES_ADDR_3C 0x3C
2411 #define IOPW_RFIFO_DATA 0x3E /* RFD */
2412
2413 /*
2414 * Doubleword I/O register address from base of 'iop_base'.
2415 */
2416 #define IOPDW_RES_ADDR_0 0x00
2417 #define IOPDW_RAM_DATA 0x04
2418 #define IOPDW_RES_ADDR_8 0x08
2419 #define IOPDW_RES_ADDR_C 0x0C
2420 #define IOPDW_RES_ADDR_10 0x10
2421 #define IOPDW_COMMA 0x14
2422 #define IOPDW_COMMB 0x18
2423 #define IOPDW_RES_ADDR_1C 0x1C
2424 #define IOPDW_SDMA_ADDR0 0x20
2425 #define IOPDW_SDMA_ADDR1 0x24
2426 #define IOPDW_SDMA_COUNT 0x28
2427 #define IOPDW_SDMA_ERROR 0x2C
2428 #define IOPDW_RDMA_ADDR0 0x30
2429 #define IOPDW_RDMA_ADDR1 0x34
2430 #define IOPDW_RDMA_COUNT 0x38
2431 #define IOPDW_RDMA_ERROR 0x3C
2432
2433 #define ADV_CHIP_ID_BYTE 0x25
2434 #define ADV_CHIP_ID_WORD 0x04C1
2435
2436 #define ADV_SC_SCSI_BUS_RESET 0x2000
2437
2438 #define ADV_INTR_ENABLE_HOST_INTR 0x01
2439 #define ADV_INTR_ENABLE_SEL_INTR 0x02
2440 #define ADV_INTR_ENABLE_DPR_INTR 0x04
2441 #define ADV_INTR_ENABLE_RTA_INTR 0x08
2442 #define ADV_INTR_ENABLE_RMA_INTR 0x10
2443 #define ADV_INTR_ENABLE_RST_INTR 0x20
2444 #define ADV_INTR_ENABLE_DPE_INTR 0x40
2445 #define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
2446
2447 #define ADV_INTR_STATUS_INTRA 0x01
2448 #define ADV_INTR_STATUS_INTRB 0x02
2449 #define ADV_INTR_STATUS_INTRC 0x04
2450
2451 #define ADV_RISC_CSR_STOP (0x0000)
2452 #define ADV_RISC_TEST_COND (0x2000)
2453 #define ADV_RISC_CSR_RUN (0x4000)
2454 #define ADV_RISC_CSR_SINGLE_STEP (0x8000)
2455
2456 #define ADV_CTRL_REG_HOST_INTR 0x0100
2457 #define ADV_CTRL_REG_SEL_INTR 0x0200
2458 #define ADV_CTRL_REG_DPR_INTR 0x0400
2459 #define ADV_CTRL_REG_RTA_INTR 0x0800
2460 #define ADV_CTRL_REG_RMA_INTR 0x1000
2461 #define ADV_CTRL_REG_RES_BIT14 0x2000
2462 #define ADV_CTRL_REG_DPE_INTR 0x4000
2463 #define ADV_CTRL_REG_POWER_DONE 0x8000
2464 #define ADV_CTRL_REG_ANY_INTR 0xFF00
2465
2466 #define ADV_CTRL_REG_CMD_RESET 0x00C6
2467 #define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
2468 #define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
2469 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
2470 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
2471
2472 #define ADV_TICKLE_NOP 0x00
2473 #define ADV_TICKLE_A 0x01
2474 #define ADV_TICKLE_B 0x02
2475 #define ADV_TICKLE_C 0x03
2476
2477 #define ADV_SCSI_CTRL_RSTOUT 0x2000
2478
2479 #define AdvIsIntPending(port) \
2480 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2481
2482 /*
2483 * SCSI_CFG0 Register bit definitions
2484 */
2485 #define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
2486 #define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
2487 #define EVEN_PARITY 0x1000 /* Select Even Parity */
2488 #define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2489 #define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
2490 #define PRIM_MODE 0x0100 /* Primitive SCSI mode */
2491 #define SCAM_EN 0x0080 /* Enable SCAM selection */
2492 #define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2493 #define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2494 #define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
2495 #define OUR_ID 0x000F /* SCSI ID */
2496
2497 /*
2498 * SCSI_CFG1 Register bit definitions
2499 */
2500 #define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
2501 #define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2502 #define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
2503 #define FILTER_SEL 0x0C00 /* Filter Period Selection */
2504 #define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
2505 #define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
2506 #define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
2507 #define ACTIVE_DBL 0x0200 /* Disable Active Negation */
2508 #define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
2509 #define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
2510 #define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
2511 #define TERM_CTL 0x0030 /* External SCSI Termination Bits */
2512 #define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
2513 #define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
2514 #define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
2515
2516 /*
2517 * Addendum for ASC-38C0800 Chip
2518 *
2519 * The ASC-38C1600 Chip uses the same definitions except that the
2520 * bus mode override bits [12:10] have been moved to byte register
2521 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
2522 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
2523 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
2524 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
2525 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
2526 */
2527 #define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
2528 #define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
2529 #define HVD 0x1000 /* HVD Device Detect */
2530 #define LVD 0x0800 /* LVD Device Detect */
2531 #define SE 0x0400 /* SE Device Detect */
2532 #define TERM_LVD 0x00C0 /* LVD Termination Bits */
2533 #define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
2534 #define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
2535 #define TERM_SE 0x0030 /* SE Termination Bits */
2536 #define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
2537 #define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
2538 #define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
2539 #define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
2540 #define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
2541 #define C_DET_SE 0x0003 /* SE Cable Detect Bits */
2542 #define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
2543 #define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
2544
2545 #define CABLE_ILLEGAL_A 0x7
2546 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
2547
2548 #define CABLE_ILLEGAL_B 0xB
2549 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
2550
2551 /*
2552 * MEM_CFG Register bit definitions
2553 */
2554 #define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
2555 #define FAST_EE_CLK 0x20 /* Diagnostic Bit */
2556 #define RAM_SZ 0x1C /* Specify size of RAM to RISC */
2557 #define RAM_SZ_2KB 0x00 /* 2 KB */
2558 #define RAM_SZ_4KB 0x04 /* 4 KB */
2559 #define RAM_SZ_8KB 0x08 /* 8 KB */
2560 #define RAM_SZ_16KB 0x0C /* 16 KB */
2561 #define RAM_SZ_32KB 0x10 /* 32 KB */
2562 #define RAM_SZ_64KB 0x14 /* 64 KB */
2563
2564 /*
2565 * DMA_CFG0 Register bit definitions
2566 *
2567 * This register is only accessible to the host.
2568 */
2569 #define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
2570 #define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
2571 #define FIFO_THRESH_16B 0x00 /* 16 bytes */
2572 #define FIFO_THRESH_32B 0x20 /* 32 bytes */
2573 #define FIFO_THRESH_48B 0x30 /* 48 bytes */
2574 #define FIFO_THRESH_64B 0x40 /* 64 bytes */
2575 #define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
2576 #define FIFO_THRESH_96B 0x60 /* 96 bytes */
2577 #define FIFO_THRESH_112B 0x70 /* 112 bytes */
2578 #define START_CTL 0x0C /* DMA start conditions */
2579 #define START_CTL_TH 0x00 /* Wait threshold level (default) */
2580 #define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
2581 #define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
2582 #define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
2583 #define READ_CMD 0x03 /* Memory Read Method */
2584 #define READ_CMD_MR 0x00 /* Memory Read */
2585 #define READ_CMD_MRL 0x02 /* Memory Read Long */
2586 #define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
2587
2588 /*
2589 * ASC-38C0800 RAM BIST Register bit definitions
2590 */
2591 #define RAM_TEST_MODE 0x80
2592 #define PRE_TEST_MODE 0x40
2593 #define NORMAL_MODE 0x00
2594 #define RAM_TEST_DONE 0x10
2595 #define RAM_TEST_STATUS 0x0F
2596 #define RAM_TEST_HOST_ERROR 0x08
2597 #define RAM_TEST_INTRAM_ERROR 0x04
2598 #define RAM_TEST_RISC_ERROR 0x02
2599 #define RAM_TEST_SCSI_ERROR 0x01
2600 #define RAM_TEST_SUCCESS 0x00
2601 #define PRE_TEST_VALUE 0x05
2602 #define NORMAL_VALUE 0x00
2603
2604 /*
2605 * ASC38C1600 Definitions
2606 *
2607 * IOPB_PCI_INT_CFG Bit Field Definitions
2608 */
2609
2610 #define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
2611
2612 /*
2613 * Bit 1 can be set to change the interrupt for the Function to operate in
2614 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
2615 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
2616 * mode, otherwise the operating mode is undefined.
2617 */
2618 #define TOTEMPOLE 0x02
2619
2620 /*
2621 * Bit 0 can be used to change the Int Pin for the Function. The value is
2622 * 0 by default for both Functions with Function 0 using INT A and Function
2623 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
2624 * INT A is used.
2625 *
2626 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
2627 * value specified in the PCI Configuration Space.
2628 */
2629 #define INTAB 0x01
2630
2631 /* a_advlib.h */
2632
2633 /*
2634 * Adv Library Status Definitions
2635 */
2636 #define ADV_TRUE 1
2637 #define ADV_FALSE 0
2638 #define ADV_NOERROR 1
2639 #define ADV_SUCCESS 1
2640 #define ADV_BUSY 0
2641 #define ADV_ERROR (-1)
2642
2643 /*
2644 * ADV_DVC_VAR 'warn_code' values
2645 */
2646 #define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
2647 #define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
2648 #define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
2649 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */
2650 #define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
2651
2652 #define ADV_MAX_TID 15 /* max. target identifier */
2653 #define ADV_MAX_LUN 7 /* max. logical unit number */
2654
2655 /*
2656 * Error code values are set in ADV_DVC_VAR 'err_code'.
2657 */
2658 #define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */
2659 #define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
2660 #define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */
2661 #define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
2662 #define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */
2663 #define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
2664 #define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */
2665 #define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
2666 #define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
2667 #define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */
2668 #define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */
2669 #define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */
2670 #define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */
2671 #define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */
2672
2673 /*
2674 * Fixed locations of microcode operating variables.
2675 */
2676 #define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
2677 #define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
2678 #define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
2679 #define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
2680 #define ASC_MC_VERSION_NUM 0x003A /* microcode number */
2681 #define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
2682 #define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
2683 #define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
2684 #define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
2685 #define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
2686 #define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
2687 #define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
2688 #define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
2689 #define ASC_MC_CHIP_TYPE 0x009A
2690 #define ASC_MC_INTRB_CODE 0x009B
2691 #define ASC_MC_WDTR_ABLE 0x009C
2692 #define ASC_MC_SDTR_ABLE 0x009E
2693 #define ASC_MC_TAGQNG_ABLE 0x00A0
2694 #define ASC_MC_DISC_ENABLE 0x00A2
2695 #define ASC_MC_IDLE_CMD_STATUS 0x00A4
2696 #define ASC_MC_IDLE_CMD 0x00A6
2697 #define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
2698 #define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
2699 #define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
2700 #define ASC_MC_DEFAULT_MEM_CFG 0x00B0
2701 #define ASC_MC_DEFAULT_SEL_MASK 0x00B2
2702 #define ASC_MC_SDTR_DONE 0x00B6
2703 #define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
2704 #define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
2705 #define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
2706 #define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
2707 #define ASC_MC_WDTR_DONE 0x0124
2708 #define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
2709 #define ASC_MC_ICQ 0x0160
2710 #define ASC_MC_IRQ 0x0164
2711 #define ASC_MC_PPR_ABLE 0x017A
2712
2713 /*
2714 * BIOS LRAM variable absolute offsets.
2715 */
2716 #define BIOS_CODESEG 0x54
2717 #define BIOS_CODELEN 0x56
2718 #define BIOS_SIGNATURE 0x58
2719 #define BIOS_VERSION 0x5A
2720
2721 /*
2722 * Microcode Control Flags
2723 *
2724 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2725 * and handled by the microcode.
2726 */
2727 #define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
2728 #define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
2729
2730 /*
2731 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2732 */
2733 #define HSHK_CFG_WIDE_XFR 0x8000
2734 #define HSHK_CFG_RATE 0x0F00
2735 #define HSHK_CFG_OFFSET 0x001F
2736
2737 #define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
2738 #define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
2739 #define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
2740 #define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
2741
2742 #define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2743 #define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
2744 #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2745 #define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
2746 #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2747
2748 #define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
2749 #define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
2750 #define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
2751 #define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
2752 #define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
2753 /*
2754 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
2755 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
2756 */
2757 #define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
2758 #define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
2759
2760 /*
2761 * All fields here are accessed by the board microcode and need to be
2762 * little-endian.
2763 */
2764 typedef struct adv_carr_t {
2765 ADV_VADDR carr_va; /* Carrier Virtual Address */
2766 ADV_PADDR carr_pa; /* Carrier Physical Address */
2767 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
2768 /*
2769 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
2770 *
2771 * next_vpa [3:1] Reserved Bits
2772 * next_vpa [0] Done Flag set in Response Queue.
2773 */
2774 ADV_VADDR next_vpa;
2775 } ADV_CARR_T;
2776
2777 /*
2778 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2779 */
2780 #define ASC_NEXT_VPA_MASK 0xFFFFFFF0
2781
2782 #define ASC_RQ_DONE 0x00000001
2783 #define ASC_RQ_GOOD 0x00000002
2784 #define ASC_CQ_STOPPER 0x00000000
2785
2786 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2787
2788 #define ADV_CARRIER_NUM_PAGE_CROSSING \
2789 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2790 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2791
2792 #define ADV_CARRIER_BUFSIZE \
2793 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2794
2795 /*
2796 * ASC_SCSI_REQ_Q 'a_flag' definitions
2797 *
2798 * The Adv Library should limit use to the lower nibble (4 bits) of
2799 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2800 */
2801 #define ADV_POLL_REQUEST 0x01 /* poll for request completion */
2802 #define ADV_SCSIQ_DONE 0x02 /* request done */
2803 #define ADV_DONT_RETRY 0x08 /* don't do retry */
2804
2805 #define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
2806 #define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
2807 #define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
2808
2809 /*
2810 * Adapter temporary configuration structure
2811 *
2812 * This structure can be discarded after initialization. Don't add
2813 * fields here needed after initialization.
2814 *
2815 * Field naming convention:
2816 *
2817 * *_enable indicates the field enables or disables a feature. The
2818 * value of the field is never reset.
2819 */
2820 typedef struct adv_dvc_cfg {
2821 ushort disc_enable; /* enable disconnection */
2822 uchar chip_version; /* chip version */
2823 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2824 ushort lib_version; /* Adv Library version number */
2825 ushort control_flag; /* Microcode Control Flag */
2826 ushort mcode_date; /* Microcode date */
2827 ushort mcode_version; /* Microcode version */
2828 ushort pci_slot_info; /* high byte device/function number */
2829 /* bits 7-3 device num., bits 2-0 function num. */
2830 /* low byte bus num. */
2831 ushort serial1; /* EEPROM serial number word 1 */
2832 ushort serial2; /* EEPROM serial number word 2 */
2833 ushort serial3; /* EEPROM serial number word 3 */
2834 struct device *dev; /* pointer to the pci dev structure for this board */
2835 } ADV_DVC_CFG;
2836
2837 struct adv_dvc_var;
2838 struct adv_scsi_req_q;
2839
2840 typedef void (*ADV_ISR_CALLBACK)
2841 (struct adv_dvc_var *, struct adv_scsi_req_q *);
2842
2843 typedef void (*ADV_ASYNC_CALLBACK)
2844 (struct adv_dvc_var *, uchar);
2845
2846 /*
2847 * Adapter operation variable structure.
2848 *
2849 * One structure is required per host adapter.
2850 *
2851 * Field naming convention:
2852 *
2853 * *_able indicates both whether a feature should be enabled or disabled
2854 * and whether a device isi capable of the feature. At initialization
2855 * this field may be set, but later if a device is found to be incapable
2856 * of the feature, the field is cleared.
2857 */
2858 typedef struct adv_dvc_var {
2859 AdvPortAddr iop_base; /* I/O port address */
2860 ushort err_code; /* fatal error code */
2861 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
2862 ADV_ISR_CALLBACK isr_callback;
2863 ADV_ASYNC_CALLBACK async_callback;
2864 ushort wdtr_able; /* try WDTR for a device */
2865 ushort sdtr_able; /* try SDTR for a device */
2866 ushort ultra_able; /* try SDTR Ultra speed for a device */
2867 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
2868 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
2869 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
2870 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
2871 ushort tagqng_able; /* try tagged queuing with a device */
2872 ushort ppr_able; /* PPR message capable per TID bitmask. */
2873 uchar max_dvc_qng; /* maximum number of tagged commands per device */
2874 ushort start_motor; /* start motor command allowed */
2875 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
2876 uchar chip_no; /* should be assigned by caller */
2877 uchar max_host_qng; /* maximum number of Q'ed command allowed */
2878 uchar irq_no; /* IRQ number */
2879 ushort no_scam; /* scam_tolerant of EEPROM */
2880 struct asc_board *drv_ptr; /* driver pointer to private structure */
2881 uchar chip_scsi_id; /* chip SCSI target ID */
2882 uchar chip_type;
2883 uchar bist_err_code;
2884 ADV_CARR_T *carrier_buf;
2885 ADV_CARR_T *carr_freelist; /* Carrier free list. */
2886 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
2887 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
2888 ushort carr_pending_cnt; /* Count of pending carriers. */
2889 /*
2890 * Note: The following fields will not be used after initialization. The
2891 * driver may discard the buffer after initialization is done.
2892 */
2893 ADV_DVC_CFG *cfg; /* temporary configuration structure */
2894 } ADV_DVC_VAR;
2895
2896 #define NO_OF_SG_PER_BLOCK 15
2897
2898 typedef struct asc_sg_block {
2899 uchar reserved1;
2900 uchar reserved2;
2901 uchar reserved3;
2902 uchar sg_cnt; /* Valid entries in block. */
2903 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
2904 struct {
2905 ADV_PADDR sg_addr; /* SG element address. */
2906 ADV_DCNT sg_count; /* SG element count. */
2907 } sg_list[NO_OF_SG_PER_BLOCK];
2908 } ADV_SG_BLOCK;
2909
2910 /*
2911 * ADV_SCSI_REQ_Q - microcode request structure
2912 *
2913 * All fields in this structure up to byte 60 are used by the microcode.
2914 * The microcode makes assumptions about the size and ordering of fields
2915 * in this structure. Do not change the structure definition here without
2916 * coordinating the change with the microcode.
2917 *
2918 * All fields accessed by microcode must be maintained in little_endian
2919 * order.
2920 */
2921 typedef struct adv_scsi_req_q {
2922 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
2923 uchar target_cmd;
2924 uchar target_id; /* Device target identifier. */
2925 uchar target_lun; /* Device target logical unit number. */
2926 ADV_PADDR data_addr; /* Data buffer physical address. */
2927 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
2928 ADV_PADDR sense_addr;
2929 ADV_PADDR carr_pa;
2930 uchar mflag;
2931 uchar sense_len;
2932 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
2933 uchar scsi_cntl;
2934 uchar done_status; /* Completion status. */
2935 uchar scsi_status; /* SCSI status byte. */
2936 uchar host_status; /* Ucode host status. */
2937 uchar sg_working_ix;
2938 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
2939 ADV_PADDR sg_real_addr; /* SG list physical address. */
2940 ADV_PADDR scsiq_rptr;
2941 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
2942 ADV_VADDR scsiq_ptr;
2943 ADV_VADDR carr_va;
2944 /*
2945 * End of microcode structure - 60 bytes. The rest of the structure
2946 * is used by the Adv Library and ignored by the microcode.
2947 */
2948 ADV_VADDR srb_ptr;
2949 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
2950 char *vdata_addr; /* Data buffer virtual address. */
2951 uchar a_flag;
2952 uchar pad[2]; /* Pad out to a word boundary. */
2953 } ADV_SCSI_REQ_Q;
2954
2955 /*
2956 * Microcode idle loop commands
2957 */
2958 #define IDLE_CMD_COMPLETED 0
2959 #define IDLE_CMD_STOP_CHIP 0x0001
2960 #define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
2961 #define IDLE_CMD_SEND_INT 0x0004
2962 #define IDLE_CMD_ABORT 0x0008
2963 #define IDLE_CMD_DEVICE_RESET 0x0010
2964 #define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
2965 #define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
2966 #define IDLE_CMD_SCSIREQ 0x0080
2967
2968 #define IDLE_CMD_STATUS_SUCCESS 0x0001
2969 #define IDLE_CMD_STATUS_FAILURE 0x0002
2970
2971 /*
2972 * AdvSendIdleCmd() flag definitions.
2973 */
2974 #define ADV_NOWAIT 0x01
2975
2976 /*
2977 * Wait loop time out values.
2978 */
2979 #define SCSI_WAIT_10_SEC 10UL /* 10 seconds */
2980 #define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
2981 #define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
2982 #define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */
2983 #define SCSI_MAX_RETRY 10 /* retry count */
2984
2985 #define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
2986 #define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
2987 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
2988 #define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
2989
2990 #define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
2991
2992 /*
2993 * Device drivers must define the following functions.
2994 */
2995 static inline ulong DvcEnterCritical(void);
2996 static inline void DvcLeaveCritical(ulong);
2997 static void DvcSleepMilliSecond(ADV_DCNT);
2998 static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
2999 uchar *, ASC_SDCNT *, int);
3000 static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
3001
3002 /*
3003 * Adv Library functions available to drivers.
3004 */
3005 static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3006 static int AdvISR(ADV_DVC_VAR *);
3007 static int AdvInitGetConfig(ADV_DVC_VAR *);
3008 static int AdvInitAsc3550Driver(ADV_DVC_VAR *);
3009 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
3010 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
3011 static int AdvResetChipAndSB(ADV_DVC_VAR *);
3012 static int AdvResetSB(ADV_DVC_VAR *asc_dvc);
3013
3014 /*
3015 * Internal Adv Library functions.
3016 */
3017 static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
3018 static int AdvInitFrom3550EEP(ADV_DVC_VAR *);
3019 static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
3020 static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
3021 static ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3022 static void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3023 static ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3024 static void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3025 static ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3026 static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3027 static void AdvWaitEEPCmd(AdvPortAddr);
3028 static ushort AdvReadEEPWord(AdvPortAddr, int);
3029
3030 /* Read byte from a register. */
3031 #define AdvReadByteRegister(iop_base, reg_off) \
3032 (ADV_MEM_READB((iop_base) + (reg_off)))
3033
3034 /* Write byte to a register. */
3035 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
3036 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3037
3038 /* Read word (2 bytes) from a register. */
3039 #define AdvReadWordRegister(iop_base, reg_off) \
3040 (ADV_MEM_READW((iop_base) + (reg_off)))
3041
3042 /* Write word (2 bytes) to a register. */
3043 #define AdvWriteWordRegister(iop_base, reg_off, word) \
3044 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
3045
3046 /* Write dword (4 bytes) to a register. */
3047 #define AdvWriteDWordRegister(iop_base, reg_off, dword) \
3048 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
3049
3050 /* Read byte from LRAM. */
3051 #define AdvReadByteLram(iop_base, addr, byte) \
3052 do { \
3053 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3054 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3055 } while (0)
3056
3057 /* Write byte to LRAM. */
3058 #define AdvWriteByteLram(iop_base, addr, byte) \
3059 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3060 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3061
3062 /* Read word (2 bytes) from LRAM. */
3063 #define AdvReadWordLram(iop_base, addr, word) \
3064 do { \
3065 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3066 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3067 } while (0)
3068
3069 /* Write word (2 bytes) to LRAM. */
3070 #define AdvWriteWordLram(iop_base, addr, word) \
3071 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3072 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3073
3074 /* Write little-endian double word (4 bytes) to LRAM */
3075 /* Because of unspecified C language ordering don't use auto-increment. */
3076 #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
3077 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3078 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3079 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3080 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3081 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3082 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3083
3084 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
3085 #define AdvReadWordAutoIncLram(iop_base) \
3086 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3087
3088 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
3089 #define AdvWriteWordAutoIncLram(iop_base, word) \
3090 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3091
3092 /*
3093 * Define macro to check for Condor signature.
3094 *
3095 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3096 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3097 */
3098 #define AdvFindSignature(iop_base) \
3099 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3100 ADV_CHIP_ID_BYTE) && \
3101 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3102 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
3103
3104 /*
3105 * Define macro to Return the version number of the chip at 'iop_base'.
3106 *
3107 * The second parameter 'bus_type' is currently unused.
3108 */
3109 #define AdvGetChipVersion(iop_base, bus_type) \
3110 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3111
3112 /*
3113 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3114 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3115 *
3116 * If the request has not yet been sent to the device it will simply be
3117 * aborted from RISC memory. If the request is disconnected it will be
3118 * aborted on reselection by sending an Abort Message to the target ID.
3119 *
3120 * Return value:
3121 * ADV_TRUE(1) - Queue was successfully aborted.
3122 * ADV_FALSE(0) - Queue was not found on the active queue list.
3123 */
3124 #define AdvAbortQueue(asc_dvc, scsiq) \
3125 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3126 (ADV_DCNT) (scsiq))
3127
3128 /*
3129 * Send a Bus Device Reset Message to the specified target ID.
3130 *
3131 * All outstanding commands will be purged if sending the
3132 * Bus Device Reset Message is successful.
3133 *
3134 * Return Value:
3135 * ADV_TRUE(1) - All requests on the target are purged.
3136 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3137 * are not purged.
3138 */
3139 #define AdvResetDevice(asc_dvc, target_id) \
3140 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3141 (ADV_DCNT) (target_id))
3142
3143 /*
3144 * SCSI Wide Type definition.
3145 */
3146 #define ADV_SCSI_BIT_ID_TYPE ushort
3147
3148 /*
3149 * AdvInitScsiTarget() 'cntl_flag' options.
3150 */
3151 #define ADV_SCAN_LUN 0x01
3152 #define ADV_CAPINFO_NOLUN 0x02
3153
3154 /*
3155 * Convert target id to target id bit mask.
3156 */
3157 #define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
3158
3159 /*
3160 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3161 */
3162
3163 #define QD_NO_STATUS 0x00 /* Request not completed yet. */
3164 #define QD_NO_ERROR 0x01
3165 #define QD_ABORTED_BY_HOST 0x02
3166 #define QD_WITH_ERROR 0x04
3167
3168 #define QHSTA_NO_ERROR 0x00
3169 #define QHSTA_M_SEL_TIMEOUT 0x11
3170 #define QHSTA_M_DATA_OVER_RUN 0x12
3171 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3172 #define QHSTA_M_QUEUE_ABORTED 0x15
3173 #define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
3174 #define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
3175 #define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
3176 #define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
3177 #define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
3178 #define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
3179 #define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
3180 /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
3181 #define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
3182 #define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
3183 #define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
3184 #define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
3185 #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
3186 #define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
3187 #define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
3188 #define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
3189 #define QHSTA_M_WTM_TIMEOUT 0x41
3190 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
3191 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
3192 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
3193 #define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
3194 #define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
3195 #define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
3196
3197 /*
3198 * Default EEPROM Configuration structure defined in a_init.c.
3199 */
3200 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
3201 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
3202 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
3203
3204 /*
3205 * DvcGetPhyAddr() flag arguments
3206 */
3207 #define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
3208 #define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
3209 #define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
3210 #define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
3211 #define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
3212 #define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
3213
3214 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
3215 #define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
3216 #define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
3217 #define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
3218
3219 /*
3220 * Total contiguous memory needed for driver SG blocks.
3221 *
3222 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3223 * number of scatter-gather elements the driver supports in a
3224 * single request.
3225 */
3226
3227 #define ADV_SG_LIST_MAX_BYTE_SIZE \
3228 (sizeof(ADV_SG_BLOCK) * \
3229 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3230
3231 /*
3232 * --- Driver Constants and Macros
3233 */
3234
3235 /* Reference Scsi_Host hostdata */
3236 #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3237
3238 /* asc_board_t flags */
3239 #define ASC_HOST_IN_RESET 0x01
3240 #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
3241 #define ASC_SELECT_QUEUE_DEPTHS 0x08
3242
3243 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3244 #define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD)
3245
3246 #define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
3247
3248 #define ASC_INFO_SIZE 128 /* advansys_info() line size */
3249
3250 #ifdef CONFIG_PROC_FS
3251 /* /proc/scsi/advansys/[0...] related definitions */
3252 #define ASC_PRTBUF_SIZE 2048
3253 #define ASC_PRTLINE_SIZE 160
3254
3255 #define ASC_PRT_NEXT() \
3256 if (cp) { \
3257 totlen += len; \
3258 leftlen -= len; \
3259 if (leftlen == 0) { \
3260 return totlen; \
3261 } \
3262 cp += len; \
3263 }
3264 #endif /* CONFIG_PROC_FS */
3265
3266 /* Asc Library return codes */
3267 #define ASC_TRUE 1
3268 #define ASC_FALSE 0
3269 #define ASC_NOERROR 1
3270 #define ASC_BUSY 0
3271 #define ASC_ERROR (-1)
3272
3273 /* struct scsi_cmnd function return codes */
3274 #define STATUS_BYTE(byte) (byte)
3275 #define MSG_BYTE(byte) ((byte) << 8)
3276 #define HOST_BYTE(byte) ((byte) << 16)
3277 #define DRIVER_BYTE(byte) ((byte) << 24)
3278
3279 /*
3280 * The following definitions and macros are OS independent interfaces to
3281 * the queue functions:
3282 * REQ - SCSI request structure
3283 * REQP - pointer to SCSI request structure
3284 * REQPTID(reqp) - reqp's target id
3285 * REQPNEXT(reqp) - reqp's next pointer
3286 * REQPNEXTP(reqp) - pointer to reqp's next pointer
3287 * REQPTIME(reqp) - reqp's time stamp value
3288 * REQTIMESTAMP() - system time stamp value
3289 */
3290 typedef struct scsi_cmnd REQ, *REQP;
3291 #define REQPNEXT(reqp) ((REQP) ((reqp)->host_scribble))
3292 #define REQPNEXTP(reqp) ((REQP *) &((reqp)->host_scribble))
3293 #define REQPTID(reqp) ((reqp)->device->id)
3294 #define REQPTIME(reqp) ((reqp)->SCp.this_residual)
3295 #define REQTIMESTAMP() (jiffies)
3296
3297 #define REQTIMESTAT(function, ascq, reqp, tid) \
3298 { \
3299 /*
3300 * If the request time stamp is less than the system time stamp, then \
3301 * maybe the system time stamp wrapped. Set the request time to zero.\
3302 */ \
3303 if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3304 REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3305 } else { \
3306 /* Indicate an error occurred with the assertion. */ \
3307 ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3308 REQPTIME(reqp) = 0; \
3309 } \
3310 /* Handle first minimum time case without external initialization. */ \
3311 if (((ascq)->q_tot_cnt[tid] == 1) || \
3312 (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3313 (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3314 ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3315 (function), (tid), (ascq)->q_min_tim[tid]); \
3316 } \
3317 if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3318 (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3319 ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3320 (function), tid, (ascq)->q_max_tim[tid]); \
3321 } \
3322 (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3323 /* Reset the time stamp field. */ \
3324 REQPTIME(reqp) = 0; \
3325 }
3326
3327 /* asc_enqueue() flags */
3328 #define ASC_FRONT 1
3329 #define ASC_BACK 2
3330
3331 /* asc_dequeue_list() argument */
3332 #define ASC_TID_ALL (-1)
3333
3334 /* Return non-zero, if the queue is empty. */
3335 #define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0)
3336
3337 #ifndef ADVANSYS_STATS
3338 #define ASC_STATS(shost, counter)
3339 #define ASC_STATS_ADD(shost, counter, count)
3340 #else /* ADVANSYS_STATS */
3341 #define ASC_STATS(shost, counter) \
3342 (ASC_BOARDP(shost)->asc_stats.counter++)
3343
3344 #define ASC_STATS_ADD(shost, counter, count) \
3345 (ASC_BOARDP(shost)->asc_stats.counter += (count))
3346 #endif /* ADVANSYS_STATS */
3347
3348 #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3349
3350 /* If the result wraps when calculating tenths, return 0. */
3351 #define ASC_TENTHS(num, den) \
3352 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3353 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3354
3355 /*
3356 * Display a message to the console.
3357 */
3358 #define ASC_PRINT(s) \
3359 { \
3360 printk("advansys: "); \
3361 printk(s); \
3362 }
3363
3364 #define ASC_PRINT1(s, a1) \
3365 { \
3366 printk("advansys: "); \
3367 printk((s), (a1)); \
3368 }
3369
3370 #define ASC_PRINT2(s, a1, a2) \
3371 { \
3372 printk("advansys: "); \
3373 printk((s), (a1), (a2)); \
3374 }
3375
3376 #define ASC_PRINT3(s, a1, a2, a3) \
3377 { \
3378 printk("advansys: "); \
3379 printk((s), (a1), (a2), (a3)); \
3380 }
3381
3382 #define ASC_PRINT4(s, a1, a2, a3, a4) \
3383 { \
3384 printk("advansys: "); \
3385 printk((s), (a1), (a2), (a3), (a4)); \
3386 }
3387
3388 #ifndef ADVANSYS_DEBUG
3389
3390 #define ASC_DBG(lvl, s)
3391 #define ASC_DBG1(lvl, s, a1)
3392 #define ASC_DBG2(lvl, s, a1, a2)
3393 #define ASC_DBG3(lvl, s, a1, a2, a3)
3394 #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3395 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3396 #define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3397 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3398 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3399 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3400 #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3401 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
3402 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
3403 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
3404 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3405
3406 #else /* ADVANSYS_DEBUG */
3407
3408 /*
3409 * Debugging Message Levels:
3410 * 0: Errors Only
3411 * 1: High-Level Tracing
3412 * 2-N: Verbose Tracing
3413 */
3414
3415 #define ASC_DBG(lvl, s) \
3416 { \
3417 if (asc_dbglvl >= (lvl)) { \
3418 printk(s); \
3419 } \
3420 }
3421
3422 #define ASC_DBG1(lvl, s, a1) \
3423 { \
3424 if (asc_dbglvl >= (lvl)) { \
3425 printk((s), (a1)); \
3426 } \
3427 }
3428
3429 #define ASC_DBG2(lvl, s, a1, a2) \
3430 { \
3431 if (asc_dbglvl >= (lvl)) { \
3432 printk((s), (a1), (a2)); \
3433 } \
3434 }
3435
3436 #define ASC_DBG3(lvl, s, a1, a2, a3) \
3437 { \
3438 if (asc_dbglvl >= (lvl)) { \
3439 printk((s), (a1), (a2), (a3)); \
3440 } \
3441 }
3442
3443 #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3444 { \
3445 if (asc_dbglvl >= (lvl)) { \
3446 printk((s), (a1), (a2), (a3), (a4)); \
3447 } \
3448 }
3449
3450 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3451 { \
3452 if (asc_dbglvl >= (lvl)) { \
3453 asc_prt_scsi_host(s); \
3454 } \
3455 }
3456
3457 #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3458 { \
3459 if (asc_dbglvl >= (lvl)) { \
3460 asc_prt_scsi_cmnd(s); \
3461 } \
3462 }
3463
3464 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3465 { \
3466 if (asc_dbglvl >= (lvl)) { \
3467 asc_prt_asc_scsi_q(scsiqp); \
3468 } \
3469 }
3470
3471 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3472 { \
3473 if (asc_dbglvl >= (lvl)) { \
3474 asc_prt_asc_qdone_info(qdone); \
3475 } \
3476 }
3477
3478 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3479 { \
3480 if (asc_dbglvl >= (lvl)) { \
3481 asc_prt_adv_scsi_req_q(scsiqp); \
3482 } \
3483 }
3484
3485 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3486 { \
3487 if (asc_dbglvl >= (lvl)) { \
3488 asc_prt_hex((name), (start), (length)); \
3489 } \
3490 }
3491
3492 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3493 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3494
3495 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3496 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3497
3498 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3499 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3500 #endif /* ADVANSYS_DEBUG */
3501
3502 #ifndef ADVANSYS_ASSERT
3503 #define ASC_ASSERT(a)
3504 #else /* ADVANSYS_ASSERT */
3505
3506 #define ASC_ASSERT(a) \
3507 { \
3508 if (!(a)) { \
3509 printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3510 __FILE__, __LINE__); \
3511 } \
3512 }
3513
3514 #endif /* ADVANSYS_ASSERT */
3515
3516 /*
3517 * --- Driver Structures
3518 */
3519
3520 #ifdef ADVANSYS_STATS
3521
3522 /* Per board statistics structure */
3523 struct asc_stats {
3524 /* Driver Entrypoint Statistics */
3525 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
3526 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
3527 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
3528 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
3529 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
3530 ADV_DCNT done; /* # calls to request's scsi_done function */
3531 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
3532 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
3533 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
3534 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3535 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
3536 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
3537 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
3538 ADV_DCNT exe_unknown; /* # unknown returns. */
3539 /* Data Transfer Statistics */
3540 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
3541 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
3542 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
3543 ADV_DCNT sg_elem; /* # scatter-gather elements */
3544 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
3545 };
3546 #endif /* ADVANSYS_STATS */
3547
3548 /*
3549 * Request queuing structure
3550 */
3551 typedef struct asc_queue {
3552 ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */
3553 REQP q_first[ADV_MAX_TID + 1]; /* first queued request */
3554 REQP q_last[ADV_MAX_TID + 1]; /* last queued request */
3555 #ifdef ADVANSYS_STATS
3556 short q_cur_cnt[ADV_MAX_TID + 1]; /* current queue count */
3557 short q_max_cnt[ADV_MAX_TID + 1]; /* maximum queue count */
3558 ADV_DCNT q_tot_cnt[ADV_MAX_TID + 1]; /* total enqueue count */
3559 ADV_DCNT q_tot_tim[ADV_MAX_TID + 1]; /* total time queued */
3560 ushort q_max_tim[ADV_MAX_TID + 1]; /* maximum time queued */
3561 ushort q_min_tim[ADV_MAX_TID + 1]; /* minimum time queued */
3562 #endif /* ADVANSYS_STATS */
3563 } asc_queue_t;
3564
3565 /*
3566 * Adv Library Request Structures
3567 *
3568 * The following two structures are used to process Wide Board requests.
3569 *
3570 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
3571 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
3572 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
3573 * Mid-Level SCSI request structure.
3574 *
3575 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
3576 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
3577 * up to 255 scatter-gather elements may be used per request or
3578 * ADV_SCSI_REQ_Q.
3579 *
3580 * Both structures must be 32 byte aligned.
3581 */
3582 typedef struct adv_sgblk {
3583 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
3584 uchar align[32]; /* Sgblock structure padding. */
3585 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
3586 } adv_sgblk_t;
3587
3588 typedef struct adv_req {
3589 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
3590 uchar align[32]; /* Request structure padding. */
3591 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
3592 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
3593 struct adv_req *next_reqp; /* Next Request Structure. */
3594 } adv_req_t;
3595
3596 /*
3597 * Structure allocated for each board.
3598 *
3599 * This structure is allocated by scsi_host_alloc() at the end
3600 * of the 'Scsi_Host' structure starting at the 'hostdata'
3601 * field. It is guaranteed to be allocated from DMA-able memory.
3602 */
3603 typedef struct asc_board {
3604 int id; /* Board Id */
3605 uint flags; /* Board flags */
3606 union {
3607 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
3608 ADV_DVC_VAR adv_dvc_var; /* Wide board */
3609 } dvc_var;
3610 union {
3611 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
3612 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
3613 } dvc_cfg;
3614 ushort asc_n_io_port; /* Number I/O ports. */
3615 asc_queue_t active; /* Active command queue */
3616 asc_queue_t waiting; /* Waiting command queue */
3617 asc_queue_t done; /* Done command queue */
3618 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
3619 struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */
3620 ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
3621 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
3622 ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
3623 union {
3624 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
3625 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
3626 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
3627 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
3628 } eep_config;
3629 ulong last_reset; /* Saved last reset time */
3630 spinlock_t lock; /* Board spinlock */
3631 /* /proc/scsi/advansys/[0...] */
3632 char *prtbuf; /* /proc print buffer */
3633 #ifdef ADVANSYS_STATS
3634 struct asc_stats asc_stats; /* Board statistics */
3635 #endif /* ADVANSYS_STATS */
3636 /*
3637 * The following fields are used only for Narrow Boards.
3638 */
3639 uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */
3640 /*
3641 * The following fields are used only for Wide Boards.
3642 */
3643 void __iomem *ioremap_addr; /* I/O Memory remap address. */
3644 ushort ioport; /* I/O Port address. */
3645 ADV_CARR_T *carrp; /* ADV_CARR_T memory block. */
3646 adv_req_t *orig_reqp; /* adv_req_t memory block. */
3647 adv_req_t *adv_reqp; /* Request structures. */
3648 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
3649 ushort bios_signature; /* BIOS Signature. */
3650 ushort bios_version; /* BIOS Version. */
3651 ushort bios_codeseg; /* BIOS Code Segment. */
3652 ushort bios_codelen; /* BIOS Code Segment Length. */
3653 } asc_board_t;
3654
3655 /* Number of boards detected in system. */
3656 static int asc_board_count;
3657
3658 /* Overrun buffer used by all narrow boards. */
3659 static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
3660
3661 /*
3662 * Global structures required to issue a command.
3663 */
3664 static ASC_SCSI_Q asc_scsi_q = { {0} };
3665 static ASC_SG_HEAD asc_sg_head = { 0 };
3666
3667 #ifdef ADVANSYS_DEBUG
3668 static int asc_dbglvl = 3;
3669 #endif /* ADVANSYS_DEBUG */
3670
3671 /*
3672 * --- Driver Function Prototypes
3673 */
3674
3675 static int advansys_slave_configure(struct scsi_device *);
3676 static void asc_scsi_done_list(struct scsi_cmnd *);
3677 static int asc_execute_scsi_cmnd(struct scsi_cmnd *);
3678 static int asc_build_req(asc_board_t *, struct scsi_cmnd *);
3679 static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
3680 static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
3681 static void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
3682 static void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3683 static void adv_async_callback(ADV_DVC_VAR *, uchar);
3684 static void asc_enqueue(asc_queue_t *, REQP, int);
3685 static REQP asc_dequeue(asc_queue_t *, int);
3686 static REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
3687 static int asc_rmqueue(asc_queue_t *, REQP);
3688 static void asc_execute_queue(asc_queue_t *);
3689 #ifdef CONFIG_PROC_FS
3690 static int asc_proc_copy(off_t, off_t, char *, int, char *, int);
3691 static int asc_prt_board_devices(struct Scsi_Host *, char *, int);
3692 static int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
3693 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
3694 static int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
3695 static int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
3696 static int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
3697 static int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
3698 static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
3699 static int asc_prt_line(char *, int, char *fmt, ...);
3700 #endif /* CONFIG_PROC_FS */
3701
3702 /* Statistics function prototypes. */
3703 #ifdef ADVANSYS_STATS
3704 #ifdef CONFIG_PROC_FS
3705 static int asc_prt_board_stats(struct Scsi_Host *, char *, int);
3706 static int asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
3707 #endif /* CONFIG_PROC_FS */
3708 #endif /* ADVANSYS_STATS */
3709
3710 /* Debug function prototypes. */
3711 #ifdef ADVANSYS_DEBUG
3712 static void asc_prt_scsi_host(struct Scsi_Host *);
3713 static void asc_prt_scsi_cmnd(struct scsi_cmnd *);
3714 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
3715 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
3716 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
3717 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
3718 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
3719 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
3720 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
3721 static void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
3722 static void asc_prt_hex(char *f, uchar *, int);
3723 #endif /* ADVANSYS_DEBUG */
3724
3725 #ifdef CONFIG_PROC_FS
3726 /*
3727 * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
3728 *
3729 * *buffer: I/O buffer
3730 * **start: if inout == FALSE pointer into buffer where user read should start
3731 * offset: current offset into a /proc/scsi/advansys/[0...] file
3732 * length: length of buffer
3733 * hostno: Scsi_Host host_no
3734 * inout: TRUE - user is writing; FALSE - user is reading
3735 *
3736 * Return the number of bytes read from or written to a
3737 * /proc/scsi/advansys/[0...] file.
3738 *
3739 * Note: This function uses the per board buffer 'prtbuf' which is
3740 * allocated when the board is initialized in advansys_detect(). The
3741 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
3742 * used to write to the buffer. The way asc_proc_copy() is written
3743 * if 'prtbuf' is too small it will not be overwritten. Instead the
3744 * user just won't get all the available statistics.
3745 */
3746 static int
3747 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
3748 off_t offset, int length, int inout)
3749 {
3750 asc_board_t *boardp;
3751 char *cp;
3752 int cplen;
3753 int cnt;
3754 int totcnt;
3755 int leftlen;
3756 char *curbuf;
3757 off_t advoffset;
3758 #ifdef ADVANSYS_STATS
3759 int tgt_id;
3760 #endif /* ADVANSYS_STATS */
3761
3762 ASC_DBG(1, "advansys_proc_info: begin\n");
3763
3764 /*
3765 * User write not supported.
3766 */
3767 if (inout == TRUE) {
3768 return (-ENOSYS);
3769 }
3770
3771 /*
3772 * User read of /proc/scsi/advansys/[0...] file.
3773 */
3774
3775 boardp = ASC_BOARDP(shost);
3776
3777 /* Copy read data starting at the beginning of the buffer. */
3778 *start = buffer;
3779 curbuf = buffer;
3780 advoffset = 0;
3781 totcnt = 0;
3782 leftlen = length;
3783
3784 /*
3785 * Get board configuration information.
3786 *
3787 * advansys_info() returns the board string from its own static buffer.
3788 */
3789 cp = (char *)advansys_info(shost);
3790 strcat(cp, "\n");
3791 cplen = strlen(cp);
3792 /* Copy board information. */
3793 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3794 totcnt += cnt;
3795 leftlen -= cnt;
3796 if (leftlen == 0) {
3797 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3798 return totcnt;
3799 }
3800 advoffset += cplen;
3801 curbuf += cnt;
3802
3803 /*
3804 * Display Wide Board BIOS Information.
3805 */
3806 if (ASC_WIDE_BOARD(boardp)) {
3807 cp = boardp->prtbuf;
3808 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
3809 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3810 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
3811 cplen);
3812 totcnt += cnt;
3813 leftlen -= cnt;
3814 if (leftlen == 0) {
3815 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3816 return totcnt;
3817 }
3818 advoffset += cplen;
3819 curbuf += cnt;
3820 }
3821
3822 /*
3823 * Display driver information for each device attached to the board.
3824 */
3825 cp = boardp->prtbuf;
3826 cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
3827 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3828 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3829 totcnt += cnt;
3830 leftlen -= cnt;
3831 if (leftlen == 0) {
3832 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3833 return totcnt;
3834 }
3835 advoffset += cplen;
3836 curbuf += cnt;
3837
3838 /*
3839 * Display EEPROM configuration for the board.
3840 */
3841 cp = boardp->prtbuf;
3842 if (ASC_NARROW_BOARD(boardp)) {
3843 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
3844 } else {
3845 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
3846 }
3847 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3848 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3849 totcnt += cnt;
3850 leftlen -= cnt;
3851 if (leftlen == 0) {
3852 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3853 return totcnt;
3854 }
3855 advoffset += cplen;
3856 curbuf += cnt;
3857
3858 /*
3859 * Display driver configuration and information for the board.
3860 */
3861 cp = boardp->prtbuf;
3862 cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
3863 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3864 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3865 totcnt += cnt;
3866 leftlen -= cnt;
3867 if (leftlen == 0) {
3868 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3869 return totcnt;
3870 }
3871 advoffset += cplen;
3872 curbuf += cnt;
3873
3874 #ifdef ADVANSYS_STATS
3875 /*
3876 * Display driver statistics for the board.
3877 */
3878 cp = boardp->prtbuf;
3879 cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
3880 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
3881 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3882 totcnt += cnt;
3883 leftlen -= cnt;
3884 if (leftlen == 0) {
3885 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3886 return totcnt;
3887 }
3888 advoffset += cplen;
3889 curbuf += cnt;
3890
3891 /*
3892 * Display driver statistics for each target.
3893 */
3894 for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
3895 cp = boardp->prtbuf;
3896 cplen = asc_prt_target_stats(shost, tgt_id, cp,
3897 ASC_PRTBUF_SIZE);
3898 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
3899 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
3900 cplen);
3901 totcnt += cnt;
3902 leftlen -= cnt;
3903 if (leftlen == 0) {
3904 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3905 return totcnt;
3906 }
3907 advoffset += cplen;
3908 curbuf += cnt;
3909 }
3910 #endif /* ADVANSYS_STATS */
3911
3912 /*
3913 * Display Asc Library dynamic configuration information
3914 * for the board.
3915 */
3916 cp = boardp->prtbuf;
3917 if (ASC_NARROW_BOARD(boardp)) {
3918 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
3919 } else {
3920 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
3921 }
3922 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3923 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3924 totcnt += cnt;
3925 leftlen -= cnt;
3926 if (leftlen == 0) {
3927 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3928 return totcnt;
3929 }
3930 advoffset += cplen;
3931 curbuf += cnt;
3932
3933 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3934
3935 return totcnt;
3936 }
3937 #endif /* CONFIG_PROC_FS */
3938
3939 /*
3940 * advansys_info()
3941 *
3942 * Return suitable for printing on the console with the argument
3943 * adapter's configuration information.
3944 *
3945 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
3946 * otherwise the static 'info' array will be overrun.
3947 */
3948 static const char *advansys_info(struct Scsi_Host *shost)
3949 {
3950 static char info[ASC_INFO_SIZE];
3951 asc_board_t *boardp;
3952 ASC_DVC_VAR *asc_dvc_varp;
3953 ADV_DVC_VAR *adv_dvc_varp;
3954 char *busname;
3955 int iolen;
3956 char *widename = NULL;
3957
3958 boardp = ASC_BOARDP(shost);
3959 if (ASC_NARROW_BOARD(boardp)) {
3960 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3961 ASC_DBG(1, "advansys_info: begin\n");
3962 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
3963 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
3964 ASC_IS_ISAPNP) {
3965 busname = "ISA PnP";
3966 } else {
3967 busname = "ISA";
3968 }
3969 /* Don't reference 'shost->n_io_port'; It may be truncated. */
3970 sprintf(info,
3971 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
3972 ASC_VERSION, busname,
3973 (ulong)shost->io_port,
3974 (ulong)shost->io_port + boardp->asc_n_io_port -
3975 1, shost->irq, shost->dma_channel);
3976 } else {
3977 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
3978 busname = "VL";
3979 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
3980 busname = "EISA";
3981 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
3982 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
3983 == ASC_IS_PCI_ULTRA) {
3984 busname = "PCI Ultra";
3985 } else {
3986 busname = "PCI";
3987 }
3988 } else {
3989 busname = "?";
3990 ASC_PRINT2("advansys_info: board %d: unknown "
3991 "bus type %d\n", boardp->id,
3992 asc_dvc_varp->bus_type);
3993 }
3994 /* Don't reference 'shost->n_io_port'; It may be truncated. */
3995 sprintf(info,
3996 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
3997 ASC_VERSION, busname, (ulong)shost->io_port,
3998 (ulong)shost->io_port + boardp->asc_n_io_port -
3999 1, shost->irq);
4000 }
4001 } else {
4002 /*
4003 * Wide Adapter Information
4004 *
4005 * Memory-mapped I/O is used instead of I/O space to access
4006 * the adapter, but display the I/O Port range. The Memory
4007 * I/O address is displayed through the driver /proc file.
4008 */
4009 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4010 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4011 iolen = ADV_3550_IOLEN;
4012 widename = "Ultra-Wide";
4013 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4014 iolen = ADV_38C0800_IOLEN;
4015 widename = "Ultra2-Wide";
4016 } else {
4017 iolen = ADV_38C1600_IOLEN;
4018 widename = "Ultra3-Wide";
4019 }
4020 sprintf(info,
4021 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
4022 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
4023 (ulong)adv_dvc_varp->iop_base + iolen - 1, shost->irq);
4024 }
4025 ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
4026 ASC_DBG(1, "advansys_info: end\n");
4027 return info;
4028 }
4029
4030 /*
4031 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
4032 *
4033 * This function always returns 0. Command return status is saved
4034 * in the 'scp' result field.
4035 */
4036 static int
4037 advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *))
4038 {
4039 struct Scsi_Host *shost;
4040 asc_board_t *boardp;
4041 ulong flags;
4042 struct scsi_cmnd *done_scp;
4043
4044 shost = scp->device->host;
4045 boardp = ASC_BOARDP(shost);
4046 ASC_STATS(shost, queuecommand);
4047
4048 /* host_lock taken by mid-level prior to call but need to protect */
4049 /* against own ISR */
4050 spin_lock_irqsave(&boardp->lock, flags);
4051
4052 /*
4053 * Block new commands while handling a reset or abort request.
4054 */
4055 if (boardp->flags & ASC_HOST_IN_RESET) {
4056 ASC_DBG1(1,
4057 "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
4058 (ulong)scp);
4059 scp->result = HOST_BYTE(DID_RESET);
4060
4061 /*
4062 * Add blocked requests to the board's 'done' queue. The queued
4063 * requests will be completed at the end of the abort or reset
4064 * handling.
4065 */
4066 asc_enqueue(&boardp->done, scp, ASC_BACK);
4067 spin_unlock_irqrestore(&boardp->lock, flags);
4068 return 0;
4069 }
4070
4071 /*
4072 * Attempt to execute any waiting commands for the board.
4073 */
4074 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4075 ASC_DBG(1,
4076 "advansys_queuecommand: before asc_execute_queue() waiting\n");
4077 asc_execute_queue(&boardp->waiting);
4078 }
4079
4080 /*
4081 * Save the function pointer to Linux mid-level 'done' function
4082 * and attempt to execute the command.
4083 *
4084 * If ASC_NOERROR is returned the request has been added to the
4085 * board's 'active' queue and will be completed by the interrupt
4086 * handler.
4087 *
4088 * If ASC_BUSY is returned add the request to the board's per
4089 * target waiting list. This is the first time the request has
4090 * been tried. Add it to the back of the waiting list. It will be
4091 * retried later.
4092 *
4093 * If an error occurred, the request will have been placed on the
4094 * board's 'done' queue and must be completed before returning.
4095 */
4096 scp->scsi_done = done;
4097 switch (asc_execute_scsi_cmnd(scp)) {
4098 case ASC_NOERROR:
4099 break;
4100 case ASC_BUSY:
4101 asc_enqueue(&boardp->waiting, scp, ASC_BACK);
4102 break;
4103 case ASC_ERROR:
4104 default:
4105 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
4106 /* Interrupts could be enabled here. */
4107 asc_scsi_done_list(done_scp);
4108 break;
4109 }
4110 spin_unlock_irqrestore(&boardp->lock, flags);
4111
4112 return 0;
4113 }
4114
4115 /*
4116 * advansys_reset()
4117 *
4118 * Reset the bus associated with the command 'scp'.
4119 *
4120 * This function runs its own thread. Interrupts must be blocked but
4121 * sleeping is allowed and no locking other than for host structures is
4122 * required. Returns SUCCESS or FAILED.
4123 */
4124 static int advansys_reset(struct scsi_cmnd *scp)
4125 {
4126 struct Scsi_Host *shost;
4127 asc_board_t *boardp;
4128 ASC_DVC_VAR *asc_dvc_varp;
4129 ADV_DVC_VAR *adv_dvc_varp;
4130 ulong flags;
4131 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4132 struct scsi_cmnd *tscp, *new_last_scp;
4133 int status;
4134 int ret = SUCCESS;
4135
4136 ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp);
4137
4138 #ifdef ADVANSYS_STATS
4139 if (scp->device->host != NULL) {
4140 ASC_STATS(scp->device->host, reset);
4141 }
4142 #endif /* ADVANSYS_STATS */
4143
4144 if ((shost = scp->device->host) == NULL) {
4145 scp->result = HOST_BYTE(DID_ERROR);
4146 return FAILED;
4147 }
4148
4149 boardp = ASC_BOARDP(shost);
4150
4151 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
4152 boardp->id);
4153 /*
4154 * Check for re-entrancy.
4155 */
4156 spin_lock_irqsave(&boardp->lock, flags);
4157 if (boardp->flags & ASC_HOST_IN_RESET) {
4158 spin_unlock_irqrestore(&boardp->lock, flags);
4159 return FAILED;
4160 }
4161 boardp->flags |= ASC_HOST_IN_RESET;
4162 spin_unlock_irqrestore(&boardp->lock, flags);
4163
4164 if (ASC_NARROW_BOARD(boardp)) {
4165 /*
4166 * Narrow Board
4167 */
4168 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4169
4170 /*
4171 * Reset the chip and SCSI bus.
4172 */
4173 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
4174 status = AscInitAsc1000Driver(asc_dvc_varp);
4175
4176 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
4177 if (asc_dvc_varp->err_code) {
4178 ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
4179 "error: 0x%x\n", boardp->id,
4180 asc_dvc_varp->err_code);
4181 ret = FAILED;
4182 } else if (status) {
4183 ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
4184 "warning: 0x%x\n", boardp->id, status);
4185 } else {
4186 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
4187 "successful.\n", boardp->id);
4188 }
4189
4190 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
4191 spin_lock_irqsave(&boardp->lock, flags);
4192
4193 } else {
4194 /*
4195 * Wide Board
4196 *
4197 * If the suggest reset bus flags are set, then reset the bus.
4198 * Otherwise only reset the device.
4199 */
4200 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4201
4202 /*
4203 * Reset the target's SCSI bus.
4204 */
4205 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
4206 switch (AdvResetChipAndSB(adv_dvc_varp)) {
4207 case ASC_TRUE:
4208 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
4209 "successful.\n", boardp->id);
4210 break;
4211 case ASC_FALSE:
4212 default:
4213 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
4214 "error.\n", boardp->id);
4215 ret = FAILED;
4216 break;
4217 }
4218 spin_lock_irqsave(&boardp->lock, flags);
4219 (void)AdvISR(adv_dvc_varp);
4220 }
4221 /* Board lock is held. */
4222
4223 /*
4224 * Dequeue all board 'done' requests. A pointer to the last request
4225 * is returned in 'last_scp'.
4226 */
4227 done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
4228
4229 /*
4230 * Dequeue all board 'active' requests for all devices and set
4231 * the request status to DID_RESET. A pointer to the last request
4232 * is returned in 'last_scp'.
4233 */
4234 if (done_scp == NULL) {
4235 done_scp = asc_dequeue_list(&boardp->active, &last_scp,
4236 ASC_TID_ALL);
4237 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4238 tscp->result = HOST_BYTE(DID_RESET);
4239 }
4240 } else {
4241 /* Append to 'done_scp' at the end with 'last_scp'. */
4242 ASC_ASSERT(last_scp != NULL);
4243 last_scp->host_scribble =
4244 (unsigned char *)asc_dequeue_list(&boardp->active,
4245 &new_last_scp,
4246 ASC_TID_ALL);
4247 if (new_last_scp != NULL) {
4248 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4249 for (tscp = REQPNEXT(last_scp); tscp;
4250 tscp = REQPNEXT(tscp)) {
4251 tscp->result = HOST_BYTE(DID_RESET);
4252 }
4253 last_scp = new_last_scp;
4254 }
4255 }
4256
4257 /*
4258 * Dequeue all 'waiting' requests and set the request status
4259 * to DID_RESET.
4260 */
4261 if (done_scp == NULL) {
4262 done_scp = asc_dequeue_list(&boardp->waiting, &last_scp,
4263 ASC_TID_ALL);
4264 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4265 tscp->result = HOST_BYTE(DID_RESET);
4266 }
4267 } else {
4268 /* Append to 'done_scp' at the end with 'last_scp'. */
4269 ASC_ASSERT(last_scp != NULL);
4270 last_scp->host_scribble =
4271 (unsigned char *)asc_dequeue_list(&boardp->waiting,
4272 &new_last_scp,
4273 ASC_TID_ALL);
4274 if (new_last_scp != NULL) {
4275 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4276 for (tscp = REQPNEXT(last_scp); tscp;
4277 tscp = REQPNEXT(tscp)) {
4278 tscp->result = HOST_BYTE(DID_RESET);
4279 }
4280 last_scp = new_last_scp;
4281 }
4282 }
4283
4284 /* Save the time of the most recently completed reset. */
4285 boardp->last_reset = jiffies;
4286
4287 /* Clear reset flag. */
4288 boardp->flags &= ~ASC_HOST_IN_RESET;
4289 spin_unlock_irqrestore(&boardp->lock, flags);
4290
4291 /*
4292 * Complete all the 'done_scp' requests.
4293 */
4294 if (done_scp)
4295 asc_scsi_done_list(done_scp);
4296
4297 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
4298
4299 return ret;
4300 }
4301
4302 /*
4303 * advansys_biosparam()
4304 *
4305 * Translate disk drive geometry if the "BIOS greater than 1 GB"
4306 * support is enabled for a drive.
4307 *
4308 * ip (information pointer) is an int array with the following definition:
4309 * ip[0]: heads
4310 * ip[1]: sectors
4311 * ip[2]: cylinders
4312 */
4313 static int
4314 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
4315 sector_t capacity, int ip[])
4316 {
4317 asc_board_t *boardp;
4318
4319 ASC_DBG(1, "advansys_biosparam: begin\n");
4320 ASC_STATS(sdev->host, biosparam);
4321 boardp = ASC_BOARDP(sdev->host);
4322 if (ASC_NARROW_BOARD(boardp)) {
4323 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
4324 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
4325 ip[0] = 255;
4326 ip[1] = 63;
4327 } else {
4328 ip[0] = 64;
4329 ip[1] = 32;
4330 }
4331 } else {
4332 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
4333 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
4334 ip[0] = 255;
4335 ip[1] = 63;
4336 } else {
4337 ip[0] = 64;
4338 ip[1] = 32;
4339 }
4340 }
4341 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
4342 ASC_DBG(1, "advansys_biosparam: end\n");
4343 return 0;
4344 }
4345
4346 static struct scsi_host_template advansys_template = {
4347 .proc_name = "advansys",
4348 #ifdef CONFIG_PROC_FS
4349 .proc_info = advansys_proc_info,
4350 #endif
4351 .name = "advansys",
4352 .info = advansys_info,
4353 .queuecommand = advansys_queuecommand,
4354 .eh_bus_reset_handler = advansys_reset,
4355 .bios_param = advansys_biosparam,
4356 .slave_configure = advansys_slave_configure,
4357 /*
4358 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
4359 * must be set. The flag will be cleared in advansys_board_found
4360 * for non-ISA adapters.
4361 */
4362 .unchecked_isa_dma = 1,
4363 /*
4364 * All adapters controlled by this driver are capable of large
4365 * scatter-gather lists. According to the mid-level SCSI documentation
4366 * this obviates any performance gain provided by setting
4367 * 'use_clustering'. But empirically while CPU utilization is increased
4368 * by enabling clustering, I/O throughput increases as well.
4369 */
4370 .use_clustering = ENABLE_CLUSTERING,
4371 };
4372
4373 /*
4374 * --- Miscellaneous Driver Functions
4375 */
4376
4377 /*
4378 * First-level interrupt handler.
4379 *
4380 * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
4381 * all boards are currently checked for interrupts on each interrupt, 'dev_id'
4382 * is not referenced. 'dev_id' could be used to identify an interrupt passed
4383 * to the AdvanSys driver which is for a device sharing an interrupt with
4384 * an AdvanSys adapter.
4385 */
4386 static irqreturn_t advansys_interrupt(int irq, void *dev_id)
4387 {
4388 unsigned long flags;
4389 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4390 struct scsi_cmnd *new_last_scp;
4391 struct Scsi_Host *shost = dev_id;
4392 asc_board_t *boardp = ASC_BOARDP(shost);
4393 irqreturn_t result = IRQ_NONE;
4394
4395 ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp);
4396 spin_lock_irqsave(&boardp->lock, flags);
4397 if (ASC_NARROW_BOARD(boardp)) {
4398 /*
4399 * Narrow Board
4400 */
4401 if (AscIsIntPending(shost->io_port)) {
4402 result = IRQ_HANDLED;
4403 ASC_STATS(shost, interrupt);
4404 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
4405 AscISR(&boardp->dvc_var.asc_dvc_var);
4406 }
4407 } else {
4408 /*
4409 * Wide Board
4410 */
4411 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
4412 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
4413 result = IRQ_HANDLED;
4414 ASC_STATS(shost, interrupt);
4415 }
4416 }
4417
4418 /*
4419 * Start waiting requests and create a list of completed requests.
4420 *
4421 * If a reset request is being performed for the board, the reset
4422 * handler will complete pending requests after it has completed.
4423 */
4424 if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
4425 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%p, "
4426 "last_scp 0x%p\n", done_scp, last_scp);
4427
4428 /* Start any waiting commands for the board. */
4429 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4430 ASC_DBG(1, "advansys_interrupt: before "
4431 "asc_execute_queue()\n");
4432 asc_execute_queue(&boardp->waiting);
4433 }
4434
4435 /*
4436 * Add to the list of requests that must be completed.
4437 *
4438 * 'done_scp' will always be NULL on the first iteration of
4439 * this loop. 'last_scp' is set at the same time as 'done_scp'.
4440 */
4441 if (done_scp == NULL) {
4442 done_scp = asc_dequeue_list(&boardp->done,
4443 &last_scp, ASC_TID_ALL);
4444 } else {
4445 ASC_ASSERT(last_scp != NULL);
4446 last_scp->host_scribble =
4447 (unsigned char *)asc_dequeue_list(&boardp->
4448 done,
4449 &new_last_scp,
4450 ASC_TID_ALL);
4451 if (new_last_scp != NULL) {
4452 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4453 last_scp = new_last_scp;
4454 }
4455 }
4456 }
4457 spin_unlock_irqrestore(&boardp->lock, flags);
4458
4459 /*
4460 * If interrupts were enabled on entry, then they
4461 * are now enabled here.
4462 *
4463 * Complete all requests on the done list.
4464 */
4465
4466 asc_scsi_done_list(done_scp);
4467
4468 ASC_DBG(1, "advansys_interrupt: end\n");
4469 return result;
4470 }
4471
4472 static void
4473 advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
4474 {
4475 ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
4476 ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
4477
4478 if (sdev->lun == 0) {
4479 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
4480 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
4481 asc_dvc->init_sdtr |= tid_bit;
4482 } else {
4483 asc_dvc->init_sdtr &= ~tid_bit;
4484 }
4485
4486 if (orig_init_sdtr != asc_dvc->init_sdtr)
4487 AscAsyncFix(asc_dvc, sdev);
4488 }
4489
4490 if (sdev->tagged_supported) {
4491 if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
4492 if (sdev->lun == 0) {
4493 asc_dvc->cfg->can_tagged_qng |= tid_bit;
4494 asc_dvc->use_tagged_qng |= tid_bit;
4495 }
4496 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
4497 asc_dvc->max_dvc_qng[sdev->id]);
4498 }
4499 } else {
4500 if (sdev->lun == 0) {
4501 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
4502 asc_dvc->use_tagged_qng &= ~tid_bit;
4503 }
4504 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
4505 }
4506
4507 if ((sdev->lun == 0) &&
4508 (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
4509 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
4510 asc_dvc->cfg->disc_enable);
4511 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
4512 asc_dvc->use_tagged_qng);
4513 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
4514 asc_dvc->cfg->can_tagged_qng);
4515
4516 asc_dvc->max_dvc_qng[sdev->id] =
4517 asc_dvc->cfg->max_tag_qng[sdev->id];
4518 AscWriteLramByte(asc_dvc->iop_base,
4519 (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
4520 asc_dvc->max_dvc_qng[sdev->id]);
4521 }
4522 }
4523
4524 /*
4525 * Wide Transfers
4526 *
4527 * If the EEPROM enabled WDTR for the device and the device supports wide
4528 * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and
4529 * write the new value to the microcode.
4530 */
4531 static void
4532 advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
4533 {
4534 unsigned short cfg_word;
4535 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
4536 if ((cfg_word & tidmask) != 0)
4537 return;
4538
4539 cfg_word |= tidmask;
4540 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
4541
4542 /*
4543 * Clear the microcode SDTR and WDTR negotiation done indicators for
4544 * the target to cause it to negotiate with the new setting set above.
4545 * WDTR when accepted causes the target to enter asynchronous mode, so
4546 * SDTR must be negotiated.
4547 */
4548 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
4549 cfg_word &= ~tidmask;
4550 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
4551 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
4552 cfg_word &= ~tidmask;
4553 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
4554 }
4555
4556 /*
4557 * Synchronous Transfers
4558 *
4559 * If the EEPROM enabled SDTR for the device and the device
4560 * supports synchronous transfers, then turn on the device's
4561 * 'sdtr_able' bit. Write the new value to the microcode.
4562 */
4563 static void
4564 advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
4565 {
4566 unsigned short cfg_word;
4567 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
4568 if ((cfg_word & tidmask) != 0)
4569 return;
4570
4571 cfg_word |= tidmask;
4572 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
4573
4574 /*
4575 * Clear the microcode "SDTR negotiation" done indicator for the
4576 * target to cause it to negotiate with the new setting set above.
4577 */
4578 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
4579 cfg_word &= ~tidmask;
4580 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
4581 }
4582
4583 /*
4584 * PPR (Parallel Protocol Request) Capable
4585 *
4586 * If the device supports DT mode, then it must be PPR capable.
4587 * The PPR message will be used in place of the SDTR and WDTR
4588 * messages to negotiate synchronous speed and offset, transfer
4589 * width, and protocol options.
4590 */
4591 static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
4592 AdvPortAddr iop_base, unsigned short tidmask)
4593 {
4594 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
4595 adv_dvc->ppr_able |= tidmask;
4596 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
4597 }
4598
4599 static void
4600 advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
4601 {
4602 AdvPortAddr iop_base = adv_dvc->iop_base;
4603 unsigned short tidmask = 1 << sdev->id;
4604
4605 if (sdev->lun == 0) {
4606 /*
4607 * Handle WDTR, SDTR, and Tag Queuing. If the feature
4608 * is enabled in the EEPROM and the device supports the
4609 * feature, then enable it in the microcode.
4610 */
4611
4612 if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
4613 advansys_wide_enable_wdtr(iop_base, tidmask);
4614 if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
4615 advansys_wide_enable_sdtr(iop_base, tidmask);
4616 if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
4617 advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
4618
4619 /*
4620 * Tag Queuing is disabled for the BIOS which runs in polled
4621 * mode and would see no benefit from Tag Queuing. Also by
4622 * disabling Tag Queuing in the BIOS devices with Tag Queuing
4623 * bugs will at least work with the BIOS.
4624 */
4625 if ((adv_dvc->tagqng_able & tidmask) &&
4626 sdev->tagged_supported) {
4627 unsigned short cfg_word;
4628 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
4629 cfg_word |= tidmask;
4630 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
4631 cfg_word);
4632 AdvWriteByteLram(iop_base,
4633 ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
4634 adv_dvc->max_dvc_qng);
4635 }
4636 }
4637
4638 if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) {
4639 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
4640 adv_dvc->max_dvc_qng);
4641 } else {
4642 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
4643 }
4644 }
4645
4646 /*
4647 * Set the number of commands to queue per device for the
4648 * specified host adapter.
4649 */
4650 static int advansys_slave_configure(struct scsi_device *sdev)
4651 {
4652 asc_board_t *boardp = ASC_BOARDP(sdev->host);
4653 boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
4654
4655 /*
4656 * Save a pointer to the sdev and set its initial/maximum
4657 * queue depth. Only save the pointer for a lun0 dev though.
4658 */
4659 if (sdev->lun == 0)
4660 boardp->device[sdev->id] = sdev;
4661
4662 if (ASC_NARROW_BOARD(boardp))
4663 advansys_narrow_slave_configure(sdev,
4664 &boardp->dvc_var.asc_dvc_var);
4665 else
4666 advansys_wide_slave_configure(sdev,
4667 &boardp->dvc_var.adv_dvc_var);
4668
4669 return 0;
4670 }
4671
4672 /*
4673 * Complete all requests on the singly linked list pointed
4674 * to by 'scp'.
4675 *
4676 * Interrupts can be enabled on entry.
4677 */
4678 static void asc_scsi_done_list(struct scsi_cmnd *scp)
4679 {
4680 struct scsi_cmnd *tscp;
4681
4682 ASC_DBG(2, "asc_scsi_done_list: begin\n");
4683 while (scp != NULL) {
4684 asc_board_t *boardp;
4685 struct device *dev;
4686
4687 ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp);
4688 tscp = REQPNEXT(scp);
4689 scp->host_scribble = NULL;
4690
4691 boardp = ASC_BOARDP(scp->device->host);
4692
4693 if (ASC_NARROW_BOARD(boardp))
4694 dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
4695 else
4696 dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
4697
4698 if (scp->use_sg)
4699 dma_unmap_sg(dev,
4700 (struct scatterlist *)scp->request_buffer,
4701 scp->use_sg, scp->sc_data_direction);
4702 else if (scp->request_bufflen)
4703 dma_unmap_single(dev, scp->SCp.dma_handle,
4704 scp->request_bufflen,
4705 scp->sc_data_direction);
4706
4707 ASC_STATS(scp->device->host, done);
4708 ASC_ASSERT(scp->scsi_done != NULL);
4709
4710 scp->scsi_done(scp);
4711
4712 scp = tscp;
4713 }
4714 ASC_DBG(2, "asc_scsi_done_list: done\n");
4715 return;
4716 }
4717
4718 /*
4719 * Execute a single 'Scsi_Cmnd'.
4720 *
4721 * The function 'done' is called when the request has been completed.
4722 *
4723 * Scsi_Cmnd:
4724 *
4725 * host - board controlling device
4726 * device - device to send command
4727 * target - target of device
4728 * lun - lun of device
4729 * cmd_len - length of SCSI CDB
4730 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
4731 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
4732 *
4733 * if (use_sg == 0) {
4734 * request_buffer - buffer address for request
4735 * request_bufflen - length of request buffer
4736 * } else {
4737 * request_buffer - pointer to scatterlist structure
4738 * }
4739 *
4740 * sense_buffer - sense command buffer
4741 *
4742 * result (4 bytes of an int):
4743 * Byte Meaning
4744 * 0 SCSI Status Byte Code
4745 * 1 SCSI One Byte Message Code
4746 * 2 Host Error Code
4747 * 3 Mid-Level Error Code
4748 *
4749 * host driver fields:
4750 * SCp - Scsi_Pointer used for command processing status
4751 * scsi_done - used to save caller's done function
4752 * host_scribble - used for pointer to another struct scsi_cmnd
4753 *
4754 * If this function returns ASC_NOERROR the request has been enqueued
4755 * on the board's 'active' queue and will be completed from the
4756 * interrupt handler.
4757 *
4758 * If this function returns ASC_NOERROR the request has been enqueued
4759 * on the board's 'done' queue and must be completed by the caller.
4760 *
4761 * If ASC_BUSY is returned the request will be enqueued by the
4762 * caller on the target's waiting queue and re-tried later.
4763 */
4764 static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
4765 {
4766 asc_board_t *boardp;
4767 ASC_DVC_VAR *asc_dvc_varp;
4768 ADV_DVC_VAR *adv_dvc_varp;
4769 ADV_SCSI_REQ_Q *adv_scsiqp;
4770 struct scsi_device *device;
4771 int ret;
4772
4773 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
4774 (ulong)scp, (ulong)scp->scsi_done);
4775
4776 boardp = ASC_BOARDP(scp->device->host);
4777 device = boardp->device[scp->device->id];
4778
4779 if (ASC_NARROW_BOARD(boardp)) {
4780 /*
4781 * Build and execute Narrow Board request.
4782 */
4783
4784 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4785
4786 /*
4787 * Build Asc Library request structure using the
4788 * global structures 'asc_scsi_req' and 'asc_sg_head'.
4789 *
4790 * If an error is returned, then the request has been
4791 * queued on the board done queue. It will be completed
4792 * by the caller.
4793 *
4794 * asc_build_req() can not return ASC_BUSY.
4795 */
4796 if (asc_build_req(boardp, scp) == ASC_ERROR) {
4797 ASC_STATS(scp->device->host, build_error);
4798 return ASC_ERROR;
4799 }
4800
4801 /*
4802 * Execute the command. If there is no error, add the command
4803 * to the active queue.
4804 */
4805 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
4806 case ASC_NOERROR:
4807 ASC_STATS(scp->device->host, exe_noerror);
4808 /*
4809 * Increment monotonically increasing per device
4810 * successful request counter. Wrapping doesn't matter.
4811 */
4812 boardp->reqcnt[scp->device->id]++;
4813 asc_enqueue(&boardp->active, scp, ASC_BACK);
4814 ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue(), "
4815 "ASC_NOERROR\n");
4816 break;
4817 case ASC_BUSY:
4818 /*
4819 * Caller will enqueue request on the target's waiting
4820 * queue and retry later.
4821 */
4822 ASC_STATS(scp->device->host, exe_busy);
4823 break;
4824 case ASC_ERROR:
4825 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4826 "AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4827 boardp->id, asc_dvc_varp->err_code);
4828 ASC_STATS(scp->device->host, exe_error);
4829 scp->result = HOST_BYTE(DID_ERROR);
4830 asc_enqueue(&boardp->done, scp, ASC_BACK);
4831 break;
4832 default:
4833 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4834 "AscExeScsiQueue() unknown, err_code 0x%x\n",
4835 boardp->id, asc_dvc_varp->err_code);
4836 ASC_STATS(scp->device->host, exe_unknown);
4837 scp->result = HOST_BYTE(DID_ERROR);
4838 asc_enqueue(&boardp->done, scp, ASC_BACK);
4839 break;
4840 }
4841 } else {
4842 /*
4843 * Build and execute Wide Board request.
4844 */
4845 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4846
4847 /*
4848 * Build and get a pointer to an Adv Library request structure.
4849 *
4850 * If the request is successfully built then send it below,
4851 * otherwise return with an error.
4852 */
4853 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
4854 case ASC_NOERROR:
4855 ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req "
4856 "ASC_NOERROR\n");
4857 break;
4858 case ASC_BUSY:
4859 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
4860 "ASC_BUSY\n");
4861 /*
4862 * If busy is returned the request has not been
4863 * enqueued. It will be enqueued by the caller on the
4864 * target's waiting queue and retried later.
4865 *
4866 * The asc_stats fields 'adv_build_noreq' and
4867 * 'adv_build_nosg' count wide board busy conditions.
4868 * They are updated in adv_build_req and
4869 * adv_get_sglist, respectively.
4870 */
4871 return ASC_BUSY;
4872 case ASC_ERROR:
4873 /*
4874 * If an error is returned, then the request has been
4875 * queued on the board done queue. It will be completed
4876 * by the caller.
4877 */
4878 default:
4879 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
4880 "ASC_ERROR\n");
4881 ASC_STATS(scp->device->host, build_error);
4882 return ASC_ERROR;
4883 }
4884
4885 /*
4886 * Execute the command. If there is no error, add the command
4887 * to the active queue.
4888 */
4889 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
4890 case ASC_NOERROR:
4891 ASC_STATS(scp->device->host, exe_noerror);
4892 /*
4893 * Increment monotonically increasing per device
4894 * successful request counter. Wrapping doesn't matter.
4895 */
4896 boardp->reqcnt[scp->device->id]++;
4897 asc_enqueue(&boardp->active, scp, ASC_BACK);
4898 ASC_DBG(1, "asc_execute_scsi_cmnd: AdvExeScsiQueue(), "
4899 "ASC_NOERROR\n");
4900 break;
4901 case ASC_BUSY:
4902 /*
4903 * Caller will enqueue request on the target's waiting
4904 * queue and retry later.
4905 */
4906 ASC_STATS(scp->device->host, exe_busy);
4907 break;
4908 case ASC_ERROR:
4909 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4910 "AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4911 boardp->id, adv_dvc_varp->err_code);
4912 ASC_STATS(scp->device->host, exe_error);
4913 scp->result = HOST_BYTE(DID_ERROR);
4914 asc_enqueue(&boardp->done, scp, ASC_BACK);
4915 break;
4916 default:
4917 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4918 "AdvExeScsiQueue() unknown, err_code 0x%x\n",
4919 boardp->id, adv_dvc_varp->err_code);
4920 ASC_STATS(scp->device->host, exe_unknown);
4921 scp->result = HOST_BYTE(DID_ERROR);
4922 asc_enqueue(&boardp->done, scp, ASC_BACK);
4923 break;
4924 }
4925 }
4926
4927 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
4928 return ret;
4929 }
4930
4931 /*
4932 * Build a request structure for the Asc Library (Narrow Board).
4933 *
4934 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
4935 * used to build the request.
4936 *
4937 * If an error occurs, then queue the request on the board done
4938 * queue and return ASC_ERROR.
4939 */
4940 static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
4941 {
4942 struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
4943
4944 /*
4945 * Mutually exclusive access is required to 'asc_scsi_q' and
4946 * 'asc_sg_head' until after the request is started.
4947 */
4948 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
4949
4950 /*
4951 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
4952 */
4953 asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
4954
4955 /*
4956 * Build the ASC_SCSI_Q request.
4957 *
4958 * For narrow boards a CDB length maximum of 12 bytes
4959 * is supported.
4960 */
4961 if (scp->cmd_len > ASC_MAX_CDB_LEN) {
4962 ASC_PRINT3("asc_build_req: board %d: cmd_len %d > "
4963 "ASC_MAX_CDB_LEN %d\n", boardp->id, scp->cmd_len,
4964 ASC_MAX_CDB_LEN);
4965 scp->result = HOST_BYTE(DID_ERROR);
4966 asc_enqueue(&boardp->done, scp, ASC_BACK);
4967 return ASC_ERROR;
4968 }
4969 asc_scsi_q.cdbptr = &scp->cmnd[0];
4970 asc_scsi_q.q2.cdb_len = scp->cmd_len;
4971 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
4972 asc_scsi_q.q1.target_lun = scp->device->lun;
4973 asc_scsi_q.q2.target_ix =
4974 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
4975 asc_scsi_q.q1.sense_addr =
4976 cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
4977 asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
4978
4979 /*
4980 * If there are any outstanding requests for the current target,
4981 * then every 255th request send an ORDERED request. This heuristic
4982 * tries to retain the benefit of request sorting while preventing
4983 * request starvation. 255 is the max number of tags or pending commands
4984 * a device may have outstanding.
4985 *
4986 * The request count is incremented below for every successfully
4987 * started request.
4988 *
4989 */
4990 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
4991 (boardp->reqcnt[scp->device->id] % 255) == 0) {
4992 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
4993 } else {
4994 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
4995 }
4996
4997 /*
4998 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
4999 * buffer command.
5000 */
5001 if (scp->use_sg == 0) {
5002 /*
5003 * CDB request of single contiguous buffer.
5004 */
5005 ASC_STATS(scp->device->host, cont_cnt);
5006 scp->SCp.dma_handle = scp->request_bufflen ?
5007 dma_map_single(dev, scp->request_buffer,
5008 scp->request_bufflen,
5009 scp->sc_data_direction) : 0;
5010 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
5011 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
5012 ASC_STATS_ADD(scp->device->host, cont_xfer,
5013 ASC_CEILING(scp->request_bufflen, 512));
5014 asc_scsi_q.q1.sg_queue_cnt = 0;
5015 asc_scsi_q.sg_head = NULL;
5016 } else {
5017 /*
5018 * CDB scatter-gather request list.
5019 */
5020 int sgcnt;
5021 int use_sg;
5022 struct scatterlist *slp;
5023
5024 slp = (struct scatterlist *)scp->request_buffer;
5025 use_sg =
5026 dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
5027
5028 if (use_sg > scp->device->host->sg_tablesize) {
5029 ASC_PRINT3
5030 ("asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
5031 boardp->id, use_sg,
5032 scp->device->host->sg_tablesize);
5033 dma_unmap_sg(dev, slp, scp->use_sg,
5034 scp->sc_data_direction);
5035 scp->result = HOST_BYTE(DID_ERROR);
5036 asc_enqueue(&boardp->done, scp, ASC_BACK);
5037 return ASC_ERROR;
5038 }
5039
5040 ASC_STATS(scp->device->host, sg_cnt);
5041
5042 /*
5043 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
5044 * structure to point to it.
5045 */
5046 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
5047
5048 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
5049 asc_scsi_q.sg_head = &asc_sg_head;
5050 asc_scsi_q.q1.data_cnt = 0;
5051 asc_scsi_q.q1.data_addr = 0;
5052 /* This is a byte value, otherwise it would need to be swapped. */
5053 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
5054 ASC_STATS_ADD(scp->device->host, sg_elem,
5055 asc_sg_head.entry_cnt);
5056
5057 /*
5058 * Convert scatter-gather list into ASC_SG_HEAD list.
5059 */
5060 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
5061 asc_sg_head.sg_list[sgcnt].addr =
5062 cpu_to_le32(sg_dma_address(slp));
5063 asc_sg_head.sg_list[sgcnt].bytes =
5064 cpu_to_le32(sg_dma_len(slp));
5065 ASC_STATS_ADD(scp->device->host, sg_xfer,
5066 ASC_CEILING(sg_dma_len(slp), 512));
5067 }
5068 }
5069
5070 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
5071 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
5072
5073 return ASC_NOERROR;
5074 }
5075
5076 /*
5077 * Build a request structure for the Adv Library (Wide Board).
5078 *
5079 * If an adv_req_t can not be allocated to issue the request,
5080 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
5081 *
5082 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
5083 * microcode for DMA addresses or math operations are byte swapped
5084 * to little-endian order.
5085 */
5086 static int
5087 adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
5088 ADV_SCSI_REQ_Q **adv_scsiqpp)
5089 {
5090 adv_req_t *reqp;
5091 ADV_SCSI_REQ_Q *scsiqp;
5092 int i;
5093 int ret;
5094 struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
5095
5096 /*
5097 * Allocate an adv_req_t structure from the board to execute
5098 * the command.
5099 */
5100 if (boardp->adv_reqp == NULL) {
5101 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
5102 ASC_STATS(scp->device->host, adv_build_noreq);
5103 return ASC_BUSY;
5104 } else {
5105 reqp = boardp->adv_reqp;
5106 boardp->adv_reqp = reqp->next_reqp;
5107 reqp->next_reqp = NULL;
5108 }
5109
5110 /*
5111 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
5112 */
5113 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5114
5115 /*
5116 * Initialize the structure.
5117 */
5118 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
5119
5120 /*
5121 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
5122 */
5123 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
5124
5125 /*
5126 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
5127 */
5128 reqp->cmndp = scp;
5129
5130 /*
5131 * Build the ADV_SCSI_REQ_Q request.
5132 */
5133
5134 /*
5135 * Set CDB length and copy it to the request structure.
5136 * For wide boards a CDB length maximum of 16 bytes
5137 * is supported.
5138 */
5139 if (scp->cmd_len > ADV_MAX_CDB_LEN) {
5140 ASC_PRINT3
5141 ("adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n",
5142 boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
5143 scp->result = HOST_BYTE(DID_ERROR);
5144 asc_enqueue(&boardp->done, scp, ASC_BACK);
5145 return ASC_ERROR;
5146 }
5147 scsiqp->cdb_len = scp->cmd_len;
5148 /* Copy first 12 CDB bytes to cdb[]. */
5149 for (i = 0; i < scp->cmd_len && i < 12; i++) {
5150 scsiqp->cdb[i] = scp->cmnd[i];
5151 }
5152 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
5153 for (; i < scp->cmd_len; i++) {
5154 scsiqp->cdb16[i - 12] = scp->cmnd[i];
5155 }
5156
5157 scsiqp->target_id = scp->device->id;
5158 scsiqp->target_lun = scp->device->lun;
5159
5160 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
5161 scsiqp->sense_len = sizeof(scp->sense_buffer);
5162
5163 /*
5164 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
5165 * buffer command.
5166 */
5167
5168 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
5169 scsiqp->vdata_addr = scp->request_buffer;
5170 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
5171
5172 if (scp->use_sg == 0) {
5173 /*
5174 * CDB request of single contiguous buffer.
5175 */
5176 reqp->sgblkp = NULL;
5177 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
5178 if (scp->request_bufflen) {
5179 scsiqp->vdata_addr = scp->request_buffer;
5180 scp->SCp.dma_handle =
5181 dma_map_single(dev, scp->request_buffer,
5182 scp->request_bufflen,
5183 scp->sc_data_direction);
5184 } else {
5185 scsiqp->vdata_addr = NULL;
5186 scp->SCp.dma_handle = 0;
5187 }
5188 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
5189 scsiqp->sg_list_ptr = NULL;
5190 scsiqp->sg_real_addr = 0;
5191 ASC_STATS(scp->device->host, cont_cnt);
5192 ASC_STATS_ADD(scp->device->host, cont_xfer,
5193 ASC_CEILING(scp->request_bufflen, 512));
5194 } else {
5195 /*
5196 * CDB scatter-gather request list.
5197 */
5198 struct scatterlist *slp;
5199 int use_sg;
5200
5201 slp = (struct scatterlist *)scp->request_buffer;
5202 use_sg =
5203 dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
5204
5205 if (use_sg > ADV_MAX_SG_LIST) {
5206 ASC_PRINT3
5207 ("adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
5208 boardp->id, use_sg,
5209 scp->device->host->sg_tablesize);
5210 dma_unmap_sg(dev, slp, scp->use_sg,
5211 scp->sc_data_direction);
5212 scp->result = HOST_BYTE(DID_ERROR);
5213 asc_enqueue(&boardp->done, scp, ASC_BACK);
5214
5215 /*
5216 * Free the 'adv_req_t' structure by adding it back to the
5217 * board free list.
5218 */
5219 reqp->next_reqp = boardp->adv_reqp;
5220 boardp->adv_reqp = reqp;
5221
5222 return ASC_ERROR;
5223 }
5224
5225 if ((ret =
5226 adv_get_sglist(boardp, reqp, scp,
5227 use_sg)) != ADV_SUCCESS) {
5228 /*
5229 * Free the adv_req_t structure by adding it back to the
5230 * board free list.
5231 */
5232 reqp->next_reqp = boardp->adv_reqp;
5233 boardp->adv_reqp = reqp;
5234
5235 return ret;
5236 }
5237
5238 ASC_STATS(scp->device->host, sg_cnt);
5239 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
5240 }
5241
5242 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5243 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
5244
5245 *adv_scsiqpp = scsiqp;
5246
5247 return ASC_NOERROR;
5248 }
5249
5250 /*
5251 * Build scatter-gather list for Adv Library (Wide Board).
5252 *
5253 * Additional ADV_SG_BLOCK structures will need to be allocated
5254 * if the total number of scatter-gather elements exceeds
5255 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
5256 * assumed to be physically contiguous.
5257 *
5258 * Return:
5259 * ADV_SUCCESS(1) - SG List successfully created
5260 * ADV_ERROR(-1) - SG List creation failed
5261 */
5262 static int
5263 adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
5264 int use_sg)
5265 {
5266 adv_sgblk_t *sgblkp;
5267 ADV_SCSI_REQ_Q *scsiqp;
5268 struct scatterlist *slp;
5269 int sg_elem_cnt;
5270 ADV_SG_BLOCK *sg_block, *prev_sg_block;
5271 ADV_PADDR sg_block_paddr;
5272 int i;
5273
5274 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5275 slp = (struct scatterlist *)scp->request_buffer;
5276 sg_elem_cnt = use_sg;
5277 prev_sg_block = NULL;
5278 reqp->sgblkp = NULL;
5279
5280 do {
5281 /*
5282 * Allocate a 'adv_sgblk_t' structure from the board free
5283 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
5284 * (15) scatter-gather elements.
5285 */
5286 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
5287 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
5288 ASC_STATS(scp->device->host, adv_build_nosg);
5289
5290 /*
5291 * Allocation failed. Free 'adv_sgblk_t' structures already
5292 * allocated for the request.
5293 */
5294 while ((sgblkp = reqp->sgblkp) != NULL) {
5295 /* Remove 'sgblkp' from the request list. */
5296 reqp->sgblkp = sgblkp->next_sgblkp;
5297
5298 /* Add 'sgblkp' to the board free list. */
5299 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5300 boardp->adv_sgblkp = sgblkp;
5301 }
5302 return ASC_BUSY;
5303 } else {
5304 /* Complete 'adv_sgblk_t' board allocation. */
5305 boardp->adv_sgblkp = sgblkp->next_sgblkp;
5306 sgblkp->next_sgblkp = NULL;
5307
5308 /*
5309 * Get 8 byte aligned virtual and physical addresses for
5310 * the allocated ADV_SG_BLOCK structure.
5311 */
5312 sg_block =
5313 (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
5314 sg_block_paddr = virt_to_bus(sg_block);
5315
5316 /*
5317 * Check if this is the first 'adv_sgblk_t' for the request.
5318 */
5319 if (reqp->sgblkp == NULL) {
5320 /* Request's first scatter-gather block. */
5321 reqp->sgblkp = sgblkp;
5322
5323 /*
5324 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
5325 * address pointers.
5326 */
5327 scsiqp->sg_list_ptr = sg_block;
5328 scsiqp->sg_real_addr =
5329 cpu_to_le32(sg_block_paddr);
5330 } else {
5331 /* Request's second or later scatter-gather block. */
5332 sgblkp->next_sgblkp = reqp->sgblkp;
5333 reqp->sgblkp = sgblkp;
5334
5335 /*
5336 * Point the previous ADV_SG_BLOCK structure to
5337 * the newly allocated ADV_SG_BLOCK structure.
5338 */
5339 ASC_ASSERT(prev_sg_block != NULL);
5340 prev_sg_block->sg_ptr =
5341 cpu_to_le32(sg_block_paddr);
5342 }
5343 }
5344
5345 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
5346 sg_block->sg_list[i].sg_addr =
5347 cpu_to_le32(sg_dma_address(slp));
5348 sg_block->sg_list[i].sg_count =
5349 cpu_to_le32(sg_dma_len(slp));
5350 ASC_STATS_ADD(scp->device->host, sg_xfer,
5351 ASC_CEILING(sg_dma_len(slp), 512));
5352
5353 if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */
5354 sg_block->sg_cnt = i + 1;
5355 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
5356 return ADV_SUCCESS;
5357 }
5358 slp++;
5359 }
5360 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
5361 prev_sg_block = sg_block;
5362 }
5363 while (1);
5364 /* NOTREACHED */
5365 }
5366
5367 /*
5368 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
5369 *
5370 * Interrupt callback function for the Narrow SCSI Asc Library.
5371 */
5372 static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
5373 {
5374 asc_board_t *boardp;
5375 struct scsi_cmnd *scp;
5376 struct Scsi_Host *shost;
5377
5378 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
5379 (ulong)asc_dvc_varp, (ulong)qdonep);
5380 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
5381
5382 /*
5383 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5384 * command that has been completed.
5385 */
5386 scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
5387 ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp);
5388
5389 if (scp == NULL) {
5390 ASC_PRINT("asc_isr_callback: scp is NULL\n");
5391 return;
5392 }
5393 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5394
5395 shost = scp->device->host;
5396 ASC_STATS(shost, callback);
5397 ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
5398
5399 /*
5400 * If the request isn't found on the active queue, it may
5401 * have been removed to handle a reset request.
5402 * Display a message and return.
5403 */
5404 boardp = ASC_BOARDP(shost);
5405 ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
5406 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5407 ASC_PRINT2
5408 ("asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
5409 boardp->id, (ulong)scp);
5410 return;
5411 }
5412
5413 /*
5414 * 'qdonep' contains the command's ending status.
5415 */
5416 switch (qdonep->d3.done_stat) {
5417 case QD_NO_ERROR:
5418 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
5419 scp->result = 0;
5420
5421 /*
5422 * Check for an underrun condition.
5423 *
5424 * If there was no error and an underrun condition, then
5425 * return the number of underrun bytes.
5426 */
5427 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
5428 qdonep->remain_bytes <= scp->request_bufflen) {
5429 ASC_DBG1(1,
5430 "asc_isr_callback: underrun condition %u bytes\n",
5431 (unsigned)qdonep->remain_bytes);
5432 scp->resid = qdonep->remain_bytes;
5433 }
5434 break;
5435
5436 case QD_WITH_ERROR:
5437 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
5438 switch (qdonep->d3.host_stat) {
5439 case QHSTA_NO_ERROR:
5440 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
5441 ASC_DBG(2,
5442 "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5443 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5444 sizeof(scp->sense_buffer));
5445 /*
5446 * Note: The 'status_byte()' macro used by target drivers
5447 * defined in scsi.h shifts the status byte returned by
5448 * host drivers right by 1 bit. This is why target drivers
5449 * also use right shifted status byte definitions. For
5450 * instance target drivers use CHECK_CONDITION, defined to
5451 * 0x1, instead of the SCSI defined check condition value
5452 * of 0x2. Host drivers are supposed to return the status
5453 * byte as it is defined by SCSI.
5454 */
5455 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5456 STATUS_BYTE(qdonep->d3.scsi_stat);
5457 } else {
5458 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
5459 }
5460 break;
5461
5462 default:
5463 /* QHSTA error occurred */
5464 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
5465 qdonep->d3.host_stat);
5466 scp->result = HOST_BYTE(DID_BAD_TARGET);
5467 break;
5468 }
5469 break;
5470
5471 case QD_ABORTED_BY_HOST:
5472 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
5473 scp->result =
5474 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
5475 scsi_msg) |
5476 STATUS_BYTE(qdonep->d3.scsi_stat);
5477 break;
5478
5479 default:
5480 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n",
5481 qdonep->d3.done_stat);
5482 scp->result =
5483 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
5484 scsi_msg) |
5485 STATUS_BYTE(qdonep->d3.scsi_stat);
5486 break;
5487 }
5488
5489 /*
5490 * If the 'init_tidmask' bit isn't already set for the target and the
5491 * current request finished normally, then set the bit for the target
5492 * to indicate that a device is present.
5493 */
5494 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5495 qdonep->d3.done_stat == QD_NO_ERROR &&
5496 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
5497 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5498 }
5499
5500 /*
5501 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5502 * function, add the command to the end of the board's done queue.
5503 * The done function for the command will be called from
5504 * advansys_interrupt().
5505 */
5506 asc_enqueue(&boardp->done, scp, ASC_BACK);
5507
5508 return;
5509 }
5510
5511 /*
5512 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
5513 *
5514 * Callback function for the Wide SCSI Adv Library.
5515 */
5516 static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
5517 {
5518 asc_board_t *boardp;
5519 adv_req_t *reqp;
5520 adv_sgblk_t *sgblkp;
5521 struct scsi_cmnd *scp;
5522 struct Scsi_Host *shost;
5523 ADV_DCNT resid_cnt;
5524
5525 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
5526 (ulong)adv_dvc_varp, (ulong)scsiqp);
5527 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5528
5529 /*
5530 * Get the adv_req_t structure for the command that has been
5531 * completed. The adv_req_t structure actually contains the
5532 * completed ADV_SCSI_REQ_Q structure.
5533 */
5534 reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
5535 ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp);
5536 if (reqp == NULL) {
5537 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
5538 return;
5539 }
5540
5541 /*
5542 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5543 * command that has been completed.
5544 *
5545 * Note: The adv_req_t request structure and adv_sgblk_t structure,
5546 * if any, are dropped, because a board structure pointer can not be
5547 * determined.
5548 */
5549 scp = reqp->cmndp;
5550 ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp);
5551 if (scp == NULL) {
5552 ASC_PRINT
5553 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
5554 return;
5555 }
5556 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5557
5558 shost = scp->device->host;
5559 ASC_STATS(shost, callback);
5560 ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
5561
5562 /*
5563 * If the request isn't found on the active queue, it may have been
5564 * removed to handle a reset request. Display a message and return.
5565 *
5566 * Note: Because the structure may still be in use don't attempt
5567 * to free the adv_req_t and adv_sgblk_t, if any, structures.
5568 */
5569 boardp = ASC_BOARDP(shost);
5570 ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
5571 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5572 ASC_PRINT2
5573 ("adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
5574 boardp->id, (ulong)scp);
5575 return;
5576 }
5577
5578 /*
5579 * 'done_status' contains the command's ending status.
5580 */
5581 switch (scsiqp->done_status) {
5582 case QD_NO_ERROR:
5583 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
5584 scp->result = 0;
5585
5586 /*
5587 * Check for an underrun condition.
5588 *
5589 * If there was no error and an underrun condition, then
5590 * then return the number of underrun bytes.
5591 */
5592 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
5593 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
5594 resid_cnt <= scp->request_bufflen) {
5595 ASC_DBG1(1,
5596 "adv_isr_callback: underrun condition %lu bytes\n",
5597 (ulong)resid_cnt);
5598 scp->resid = resid_cnt;
5599 }
5600 break;
5601
5602 case QD_WITH_ERROR:
5603 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
5604 switch (scsiqp->host_status) {
5605 case QHSTA_NO_ERROR:
5606 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
5607 ASC_DBG(2,
5608 "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5609 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5610 sizeof(scp->sense_buffer));
5611 /*
5612 * Note: The 'status_byte()' macro used by target drivers
5613 * defined in scsi.h shifts the status byte returned by
5614 * host drivers right by 1 bit. This is why target drivers
5615 * also use right shifted status byte definitions. For
5616 * instance target drivers use CHECK_CONDITION, defined to
5617 * 0x1, instead of the SCSI defined check condition value
5618 * of 0x2. Host drivers are supposed to return the status
5619 * byte as it is defined by SCSI.
5620 */
5621 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5622 STATUS_BYTE(scsiqp->scsi_status);
5623 } else {
5624 scp->result = STATUS_BYTE(scsiqp->scsi_status);
5625 }
5626 break;
5627
5628 default:
5629 /* Some other QHSTA error occurred. */
5630 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
5631 scsiqp->host_status);
5632 scp->result = HOST_BYTE(DID_BAD_TARGET);
5633 break;
5634 }
5635 break;
5636
5637 case QD_ABORTED_BY_HOST:
5638 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
5639 scp->result =
5640 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
5641 break;
5642
5643 default:
5644 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n",
5645 scsiqp->done_status);
5646 scp->result =
5647 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
5648 break;
5649 }
5650
5651 /*
5652 * If the 'init_tidmask' bit isn't already set for the target and the
5653 * current request finished normally, then set the bit for the target
5654 * to indicate that a device is present.
5655 */
5656 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5657 scsiqp->done_status == QD_NO_ERROR &&
5658 scsiqp->host_status == QHSTA_NO_ERROR) {
5659 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5660 }
5661
5662 /*
5663 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5664 * function, add the command to the end of the board's done queue.
5665 * The done function for the command will be called from
5666 * advansys_interrupt().
5667 */
5668 asc_enqueue(&boardp->done, scp, ASC_BACK);
5669
5670 /*
5671 * Free all 'adv_sgblk_t' structures allocated for the request.
5672 */
5673 while ((sgblkp = reqp->sgblkp) != NULL) {
5674 /* Remove 'sgblkp' from the request list. */
5675 reqp->sgblkp = sgblkp->next_sgblkp;
5676
5677 /* Add 'sgblkp' to the board free list. */
5678 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5679 boardp->adv_sgblkp = sgblkp;
5680 }
5681
5682 /*
5683 * Free the adv_req_t structure used with the command by adding
5684 * it back to the board free list.
5685 */
5686 reqp->next_reqp = boardp->adv_reqp;
5687 boardp->adv_reqp = reqp;
5688
5689 ASC_DBG(1, "adv_isr_callback: done\n");
5690
5691 return;
5692 }
5693
5694 /*
5695 * adv_async_callback() - Adv Library asynchronous event callback function.
5696 */
5697 static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
5698 {
5699 switch (code) {
5700 case ADV_ASYNC_SCSI_BUS_RESET_DET:
5701 /*
5702 * The firmware detected a SCSI Bus reset.
5703 */
5704 ASC_DBG(0,
5705 "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
5706 break;
5707
5708 case ADV_ASYNC_RDMA_FAILURE:
5709 /*
5710 * Handle RDMA failure by resetting the SCSI Bus and
5711 * possibly the chip if it is unresponsive. Log the error
5712 * with a unique code.
5713 */
5714 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
5715 AdvResetChipAndSB(adv_dvc_varp);
5716 break;
5717
5718 case ADV_HOST_SCSI_BUS_RESET:
5719 /*
5720 * Host generated SCSI bus reset occurred.
5721 */
5722 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
5723 break;
5724
5725 default:
5726 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
5727 break;
5728 }
5729 }
5730
5731 /*
5732 * Add a 'REQP' to the end of specified queue. Set 'tidmask'
5733 * to indicate a command is queued for the device.
5734 *
5735 * 'flag' may be either ASC_FRONT or ASC_BACK.
5736 *
5737 * 'REQPNEXT(reqp)' returns reqp's next pointer.
5738 */
5739 static void asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
5740 {
5741 int tid;
5742
5743 ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
5744 (ulong)ascq, (ulong)reqp, flag);
5745 ASC_ASSERT(reqp != NULL);
5746 ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
5747 tid = REQPTID(reqp);
5748 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5749 if (flag == ASC_FRONT) {
5750 reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
5751 ascq->q_first[tid] = reqp;
5752 /* If the queue was empty, set the last pointer. */
5753 if (ascq->q_last[tid] == NULL) {
5754 ascq->q_last[tid] = reqp;
5755 }
5756 } else { /* ASC_BACK */
5757 if (ascq->q_last[tid] != NULL) {
5758 ascq->q_last[tid]->host_scribble =
5759 (unsigned char *)reqp;
5760 }
5761 ascq->q_last[tid] = reqp;
5762 reqp->host_scribble = NULL;
5763 /* If the queue was empty, set the first pointer. */
5764 if (ascq->q_first[tid] == NULL) {
5765 ascq->q_first[tid] = reqp;
5766 }
5767 }
5768 /* The queue has at least one entry, set its bit. */
5769 ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
5770 #ifdef ADVANSYS_STATS
5771 /* Maintain request queue statistics. */
5772 ascq->q_tot_cnt[tid]++;
5773 ascq->q_cur_cnt[tid]++;
5774 if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
5775 ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
5776 ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
5777 tid, ascq->q_max_cnt[tid]);
5778 }
5779 REQPTIME(reqp) = REQTIMESTAMP();
5780 #endif /* ADVANSYS_STATS */
5781 ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong)reqp);
5782 return;
5783 }
5784
5785 /*
5786 * Return first queued 'REQP' on the specified queue for
5787 * the specified target device. Clear the 'tidmask' bit for
5788 * the device if no more commands are left queued for it.
5789 *
5790 * 'REQPNEXT(reqp)' returns reqp's next pointer.
5791 */
5792 static REQP asc_dequeue(asc_queue_t *ascq, int tid)
5793 {
5794 REQP reqp;
5795
5796 ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5797 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5798 if ((reqp = ascq->q_first[tid]) != NULL) {
5799 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
5800 ascq->q_first[tid] = REQPNEXT(reqp);
5801 /* If the queue is empty, clear its bit and the last pointer. */
5802 if (ascq->q_first[tid] == NULL) {
5803 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5804 ASC_ASSERT(ascq->q_last[tid] == reqp);
5805 ascq->q_last[tid] = NULL;
5806 }
5807 #ifdef ADVANSYS_STATS
5808 /* Maintain request queue statistics. */
5809 ascq->q_cur_cnt[tid]--;
5810 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
5811 REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
5812 #endif /* ADVANSYS_STATS */
5813 }
5814 ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong)reqp);
5815 return reqp;
5816 }
5817
5818 /*
5819 * Return a pointer to a singly linked list of all the requests queued
5820 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
5821 *
5822 * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
5823 * the last request returned in the singly linked list.
5824 *
5825 * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
5826 * then all queued requests are concatenated into one list and
5827 * returned.
5828 *
5829 * Note: If 'lastpp' is used to append a new list to the end of
5830 * an old list, only change the old list last pointer if '*lastpp'
5831 * (or the function return value) is not NULL, i.e. use a temporary
5832 * variable for 'lastpp' and check its value after the function return
5833 * before assigning it to the list last pointer.
5834 *
5835 * Unfortunately collecting queuing time statistics adds overhead to
5836 * the function that isn't inherent to the function's algorithm.
5837 */
5838 static REQP asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
5839 {
5840 REQP firstp, lastp;
5841 int i;
5842
5843 ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5844 ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
5845
5846 /*
5847 * If 'tid' is not ASC_TID_ALL, return requests only for
5848 * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
5849 * requests for all tids.
5850 */
5851 if (tid != ASC_TID_ALL) {
5852 /* Return all requests for the specified 'tid'. */
5853 if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
5854 /* List is empty; Set first and last return pointers to NULL. */
5855 firstp = lastp = NULL;
5856 } else {
5857 firstp = ascq->q_first[tid];
5858 lastp = ascq->q_last[tid];
5859 ascq->q_first[tid] = ascq->q_last[tid] = NULL;
5860 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5861 #ifdef ADVANSYS_STATS
5862 {
5863 REQP reqp;
5864 ascq->q_cur_cnt[tid] = 0;
5865 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
5866 REQTIMESTAT("asc_dequeue_list", ascq,
5867 reqp, tid);
5868 }
5869 }
5870 #endif /* ADVANSYS_STATS */
5871 }
5872 } else {
5873 /* Return all requests for all tids. */
5874 firstp = lastp = NULL;
5875 for (i = 0; i <= ADV_MAX_TID; i++) {
5876 if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
5877 if (firstp == NULL) {
5878 firstp = ascq->q_first[i];
5879 lastp = ascq->q_last[i];
5880 } else {
5881 ASC_ASSERT(lastp != NULL);
5882 lastp->host_scribble =
5883 (unsigned char *)ascq->q_first[i];
5884 lastp = ascq->q_last[i];
5885 }
5886 ascq->q_first[i] = ascq->q_last[i] = NULL;
5887 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
5888 #ifdef ADVANSYS_STATS
5889 ascq->q_cur_cnt[i] = 0;
5890 #endif /* ADVANSYS_STATS */
5891 }
5892 }
5893 #ifdef ADVANSYS_STATS
5894 {
5895 REQP reqp;
5896 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
5897 REQTIMESTAT("asc_dequeue_list", ascq, reqp,
5898 reqp->device->id);
5899 }
5900 }
5901 #endif /* ADVANSYS_STATS */
5902 }
5903 if (lastpp) {
5904 *lastpp = lastp;
5905 }
5906 ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong)firstp);
5907 return firstp;
5908 }
5909
5910 /*
5911 * Remove the specified 'REQP' from the specified queue for
5912 * the specified target device. Clear the 'tidmask' bit for the
5913 * device if no more commands are left queued for it.
5914 *
5915 * 'REQPNEXT(reqp)' returns reqp's the next pointer.
5916 *
5917 * Return ASC_TRUE if the command was found and removed,
5918 * otherwise return ASC_FALSE.
5919 */
5920 static int asc_rmqueue(asc_queue_t *ascq, REQP reqp)
5921 {
5922 REQP currp, prevp;
5923 int tid;
5924 int ret = ASC_FALSE;
5925
5926 ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
5927 (ulong)ascq, (ulong)reqp);
5928 ASC_ASSERT(reqp != NULL);
5929
5930 tid = REQPTID(reqp);
5931 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5932
5933 /*
5934 * Handle the common case of 'reqp' being the first
5935 * entry on the queue.
5936 */
5937 if (reqp == ascq->q_first[tid]) {
5938 ret = ASC_TRUE;
5939 ascq->q_first[tid] = REQPNEXT(reqp);
5940 /* If the queue is now empty, clear its bit and the last pointer. */
5941 if (ascq->q_first[tid] == NULL) {
5942 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5943 ASC_ASSERT(ascq->q_last[tid] == reqp);
5944 ascq->q_last[tid] = NULL;
5945 }
5946 } else if (ascq->q_first[tid] != NULL) {
5947 ASC_ASSERT(ascq->q_last[tid] != NULL);
5948 /*
5949 * Because the case of 'reqp' being the first entry has been
5950 * handled above and it is known the queue is not empty, if
5951 * 'reqp' is found on the queue it is guaranteed the queue will
5952 * not become empty and that 'q_first[tid]' will not be changed.
5953 *
5954 * Set 'prevp' to the first entry, 'currp' to the second entry,
5955 * and search for 'reqp'.
5956 */
5957 for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
5958 currp; prevp = currp, currp = REQPNEXT(currp)) {
5959 if (currp == reqp) {
5960 ret = ASC_TRUE;
5961 prevp->host_scribble =
5962 (unsigned char *)REQPNEXT(currp);
5963 reqp->host_scribble = NULL;
5964 if (ascq->q_last[tid] == reqp) {
5965 ascq->q_last[tid] = prevp;
5966 }
5967 break;
5968 }
5969 }
5970 }
5971 #ifdef ADVANSYS_STATS
5972 /* Maintain request queue statistics. */
5973 if (ret == ASC_TRUE) {
5974 ascq->q_cur_cnt[tid]--;
5975 REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
5976 }
5977 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
5978 #endif /* ADVANSYS_STATS */
5979 ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong)reqp, ret);
5980 return ret;
5981 }
5982
5983 /*
5984 * Execute as many queued requests as possible for the specified queue.
5985 *
5986 * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd.
5987 */
5988 static void asc_execute_queue(asc_queue_t *ascq)
5989 {
5990 ADV_SCSI_BIT_ID_TYPE scan_tidmask;
5991 REQP reqp;
5992 int i;
5993
5994 ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong)ascq);
5995 /*
5996 * Execute queued commands for devices attached to
5997 * the current board in round-robin fashion.
5998 */
5999 scan_tidmask = ascq->q_tidmask;
6000 do {
6001 for (i = 0; i <= ADV_MAX_TID; i++) {
6002 if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
6003 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
6004 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
6005 } else
6006 if (asc_execute_scsi_cmnd
6007 ((struct scsi_cmnd *)reqp)
6008 == ASC_BUSY) {
6009 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
6010 /*
6011 * The request returned ASC_BUSY. Enqueue at the front of
6012 * target's waiting list to maintain correct ordering.
6013 */
6014 asc_enqueue(ascq, reqp, ASC_FRONT);
6015 }
6016 }
6017 }
6018 } while (scan_tidmask);
6019 return;
6020 }
6021
6022 #ifdef CONFIG_PROC_FS
6023 /*
6024 * asc_prt_board_devices()
6025 *
6026 * Print driver information for devices attached to the board.
6027 *
6028 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6029 * cf. asc_prt_line().
6030 *
6031 * Return the number of characters copied into 'cp'. No more than
6032 * 'cplen' characters will be copied to 'cp'.
6033 */
6034 static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
6035 {
6036 asc_board_t *boardp;
6037 int leftlen;
6038 int totlen;
6039 int len;
6040 int chip_scsi_id;
6041 int i;
6042
6043 boardp = ASC_BOARDP(shost);
6044 leftlen = cplen;
6045 totlen = len = 0;
6046
6047 len = asc_prt_line(cp, leftlen,
6048 "\nDevice Information for AdvanSys SCSI Host %d:\n",
6049 shost->host_no);
6050 ASC_PRT_NEXT();
6051
6052 if (ASC_NARROW_BOARD(boardp)) {
6053 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6054 } else {
6055 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6056 }
6057
6058 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
6059 ASC_PRT_NEXT();
6060 for (i = 0; i <= ADV_MAX_TID; i++) {
6061 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
6062 len = asc_prt_line(cp, leftlen, " %X,", i);
6063 ASC_PRT_NEXT();
6064 }
6065 }
6066 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
6067 ASC_PRT_NEXT();
6068
6069 return totlen;
6070 }
6071
6072 /*
6073 * Display Wide Board BIOS Information.
6074 */
6075 static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
6076 {
6077 asc_board_t *boardp;
6078 int leftlen;
6079 int totlen;
6080 int len;
6081 ushort major, minor, letter;
6082
6083 boardp = ASC_BOARDP(shost);
6084 leftlen = cplen;
6085 totlen = len = 0;
6086
6087 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
6088 ASC_PRT_NEXT();
6089
6090 /*
6091 * If the BIOS saved a valid signature, then fill in
6092 * the BIOS code segment base address.
6093 */
6094 if (boardp->bios_signature != 0x55AA) {
6095 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
6096 ASC_PRT_NEXT();
6097 len = asc_prt_line(cp, leftlen,
6098 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
6099 ASC_PRT_NEXT();
6100 len = asc_prt_line(cp, leftlen,
6101 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
6102 ASC_PRT_NEXT();
6103 } else {
6104 major = (boardp->bios_version >> 12) & 0xF;
6105 minor = (boardp->bios_version >> 8) & 0xF;
6106 letter = (boardp->bios_version & 0xFF);
6107
6108 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
6109 major, minor,
6110 letter >= 26 ? '?' : letter + 'A');
6111 ASC_PRT_NEXT();
6112
6113 /*
6114 * Current available ROM BIOS release is 3.1I for UW
6115 * and 3.2I for U2W. This code doesn't differentiate
6116 * UW and U2W boards.
6117 */
6118 if (major < 3 || (major <= 3 && minor < 1) ||
6119 (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
6120 len = asc_prt_line(cp, leftlen,
6121 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
6122 ASC_PRT_NEXT();
6123 len = asc_prt_line(cp, leftlen,
6124 "ftp://ftp.connectcom.net/pub\n");
6125 ASC_PRT_NEXT();
6126 }
6127 }
6128
6129 return totlen;
6130 }
6131
6132 /*
6133 * Add serial number to information bar if signature AAh
6134 * is found in at bit 15-9 (7 bits) of word 1.
6135 *
6136 * Serial Number consists fo 12 alpha-numeric digits.
6137 *
6138 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
6139 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
6140 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
6141 * 5 - Product revision (A-J) Word0: " "
6142 *
6143 * Signature Word1: 15-9 (7 bits)
6144 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
6145 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
6146 *
6147 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
6148 *
6149 * Note 1: Only production cards will have a serial number.
6150 *
6151 * Note 2: Signature is most significant 7 bits (0xFE).
6152 *
6153 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
6154 */
6155 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
6156 {
6157 ushort w, num;
6158
6159 if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
6160 return ASC_FALSE;
6161 } else {
6162 /*
6163 * First word - 6 digits.
6164 */
6165 w = serialnum[0];
6166
6167 /* Product type - 1st digit. */
6168 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
6169 /* Product type is P=Prototype */
6170 *cp += 0x8;
6171 }
6172 cp++;
6173
6174 /* Manufacturing location - 2nd digit. */
6175 *cp++ = 'A' + ((w & 0x1C00) >> 10);
6176
6177 /* Product ID - 3rd, 4th digits. */
6178 num = w & 0x3FF;
6179 *cp++ = '0' + (num / 100);
6180 num %= 100;
6181 *cp++ = '0' + (num / 10);
6182
6183 /* Product revision - 5th digit. */
6184 *cp++ = 'A' + (num % 10);
6185
6186 /*
6187 * Second word
6188 */
6189 w = serialnum[1];
6190
6191 /*
6192 * Year - 6th digit.
6193 *
6194 * If bit 15 of third word is set, then the
6195 * last digit of the year is greater than 7.
6196 */
6197 if (serialnum[2] & 0x8000) {
6198 *cp++ = '8' + ((w & 0x1C0) >> 6);
6199 } else {
6200 *cp++ = '0' + ((w & 0x1C0) >> 6);
6201 }
6202
6203 /* Week of year - 7th, 8th digits. */
6204 num = w & 0x003F;
6205 *cp++ = '0' + num / 10;
6206 num %= 10;
6207 *cp++ = '0' + num;
6208
6209 /*
6210 * Third word
6211 */
6212 w = serialnum[2] & 0x7FFF;
6213
6214 /* Serial number - 9th digit. */
6215 *cp++ = 'A' + (w / 1000);
6216
6217 /* 10th, 11th, 12th digits. */
6218 num = w % 1000;
6219 *cp++ = '0' + num / 100;
6220 num %= 100;
6221 *cp++ = '0' + num / 10;
6222 num %= 10;
6223 *cp++ = '0' + num;
6224
6225 *cp = '\0'; /* Null Terminate the string. */
6226 return ASC_TRUE;
6227 }
6228 }
6229
6230 /*
6231 * asc_prt_asc_board_eeprom()
6232 *
6233 * Print board EEPROM configuration.
6234 *
6235 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6236 * cf. asc_prt_line().
6237 *
6238 * Return the number of characters copied into 'cp'. No more than
6239 * 'cplen' characters will be copied to 'cp'.
6240 */
6241 static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
6242 {
6243 asc_board_t *boardp;
6244 ASC_DVC_VAR *asc_dvc_varp;
6245 int leftlen;
6246 int totlen;
6247 int len;
6248 ASCEEP_CONFIG *ep;
6249 int i;
6250 #ifdef CONFIG_ISA
6251 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
6252 #endif /* CONFIG_ISA */
6253 uchar serialstr[13];
6254
6255 boardp = ASC_BOARDP(shost);
6256 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6257 ep = &boardp->eep_config.asc_eep;
6258
6259 leftlen = cplen;
6260 totlen = len = 0;
6261
6262 len = asc_prt_line(cp, leftlen,
6263 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6264 shost->host_no);
6265 ASC_PRT_NEXT();
6266
6267 if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
6268 == ASC_TRUE) {
6269 len =
6270 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6271 serialstr);
6272 ASC_PRT_NEXT();
6273 } else {
6274 if (ep->adapter_info[5] == 0xBB) {
6275 len = asc_prt_line(cp, leftlen,
6276 " Default Settings Used for EEPROM-less Adapter.\n");
6277 ASC_PRT_NEXT();
6278 } else {
6279 len = asc_prt_line(cp, leftlen,
6280 " Serial Number Signature Not Present.\n");
6281 ASC_PRT_NEXT();
6282 }
6283 }
6284
6285 len = asc_prt_line(cp, leftlen,
6286 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6287 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
6288 ep->max_tag_qng);
6289 ASC_PRT_NEXT();
6290
6291 len = asc_prt_line(cp, leftlen,
6292 " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
6293 ASC_PRT_NEXT();
6294
6295 len = asc_prt_line(cp, leftlen, " Target ID: ");
6296 ASC_PRT_NEXT();
6297 for (i = 0; i <= ASC_MAX_TID; i++) {
6298 len = asc_prt_line(cp, leftlen, " %d", i);
6299 ASC_PRT_NEXT();
6300 }
6301 len = asc_prt_line(cp, leftlen, "\n");
6302 ASC_PRT_NEXT();
6303
6304 len = asc_prt_line(cp, leftlen, " Disconnects: ");
6305 ASC_PRT_NEXT();
6306 for (i = 0; i <= ASC_MAX_TID; i++) {
6307 len = asc_prt_line(cp, leftlen, " %c",
6308 (ep->
6309 disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6310 'N');
6311 ASC_PRT_NEXT();
6312 }
6313 len = asc_prt_line(cp, leftlen, "\n");
6314 ASC_PRT_NEXT();
6315
6316 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
6317 ASC_PRT_NEXT();
6318 for (i = 0; i <= ASC_MAX_TID; i++) {
6319 len = asc_prt_line(cp, leftlen, " %c",
6320 (ep->
6321 use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6322 'N');
6323 ASC_PRT_NEXT();
6324 }
6325 len = asc_prt_line(cp, leftlen, "\n");
6326 ASC_PRT_NEXT();
6327
6328 len = asc_prt_line(cp, leftlen, " Start Motor: ");
6329 ASC_PRT_NEXT();
6330 for (i = 0; i <= ASC_MAX_TID; i++) {
6331 len = asc_prt_line(cp, leftlen, " %c",
6332 (ep->
6333 start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6334 'N');
6335 ASC_PRT_NEXT();
6336 }
6337 len = asc_prt_line(cp, leftlen, "\n");
6338 ASC_PRT_NEXT();
6339
6340 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6341 ASC_PRT_NEXT();
6342 for (i = 0; i <= ASC_MAX_TID; i++) {
6343 len = asc_prt_line(cp, leftlen, " %c",
6344 (ep->
6345 init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6346 'N');
6347 ASC_PRT_NEXT();
6348 }
6349 len = asc_prt_line(cp, leftlen, "\n");
6350 ASC_PRT_NEXT();
6351
6352 #ifdef CONFIG_ISA
6353 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
6354 len = asc_prt_line(cp, leftlen,
6355 " Host ISA DMA speed: %d MB/S\n",
6356 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
6357 ASC_PRT_NEXT();
6358 }
6359 #endif /* CONFIG_ISA */
6360
6361 return totlen;
6362 }
6363
6364 /*
6365 * asc_prt_adv_board_eeprom()
6366 *
6367 * Print board EEPROM configuration.
6368 *
6369 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6370 * cf. asc_prt_line().
6371 *
6372 * Return the number of characters copied into 'cp'. No more than
6373 * 'cplen' characters will be copied to 'cp'.
6374 */
6375 static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
6376 {
6377 asc_board_t *boardp;
6378 ADV_DVC_VAR *adv_dvc_varp;
6379 int leftlen;
6380 int totlen;
6381 int len;
6382 int i;
6383 char *termstr;
6384 uchar serialstr[13];
6385 ADVEEP_3550_CONFIG *ep_3550 = NULL;
6386 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
6387 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
6388 ushort word;
6389 ushort *wordp;
6390 ushort sdtr_speed = 0;
6391
6392 boardp = ASC_BOARDP(shost);
6393 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6394 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6395 ep_3550 = &boardp->eep_config.adv_3550_eep;
6396 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6397 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
6398 } else {
6399 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
6400 }
6401
6402 leftlen = cplen;
6403 totlen = len = 0;
6404
6405 len = asc_prt_line(cp, leftlen,
6406 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6407 shost->host_no);
6408 ASC_PRT_NEXT();
6409
6410 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6411 wordp = &ep_3550->serial_number_word1;
6412 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6413 wordp = &ep_38C0800->serial_number_word1;
6414 } else {
6415 wordp = &ep_38C1600->serial_number_word1;
6416 }
6417
6418 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
6419 len =
6420 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6421 serialstr);
6422 ASC_PRT_NEXT();
6423 } else {
6424 len = asc_prt_line(cp, leftlen,
6425 " Serial Number Signature Not Present.\n");
6426 ASC_PRT_NEXT();
6427 }
6428
6429 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6430 len = asc_prt_line(cp, leftlen,
6431 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6432 ep_3550->adapter_scsi_id,
6433 ep_3550->max_host_qng, ep_3550->max_dvc_qng);
6434 ASC_PRT_NEXT();
6435 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6436 len = asc_prt_line(cp, leftlen,
6437 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6438 ep_38C0800->adapter_scsi_id,
6439 ep_38C0800->max_host_qng,
6440 ep_38C0800->max_dvc_qng);
6441 ASC_PRT_NEXT();
6442 } else {
6443 len = asc_prt_line(cp, leftlen,
6444 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6445 ep_38C1600->adapter_scsi_id,
6446 ep_38C1600->max_host_qng,
6447 ep_38C1600->max_dvc_qng);
6448 ASC_PRT_NEXT();
6449 }
6450 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6451 word = ep_3550->termination;
6452 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6453 word = ep_38C0800->termination_lvd;
6454 } else {
6455 word = ep_38C1600->termination_lvd;
6456 }
6457 switch (word) {
6458 case 1:
6459 termstr = "Low Off/High Off";
6460 break;
6461 case 2:
6462 termstr = "Low Off/High On";
6463 break;
6464 case 3:
6465 termstr = "Low On/High On";
6466 break;
6467 default:
6468 case 0:
6469 termstr = "Automatic";
6470 break;
6471 }
6472
6473 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6474 len = asc_prt_line(cp, leftlen,
6475 " termination: %u (%s), bios_ctrl: 0x%x\n",
6476 ep_3550->termination, termstr,
6477 ep_3550->bios_ctrl);
6478 ASC_PRT_NEXT();
6479 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6480 len = asc_prt_line(cp, leftlen,
6481 " termination: %u (%s), bios_ctrl: 0x%x\n",
6482 ep_38C0800->termination_lvd, termstr,
6483 ep_38C0800->bios_ctrl);
6484 ASC_PRT_NEXT();
6485 } else {
6486 len = asc_prt_line(cp, leftlen,
6487 " termination: %u (%s), bios_ctrl: 0x%x\n",
6488 ep_38C1600->termination_lvd, termstr,
6489 ep_38C1600->bios_ctrl);
6490 ASC_PRT_NEXT();
6491 }
6492
6493 len = asc_prt_line(cp, leftlen, " Target ID: ");
6494 ASC_PRT_NEXT();
6495 for (i = 0; i <= ADV_MAX_TID; i++) {
6496 len = asc_prt_line(cp, leftlen, " %X", i);
6497 ASC_PRT_NEXT();
6498 }
6499 len = asc_prt_line(cp, leftlen, "\n");
6500 ASC_PRT_NEXT();
6501
6502 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6503 word = ep_3550->disc_enable;
6504 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6505 word = ep_38C0800->disc_enable;
6506 } else {
6507 word = ep_38C1600->disc_enable;
6508 }
6509 len = asc_prt_line(cp, leftlen, " Disconnects: ");
6510 ASC_PRT_NEXT();
6511 for (i = 0; i <= ADV_MAX_TID; i++) {
6512 len = asc_prt_line(cp, leftlen, " %c",
6513 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6514 ASC_PRT_NEXT();
6515 }
6516 len = asc_prt_line(cp, leftlen, "\n");
6517 ASC_PRT_NEXT();
6518
6519 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6520 word = ep_3550->tagqng_able;
6521 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6522 word = ep_38C0800->tagqng_able;
6523 } else {
6524 word = ep_38C1600->tagqng_able;
6525 }
6526 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
6527 ASC_PRT_NEXT();
6528 for (i = 0; i <= ADV_MAX_TID; i++) {
6529 len = asc_prt_line(cp, leftlen, " %c",
6530 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6531 ASC_PRT_NEXT();
6532 }
6533 len = asc_prt_line(cp, leftlen, "\n");
6534 ASC_PRT_NEXT();
6535
6536 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6537 word = ep_3550->start_motor;
6538 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6539 word = ep_38C0800->start_motor;
6540 } else {
6541 word = ep_38C1600->start_motor;
6542 }
6543 len = asc_prt_line(cp, leftlen, " Start Motor: ");
6544 ASC_PRT_NEXT();
6545 for (i = 0; i <= ADV_MAX_TID; i++) {
6546 len = asc_prt_line(cp, leftlen, " %c",
6547 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6548 ASC_PRT_NEXT();
6549 }
6550 len = asc_prt_line(cp, leftlen, "\n");
6551 ASC_PRT_NEXT();
6552
6553 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6554 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6555 ASC_PRT_NEXT();
6556 for (i = 0; i <= ADV_MAX_TID; i++) {
6557 len = asc_prt_line(cp, leftlen, " %c",
6558 (ep_3550->
6559 sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
6560 'Y' : 'N');
6561 ASC_PRT_NEXT();
6562 }
6563 len = asc_prt_line(cp, leftlen, "\n");
6564 ASC_PRT_NEXT();
6565 }
6566
6567 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6568 len = asc_prt_line(cp, leftlen, " Ultra Transfer: ");
6569 ASC_PRT_NEXT();
6570 for (i = 0; i <= ADV_MAX_TID; i++) {
6571 len = asc_prt_line(cp, leftlen, " %c",
6572 (ep_3550->
6573 ultra_able & ADV_TID_TO_TIDMASK(i))
6574 ? 'Y' : 'N');
6575 ASC_PRT_NEXT();
6576 }
6577 len = asc_prt_line(cp, leftlen, "\n");
6578 ASC_PRT_NEXT();
6579 }
6580
6581 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6582 word = ep_3550->wdtr_able;
6583 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6584 word = ep_38C0800->wdtr_able;
6585 } else {
6586 word = ep_38C1600->wdtr_able;
6587 }
6588 len = asc_prt_line(cp, leftlen, " Wide Transfer: ");
6589 ASC_PRT_NEXT();
6590 for (i = 0; i <= ADV_MAX_TID; i++) {
6591 len = asc_prt_line(cp, leftlen, " %c",
6592 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6593 ASC_PRT_NEXT();
6594 }
6595 len = asc_prt_line(cp, leftlen, "\n");
6596 ASC_PRT_NEXT();
6597
6598 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
6599 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
6600 len = asc_prt_line(cp, leftlen,
6601 " Synchronous Transfer Speed (Mhz):\n ");
6602 ASC_PRT_NEXT();
6603 for (i = 0; i <= ADV_MAX_TID; i++) {
6604 char *speed_str;
6605
6606 if (i == 0) {
6607 sdtr_speed = adv_dvc_varp->sdtr_speed1;
6608 } else if (i == 4) {
6609 sdtr_speed = adv_dvc_varp->sdtr_speed2;
6610 } else if (i == 8) {
6611 sdtr_speed = adv_dvc_varp->sdtr_speed3;
6612 } else if (i == 12) {
6613 sdtr_speed = adv_dvc_varp->sdtr_speed4;
6614 }
6615 switch (sdtr_speed & ADV_MAX_TID) {
6616 case 0:
6617 speed_str = "Off";
6618 break;
6619 case 1:
6620 speed_str = " 5";
6621 break;
6622 case 2:
6623 speed_str = " 10";
6624 break;
6625 case 3:
6626 speed_str = " 20";
6627 break;
6628 case 4:
6629 speed_str = " 40";
6630 break;
6631 case 5:
6632 speed_str = " 80";
6633 break;
6634 default:
6635 speed_str = "Unk";
6636 break;
6637 }
6638 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
6639 ASC_PRT_NEXT();
6640 if (i == 7) {
6641 len = asc_prt_line(cp, leftlen, "\n ");
6642 ASC_PRT_NEXT();
6643 }
6644 sdtr_speed >>= 4;
6645 }
6646 len = asc_prt_line(cp, leftlen, "\n");
6647 ASC_PRT_NEXT();
6648 }
6649
6650 return totlen;
6651 }
6652
6653 /*
6654 * asc_prt_driver_conf()
6655 *
6656 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6657 * cf. asc_prt_line().
6658 *
6659 * Return the number of characters copied into 'cp'. No more than
6660 * 'cplen' characters will be copied to 'cp'.
6661 */
6662 static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
6663 {
6664 asc_board_t *boardp;
6665 int leftlen;
6666 int totlen;
6667 int len;
6668 int chip_scsi_id;
6669
6670 boardp = ASC_BOARDP(shost);
6671
6672 leftlen = cplen;
6673 totlen = len = 0;
6674
6675 len = asc_prt_line(cp, leftlen,
6676 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
6677 shost->host_no);
6678 ASC_PRT_NEXT();
6679
6680 len = asc_prt_line(cp, leftlen,
6681 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
6682 shost->host_busy, shost->last_reset, shost->max_id,
6683 shost->max_lun, shost->max_channel);
6684 ASC_PRT_NEXT();
6685
6686 len = asc_prt_line(cp, leftlen,
6687 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
6688 shost->unique_id, shost->can_queue, shost->this_id,
6689 shost->sg_tablesize, shost->cmd_per_lun);
6690 ASC_PRT_NEXT();
6691
6692 len = asc_prt_line(cp, leftlen,
6693 " unchecked_isa_dma %d, use_clustering %d\n",
6694 shost->unchecked_isa_dma, shost->use_clustering);
6695 ASC_PRT_NEXT();
6696
6697 len = asc_prt_line(cp, leftlen,
6698 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
6699 boardp->flags, boardp->last_reset, jiffies,
6700 boardp->asc_n_io_port);
6701 ASC_PRT_NEXT();
6702
6703 /* 'shost->n_io_port' may be truncated because it is only one byte. */
6704 len = asc_prt_line(cp, leftlen,
6705 " io_port 0x%x, n_io_port 0x%x\n",
6706 shost->io_port, shost->n_io_port);
6707 ASC_PRT_NEXT();
6708
6709 if (ASC_NARROW_BOARD(boardp)) {
6710 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6711 } else {
6712 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6713 }
6714
6715 return totlen;
6716 }
6717
6718 /*
6719 * asc_prt_asc_board_info()
6720 *
6721 * Print dynamic board configuration information.
6722 *
6723 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6724 * cf. asc_prt_line().
6725 *
6726 * Return the number of characters copied into 'cp'. No more than
6727 * 'cplen' characters will be copied to 'cp'.
6728 */
6729 static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
6730 {
6731 asc_board_t *boardp;
6732 int chip_scsi_id;
6733 int leftlen;
6734 int totlen;
6735 int len;
6736 ASC_DVC_VAR *v;
6737 ASC_DVC_CFG *c;
6738 int i;
6739 int renegotiate = 0;
6740
6741 boardp = ASC_BOARDP(shost);
6742 v = &boardp->dvc_var.asc_dvc_var;
6743 c = &boardp->dvc_cfg.asc_dvc_cfg;
6744 chip_scsi_id = c->chip_scsi_id;
6745
6746 leftlen = cplen;
6747 totlen = len = 0;
6748
6749 len = asc_prt_line(cp, leftlen,
6750 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6751 shost->host_no);
6752 ASC_PRT_NEXT();
6753
6754 len = asc_prt_line(cp, leftlen,
6755 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
6756 c->chip_version, c->lib_version, c->lib_serial_no,
6757 c->mcode_date);
6758 ASC_PRT_NEXT();
6759
6760 len = asc_prt_line(cp, leftlen,
6761 " mcode_version 0x%x, err_code %u\n",
6762 c->mcode_version, v->err_code);
6763 ASC_PRT_NEXT();
6764
6765 /* Current number of commands waiting for the host. */
6766 len = asc_prt_line(cp, leftlen,
6767 " Total Command Pending: %d\n", v->cur_total_qng);
6768 ASC_PRT_NEXT();
6769
6770 len = asc_prt_line(cp, leftlen, " Command Queuing:");
6771 ASC_PRT_NEXT();
6772 for (i = 0; i <= ASC_MAX_TID; i++) {
6773 if ((chip_scsi_id == i) ||
6774 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6775 continue;
6776 }
6777 len = asc_prt_line(cp, leftlen, " %X:%c",
6778 i,
6779 (v->
6780 use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
6781 'Y' : 'N');
6782 ASC_PRT_NEXT();
6783 }
6784 len = asc_prt_line(cp, leftlen, "\n");
6785 ASC_PRT_NEXT();
6786
6787 /* Current number of commands waiting for a device. */
6788 len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
6789 ASC_PRT_NEXT();
6790 for (i = 0; i <= ASC_MAX_TID; i++) {
6791 if ((chip_scsi_id == i) ||
6792 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6793 continue;
6794 }
6795 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
6796 ASC_PRT_NEXT();
6797 }
6798 len = asc_prt_line(cp, leftlen, "\n");
6799 ASC_PRT_NEXT();
6800
6801 /* Current limit on number of commands that can be sent to a device. */
6802 len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
6803 ASC_PRT_NEXT();
6804 for (i = 0; i <= ASC_MAX_TID; i++) {
6805 if ((chip_scsi_id == i) ||
6806 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6807 continue;
6808 }
6809 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
6810 ASC_PRT_NEXT();
6811 }
6812 len = asc_prt_line(cp, leftlen, "\n");
6813 ASC_PRT_NEXT();
6814
6815 /* Indicate whether the device has returned queue full status. */
6816 len = asc_prt_line(cp, leftlen, " Command Queue Full:");
6817 ASC_PRT_NEXT();
6818 for (i = 0; i <= ASC_MAX_TID; i++) {
6819 if ((chip_scsi_id == i) ||
6820 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6821 continue;
6822 }
6823 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
6824 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
6825 i, boardp->queue_full_cnt[i]);
6826 } else {
6827 len = asc_prt_line(cp, leftlen, " %X:N", i);
6828 }
6829 ASC_PRT_NEXT();
6830 }
6831 len = asc_prt_line(cp, leftlen, "\n");
6832 ASC_PRT_NEXT();
6833
6834 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6835 ASC_PRT_NEXT();
6836 for (i = 0; i <= ASC_MAX_TID; i++) {
6837 if ((chip_scsi_id == i) ||
6838 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6839 continue;
6840 }
6841 len = asc_prt_line(cp, leftlen, " %X:%c",
6842 i,
6843 (v->
6844 sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6845 'N');
6846 ASC_PRT_NEXT();
6847 }
6848 len = asc_prt_line(cp, leftlen, "\n");
6849 ASC_PRT_NEXT();
6850
6851 for (i = 0; i <= ASC_MAX_TID; i++) {
6852 uchar syn_period_ix;
6853
6854 if ((chip_scsi_id == i) ||
6855 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
6856 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
6857 continue;
6858 }
6859
6860 len = asc_prt_line(cp, leftlen, " %X:", i);
6861 ASC_PRT_NEXT();
6862
6863 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
6864 len = asc_prt_line(cp, leftlen, " Asynchronous");
6865 ASC_PRT_NEXT();
6866 } else {
6867 syn_period_ix =
6868 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
6869 1);
6870
6871 len = asc_prt_line(cp, leftlen,
6872 " Transfer Period Factor: %d (%d.%d Mhz),",
6873 v->sdtr_period_tbl[syn_period_ix],
6874 250 /
6875 v->sdtr_period_tbl[syn_period_ix],
6876 ASC_TENTHS(250,
6877 v->
6878 sdtr_period_tbl
6879 [syn_period_ix]));
6880 ASC_PRT_NEXT();
6881
6882 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
6883 boardp->
6884 sdtr_data[i] & ASC_SYN_MAX_OFFSET);
6885 ASC_PRT_NEXT();
6886 }
6887
6888 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
6889 len = asc_prt_line(cp, leftlen, "*\n");
6890 renegotiate = 1;
6891 } else {
6892 len = asc_prt_line(cp, leftlen, "\n");
6893 }
6894 ASC_PRT_NEXT();
6895 }
6896
6897 if (renegotiate) {
6898 len = asc_prt_line(cp, leftlen,
6899 " * = Re-negotiation pending before next command.\n");
6900 ASC_PRT_NEXT();
6901 }
6902
6903 return totlen;
6904 }
6905
6906 /*
6907 * asc_prt_adv_board_info()
6908 *
6909 * Print dynamic board configuration information.
6910 *
6911 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6912 * cf. asc_prt_line().
6913 *
6914 * Return the number of characters copied into 'cp'. No more than
6915 * 'cplen' characters will be copied to 'cp'.
6916 */
6917 static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
6918 {
6919 asc_board_t *boardp;
6920 int leftlen;
6921 int totlen;
6922 int len;
6923 int i;
6924 ADV_DVC_VAR *v;
6925 ADV_DVC_CFG *c;
6926 AdvPortAddr iop_base;
6927 ushort chip_scsi_id;
6928 ushort lramword;
6929 uchar lrambyte;
6930 ushort tagqng_able;
6931 ushort sdtr_able, wdtr_able;
6932 ushort wdtr_done, sdtr_done;
6933 ushort period = 0;
6934 int renegotiate = 0;
6935
6936 boardp = ASC_BOARDP(shost);
6937 v = &boardp->dvc_var.adv_dvc_var;
6938 c = &boardp->dvc_cfg.adv_dvc_cfg;
6939 iop_base = v->iop_base;
6940 chip_scsi_id = v->chip_scsi_id;
6941
6942 leftlen = cplen;
6943 totlen = len = 0;
6944
6945 len = asc_prt_line(cp, leftlen,
6946 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6947 shost->host_no);
6948 ASC_PRT_NEXT();
6949
6950 len = asc_prt_line(cp, leftlen,
6951 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
6952 v->iop_base,
6953 AdvReadWordRegister(iop_base,
6954 IOPW_SCSI_CFG1) & CABLE_DETECT,
6955 v->err_code);
6956 ASC_PRT_NEXT();
6957
6958 len = asc_prt_line(cp, leftlen,
6959 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
6960 c->chip_version, c->lib_version, c->mcode_date,
6961 c->mcode_version);
6962 ASC_PRT_NEXT();
6963
6964 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
6965 len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
6966 ASC_PRT_NEXT();
6967 for (i = 0; i <= ADV_MAX_TID; i++) {
6968 if ((chip_scsi_id == i) ||
6969 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6970 continue;
6971 }
6972
6973 len = asc_prt_line(cp, leftlen, " %X:%c",
6974 i,
6975 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6976 'N');
6977 ASC_PRT_NEXT();
6978 }
6979 len = asc_prt_line(cp, leftlen, "\n");
6980 ASC_PRT_NEXT();
6981
6982 len = asc_prt_line(cp, leftlen, " Queue Limit:");
6983 ASC_PRT_NEXT();
6984 for (i = 0; i <= ADV_MAX_TID; i++) {
6985 if ((chip_scsi_id == i) ||
6986 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6987 continue;
6988 }
6989
6990 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
6991 lrambyte);
6992
6993 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
6994 ASC_PRT_NEXT();
6995 }
6996 len = asc_prt_line(cp, leftlen, "\n");
6997 ASC_PRT_NEXT();
6998
6999 len = asc_prt_line(cp, leftlen, " Command Pending:");
7000 ASC_PRT_NEXT();
7001 for (i = 0; i <= ADV_MAX_TID; i++) {
7002 if ((chip_scsi_id == i) ||
7003 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7004 continue;
7005 }
7006
7007 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
7008 lrambyte);
7009
7010 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
7011 ASC_PRT_NEXT();
7012 }
7013 len = asc_prt_line(cp, leftlen, "\n");
7014 ASC_PRT_NEXT();
7015
7016 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7017 len = asc_prt_line(cp, leftlen, " Wide Enabled:");
7018 ASC_PRT_NEXT();
7019 for (i = 0; i <= ADV_MAX_TID; i++) {
7020 if ((chip_scsi_id == i) ||
7021 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7022 continue;
7023 }
7024
7025 len = asc_prt_line(cp, leftlen, " %X:%c",
7026 i,
7027 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7028 'N');
7029 ASC_PRT_NEXT();
7030 }
7031 len = asc_prt_line(cp, leftlen, "\n");
7032 ASC_PRT_NEXT();
7033
7034 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
7035 len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
7036 ASC_PRT_NEXT();
7037 for (i = 0; i <= ADV_MAX_TID; i++) {
7038 if ((chip_scsi_id == i) ||
7039 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7040 continue;
7041 }
7042
7043 AdvReadWordLram(iop_base,
7044 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7045 lramword);
7046
7047 len = asc_prt_line(cp, leftlen, " %X:%d",
7048 i, (lramword & 0x8000) ? 16 : 8);
7049 ASC_PRT_NEXT();
7050
7051 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
7052 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7053 len = asc_prt_line(cp, leftlen, "*");
7054 ASC_PRT_NEXT();
7055 renegotiate = 1;
7056 }
7057 }
7058 len = asc_prt_line(cp, leftlen, "\n");
7059 ASC_PRT_NEXT();
7060
7061 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7062 len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
7063 ASC_PRT_NEXT();
7064 for (i = 0; i <= ADV_MAX_TID; i++) {
7065 if ((chip_scsi_id == i) ||
7066 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7067 continue;
7068 }
7069
7070 len = asc_prt_line(cp, leftlen, " %X:%c",
7071 i,
7072 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7073 'N');
7074 ASC_PRT_NEXT();
7075 }
7076 len = asc_prt_line(cp, leftlen, "\n");
7077 ASC_PRT_NEXT();
7078
7079 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
7080 for (i = 0; i <= ADV_MAX_TID; i++) {
7081
7082 AdvReadWordLram(iop_base,
7083 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7084 lramword);
7085 lramword &= ~0x8000;
7086
7087 if ((chip_scsi_id == i) ||
7088 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
7089 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
7090 continue;
7091 }
7092
7093 len = asc_prt_line(cp, leftlen, " %X:", i);
7094 ASC_PRT_NEXT();
7095
7096 if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */
7097 len = asc_prt_line(cp, leftlen, " Asynchronous");
7098 ASC_PRT_NEXT();
7099 } else {
7100 len =
7101 asc_prt_line(cp, leftlen,
7102 " Transfer Period Factor: ");
7103 ASC_PRT_NEXT();
7104
7105 if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */
7106 len =
7107 asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
7108 ASC_PRT_NEXT();
7109 } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */
7110 len =
7111 asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
7112 ASC_PRT_NEXT();
7113 } else { /* 20 Mhz or below. */
7114
7115 period = (((lramword >> 8) * 25) + 50) / 4;
7116
7117 if (period == 0) { /* Should never happen. */
7118 len =
7119 asc_prt_line(cp, leftlen,
7120 "%d (? Mhz), ");
7121 ASC_PRT_NEXT();
7122 } else {
7123 len = asc_prt_line(cp, leftlen,
7124 "%d (%d.%d Mhz),",
7125 period, 250 / period,
7126 ASC_TENTHS(250,
7127 period));
7128 ASC_PRT_NEXT();
7129 }
7130 }
7131
7132 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
7133 lramword & 0x1F);
7134 ASC_PRT_NEXT();
7135 }
7136
7137 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7138 len = asc_prt_line(cp, leftlen, "*\n");
7139 renegotiate = 1;
7140 } else {
7141 len = asc_prt_line(cp, leftlen, "\n");
7142 }
7143 ASC_PRT_NEXT();
7144 }
7145
7146 if (renegotiate) {
7147 len = asc_prt_line(cp, leftlen,
7148 " * = Re-negotiation pending before next command.\n");
7149 ASC_PRT_NEXT();
7150 }
7151
7152 return totlen;
7153 }
7154
7155 /*
7156 * asc_proc_copy()
7157 *
7158 * Copy proc information to a read buffer taking into account the current
7159 * read offset in the file and the remaining space in the read buffer.
7160 */
7161 static int
7162 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
7163 char *cp, int cplen)
7164 {
7165 int cnt = 0;
7166
7167 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
7168 (unsigned)offset, (unsigned)advoffset, cplen);
7169 if (offset <= advoffset) {
7170 /* Read offset below current offset, copy everything. */
7171 cnt = min(cplen, leftlen);
7172 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7173 (ulong)curbuf, (ulong)cp, cnt);
7174 memcpy(curbuf, cp, cnt);
7175 } else if (offset < advoffset + cplen) {
7176 /* Read offset within current range, partial copy. */
7177 cnt = (advoffset + cplen) - offset;
7178 cp = (cp + cplen) - cnt;
7179 cnt = min(cnt, leftlen);
7180 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7181 (ulong)curbuf, (ulong)cp, cnt);
7182 memcpy(curbuf, cp, cnt);
7183 }
7184 return cnt;
7185 }
7186
7187 /*
7188 * asc_prt_line()
7189 *
7190 * If 'cp' is NULL print to the console, otherwise print to a buffer.
7191 *
7192 * Return 0 if printing to the console, otherwise return the number of
7193 * bytes written to the buffer.
7194 *
7195 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
7196 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
7197 */
7198 static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
7199 {
7200 va_list args;
7201 int ret;
7202 char s[ASC_PRTLINE_SIZE];
7203
7204 va_start(args, fmt);
7205 ret = vsprintf(s, fmt, args);
7206 ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
7207 if (buf == NULL) {
7208 (void)printk(s);
7209 ret = 0;
7210 } else {
7211 ret = min(buflen, ret);
7212 memcpy(buf, s, ret);
7213 }
7214 va_end(args);
7215 return ret;
7216 }
7217 #endif /* CONFIG_PROC_FS */
7218
7219 /*
7220 * --- Functions Required by the Asc Library
7221 */
7222
7223 /*
7224 * Delay for 'n' milliseconds. Don't use the 'jiffies'
7225 * global variable which is incremented once every 5 ms
7226 * from a timer interrupt, because this function may be
7227 * called when interrupts are disabled.
7228 */
7229 static void DvcSleepMilliSecond(ADV_DCNT n)
7230 {
7231 ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong)n);
7232 mdelay(n);
7233 }
7234
7235 /*
7236 * Currently and inline noop but leave as a placeholder.
7237 * Leave DvcEnterCritical() as a noop placeholder.
7238 */
7239 static inline ulong DvcEnterCritical(void)
7240 {
7241 return 0;
7242 }
7243
7244 /*
7245 * Critical sections are all protected by the board spinlock.
7246 * Leave DvcLeaveCritical() as a noop placeholder.
7247 */
7248 static inline void DvcLeaveCritical(ulong flags)
7249 {
7250 return;
7251 }
7252
7253 /*
7254 * void
7255 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7256 *
7257 * Calling/Exit State:
7258 * none
7259 *
7260 * Description:
7261 * Output an ASC_SCSI_Q structure to the chip
7262 */
7263 static void
7264 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7265 {
7266 int i;
7267
7268 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
7269 AscSetChipLramAddr(iop_base, s_addr);
7270 for (i = 0; i < 2 * words; i += 2) {
7271 if (i == 4 || i == 20) {
7272 continue;
7273 }
7274 outpw(iop_base + IOP_RAM_DATA,
7275 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
7276 }
7277 }
7278
7279 /*
7280 * void
7281 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7282 *
7283 * Calling/Exit State:
7284 * none
7285 *
7286 * Description:
7287 * Input an ASC_QDONE_INFO structure from the chip
7288 */
7289 static void
7290 DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7291 {
7292 int i;
7293 ushort word;
7294
7295 AscSetChipLramAddr(iop_base, s_addr);
7296 for (i = 0; i < 2 * words; i += 2) {
7297 if (i == 10) {
7298 continue;
7299 }
7300 word = inpw(iop_base + IOP_RAM_DATA);
7301 inbuf[i] = word & 0xff;
7302 inbuf[i + 1] = (word >> 8) & 0xff;
7303 }
7304 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
7305 }
7306
7307 /*
7308 * Return the BIOS address of the adapter at the specified
7309 * I/O port and with the specified bus type.
7310 */
7311 static unsigned short __devinit
7312 AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type)
7313 {
7314 unsigned short cfg_lsw;
7315 unsigned short bios_addr;
7316
7317 /*
7318 * The PCI BIOS is re-located by the motherboard BIOS. Because
7319 * of this the driver can not determine where a PCI BIOS is
7320 * loaded and executes.
7321 */
7322 if (bus_type & ASC_IS_PCI)
7323 return 0;
7324
7325 #ifdef CONFIG_ISA
7326 if ((bus_type & ASC_IS_EISA) != 0) {
7327 cfg_lsw = AscGetEisaChipCfg(iop_base);
7328 cfg_lsw &= 0x000F;
7329 bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
7330 return bios_addr;
7331 }
7332 #endif /* CONFIG_ISA */
7333
7334 cfg_lsw = AscGetChipCfgLsw(iop_base);
7335
7336 /*
7337 * ISA PnP uses the top bit as the 32K BIOS flag
7338 */
7339 if (bus_type == ASC_IS_ISAPNP)
7340 cfg_lsw &= 0x7FFF;
7341 bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
7342 return bios_addr;
7343 }
7344
7345 /*
7346 * --- Functions Required by the Adv Library
7347 */
7348
7349 /*
7350 * DvcGetPhyAddr()
7351 *
7352 * Return the physical address of 'vaddr' and set '*lenp' to the
7353 * number of physically contiguous bytes that follow 'vaddr'.
7354 * 'flag' indicates the type of structure whose physical address
7355 * is being translated.
7356 *
7357 * Note: Because Linux currently doesn't page the kernel and all
7358 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
7359 */
7360 ADV_PADDR
7361 DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
7362 uchar *vaddr, ADV_SDCNT *lenp, int flag)
7363 {
7364 ADV_PADDR paddr;
7365
7366 paddr = virt_to_bus(vaddr);
7367
7368 ASC_DBG4(4,
7369 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
7370 (ulong)vaddr, (ulong)lenp, (ulong)*((ulong *)lenp),
7371 (ulong)paddr);
7372
7373 return paddr;
7374 }
7375
7376 /*
7377 * --- Tracing and Debugging Functions
7378 */
7379
7380 #ifdef ADVANSYS_STATS
7381 #ifdef CONFIG_PROC_FS
7382 /*
7383 * asc_prt_board_stats()
7384 *
7385 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7386 * cf. asc_prt_line().
7387 *
7388 * Return the number of characters copied into 'cp'. No more than
7389 * 'cplen' characters will be copied to 'cp'.
7390 */
7391 static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
7392 {
7393 int leftlen;
7394 int totlen;
7395 int len;
7396 struct asc_stats *s;
7397 asc_board_t *boardp;
7398
7399 leftlen = cplen;
7400 totlen = len = 0;
7401
7402 boardp = ASC_BOARDP(shost);
7403 s = &boardp->asc_stats;
7404
7405 len = asc_prt_line(cp, leftlen,
7406 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
7407 shost->host_no);
7408 ASC_PRT_NEXT();
7409
7410 len = asc_prt_line(cp, leftlen,
7411 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
7412 s->queuecommand, s->reset, s->biosparam,
7413 s->interrupt);
7414 ASC_PRT_NEXT();
7415
7416 len = asc_prt_line(cp, leftlen,
7417 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
7418 s->callback, s->done, s->build_error,
7419 s->adv_build_noreq, s->adv_build_nosg);
7420 ASC_PRT_NEXT();
7421
7422 len = asc_prt_line(cp, leftlen,
7423 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
7424 s->exe_noerror, s->exe_busy, s->exe_error,
7425 s->exe_unknown);
7426 ASC_PRT_NEXT();
7427
7428 /*
7429 * Display data transfer statistics.
7430 */
7431 if (s->cont_cnt > 0) {
7432 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
7433 ASC_PRT_NEXT();
7434
7435 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
7436 s->cont_xfer / 2,
7437 ASC_TENTHS(s->cont_xfer, 2));
7438 ASC_PRT_NEXT();
7439
7440 /* Contiguous transfer average size */
7441 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
7442 (s->cont_xfer / 2) / s->cont_cnt,
7443 ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
7444 ASC_PRT_NEXT();
7445 }
7446
7447 if (s->sg_cnt > 0) {
7448
7449 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
7450 s->sg_cnt, s->sg_elem);
7451 ASC_PRT_NEXT();
7452
7453 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
7454 s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
7455 ASC_PRT_NEXT();
7456
7457 /* Scatter gather transfer statistics */
7458 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
7459 s->sg_elem / s->sg_cnt,
7460 ASC_TENTHS(s->sg_elem, s->sg_cnt));
7461 ASC_PRT_NEXT();
7462
7463 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
7464 (s->sg_xfer / 2) / s->sg_elem,
7465 ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
7466 ASC_PRT_NEXT();
7467
7468 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
7469 (s->sg_xfer / 2) / s->sg_cnt,
7470 ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
7471 ASC_PRT_NEXT();
7472 }
7473
7474 /*
7475 * Display request queuing statistics.
7476 */
7477 len = asc_prt_line(cp, leftlen,
7478 " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
7479 HZ);
7480 ASC_PRT_NEXT();
7481
7482 return totlen;
7483 }
7484
7485 /*
7486 * asc_prt_target_stats()
7487 *
7488 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7489 * cf. asc_prt_line().
7490 *
7491 * This is separated from asc_prt_board_stats because a full set
7492 * of targets will overflow ASC_PRTBUF_SIZE.
7493 *
7494 * Return the number of characters copied into 'cp'. No more than
7495 * 'cplen' characters will be copied to 'cp'.
7496 */
7497 static int
7498 asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen)
7499 {
7500 int leftlen;
7501 int totlen;
7502 int len;
7503 struct asc_stats *s;
7504 ushort chip_scsi_id;
7505 asc_board_t *boardp;
7506 asc_queue_t *active;
7507 asc_queue_t *waiting;
7508
7509 leftlen = cplen;
7510 totlen = len = 0;
7511
7512 boardp = ASC_BOARDP(shost);
7513 s = &boardp->asc_stats;
7514
7515 active = &ASC_BOARDP(shost)->active;
7516 waiting = &ASC_BOARDP(shost)->waiting;
7517
7518 if (ASC_NARROW_BOARD(boardp)) {
7519 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7520 } else {
7521 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7522 }
7523
7524 if ((chip_scsi_id == tgt_id) ||
7525 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
7526 return 0;
7527 }
7528
7529 do {
7530 if (active->q_tot_cnt[tgt_id] > 0
7531 || waiting->q_tot_cnt[tgt_id] > 0) {
7532 len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
7533 ASC_PRT_NEXT();
7534
7535 len = asc_prt_line(cp, leftlen,
7536 " active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
7537 active->q_cur_cnt[tgt_id],
7538 active->q_max_cnt[tgt_id],
7539 active->q_tot_cnt[tgt_id],
7540 active->q_min_tim[tgt_id],
7541 active->q_max_tim[tgt_id],
7542 (active->q_tot_cnt[tgt_id] ==
7543 0) ? 0 : (active->
7544 q_tot_tim[tgt_id] /
7545 active->
7546 q_tot_cnt[tgt_id]),
7547 (active->q_tot_cnt[tgt_id] ==
7548 0) ? 0 : ASC_TENTHS(active->
7549 q_tot_tim
7550 [tgt_id],
7551 active->
7552 q_tot_cnt
7553 [tgt_id]));
7554 ASC_PRT_NEXT();
7555
7556 len = asc_prt_line(cp, leftlen,
7557 " waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
7558 waiting->q_cur_cnt[tgt_id],
7559 waiting->q_max_cnt[tgt_id],
7560 waiting->q_tot_cnt[tgt_id],
7561 waiting->q_min_tim[tgt_id],
7562 waiting->q_max_tim[tgt_id],
7563 (waiting->q_tot_cnt[tgt_id] ==
7564 0) ? 0 : (waiting->
7565 q_tot_tim[tgt_id] /
7566 waiting->
7567 q_tot_cnt[tgt_id]),
7568 (waiting->q_tot_cnt[tgt_id] ==
7569 0) ? 0 : ASC_TENTHS(waiting->
7570 q_tot_tim
7571 [tgt_id],
7572 waiting->
7573 q_tot_cnt
7574 [tgt_id]));
7575 ASC_PRT_NEXT();
7576 }
7577 } while (0);
7578
7579 return totlen;
7580 }
7581 #endif /* CONFIG_PROC_FS */
7582 #endif /* ADVANSYS_STATS */
7583
7584 #ifdef ADVANSYS_DEBUG
7585 /*
7586 * asc_prt_scsi_host()
7587 */
7588 static void asc_prt_scsi_host(struct Scsi_Host *s)
7589 {
7590 asc_board_t *boardp;
7591
7592 boardp = ASC_BOARDP(s);
7593
7594 printk("Scsi_Host at addr 0x%lx\n", (ulong)s);
7595 printk(" host_busy %u, host_no %d, last_reset %d,\n",
7596 s->host_busy, s->host_no, (unsigned)s->last_reset);
7597
7598 printk(" base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
7599 (ulong)s->base, (ulong)s->io_port, s->n_io_port, s->irq);
7600
7601 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
7602 s->dma_channel, s->this_id, s->can_queue);
7603
7604 printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
7605 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
7606
7607 if (ASC_NARROW_BOARD(boardp)) {
7608 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
7609 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
7610 } else {
7611 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
7612 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
7613 }
7614 }
7615
7616 /*
7617 * asc_prt_scsi_cmnd()
7618 */
7619 static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
7620 {
7621 printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s);
7622
7623 printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
7624 (ulong)s->device->host, (ulong)s->device, s->device->id,
7625 s->device->lun, s->device->channel);
7626
7627 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
7628
7629 printk("sc_data_direction %u, resid %d\n",
7630 s->sc_data_direction, s->resid);
7631
7632 printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len);
7633
7634 printk(" serial_number 0x%x, retries %d, allowed %d\n",
7635 (unsigned)s->serial_number, s->retries, s->allowed);
7636
7637 printk(" timeout_per_command %d\n", s->timeout_per_command);
7638
7639 printk(" scsi_done 0x%p, done 0x%p, host_scribble 0x%p, result 0x%x\n",
7640 s->scsi_done, s->done, s->host_scribble, s->result);
7641
7642 printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
7643 }
7644
7645 /*
7646 * asc_prt_asc_dvc_var()
7647 */
7648 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
7649 {
7650 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
7651
7652 printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl "
7653 "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
7654
7655 printk(" bus_type %d, isr_callback 0x%p, exe_callback 0x%p, "
7656 "init_sdtr 0x%x,\n", h->bus_type, h->isr_callback,
7657 h->exe_callback, (unsigned)h->init_sdtr);
7658
7659 printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, "
7660 "chip_no 0x%x,\n", (unsigned)h->sdtr_done,
7661 (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready,
7662 (unsigned)h->chip_no);
7663
7664 printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait "
7665 "%u,\n", (unsigned)h->queue_full_or_busy,
7666 (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
7667
7668 printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, "
7669 "in_critical_cnt %u,\n", (unsigned)h->is_in_int,
7670 (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng,
7671 (unsigned)h->in_critical_cnt);
7672
7673 printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, "
7674 "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage,
7675 (unsigned)h->init_state, (unsigned)h->no_scam,
7676 (unsigned)h->pci_fix_asyn_xfer);
7677
7678 printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no);
7679 }
7680
7681 /*
7682 * asc_prt_asc_dvc_cfg()
7683 */
7684 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
7685 {
7686 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
7687
7688 printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
7689 h->can_tagged_qng, h->cmd_qng_enabled);
7690 printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
7691 h->disc_enable, h->sdtr_enable);
7692
7693 printk
7694 (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
7695 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
7696 h->chip_version);
7697
7698 printk
7699 (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
7700 to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
7701 h->mcode_date);
7702
7703 printk(" mcode_version %d, overrun_buf 0x%lx\n",
7704 h->mcode_version, (ulong)h->overrun_buf);
7705 }
7706
7707 /*
7708 * asc_prt_asc_scsi_q()
7709 */
7710 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
7711 {
7712 ASC_SG_HEAD *sgp;
7713 int i;
7714
7715 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
7716
7717 printk
7718 (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
7719 q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
7720 q->q2.tag_code);
7721
7722 printk
7723 (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7724 (ulong)le32_to_cpu(q->q1.data_addr),
7725 (ulong)le32_to_cpu(q->q1.data_cnt),
7726 (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
7727
7728 printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
7729 (ulong)q->cdbptr, q->q2.cdb_len,
7730 (ulong)q->sg_head, q->q1.sg_queue_cnt);
7731
7732 if (q->sg_head) {
7733 sgp = q->sg_head;
7734 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
7735 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
7736 sgp->queue_cnt);
7737 for (i = 0; i < sgp->entry_cnt; i++) {
7738 printk(" [%u]: addr 0x%lx, bytes %lu\n",
7739 i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
7740 (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
7741 }
7742
7743 }
7744 }
7745
7746 /*
7747 * asc_prt_asc_qdone_info()
7748 */
7749 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
7750 {
7751 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
7752 printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
7753 (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
7754 q->d2.tag_code);
7755 printk
7756 (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
7757 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
7758 }
7759
7760 /*
7761 * asc_prt_adv_dvc_var()
7762 *
7763 * Display an ADV_DVC_VAR structure.
7764 */
7765 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
7766 {
7767 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
7768
7769 printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
7770 (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
7771
7772 printk(" isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
7773 (ulong)h->isr_callback, (unsigned)h->sdtr_able,
7774 (unsigned)h->wdtr_able);
7775
7776 printk(" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
7777 (unsigned)h->start_motor,
7778 (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no);
7779
7780 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
7781 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
7782 (ulong)h->carr_freelist);
7783
7784 printk(" icq_sp 0x%lx, irq_sp 0x%lx\n",
7785 (ulong)h->icq_sp, (ulong)h->irq_sp);
7786
7787 printk(" no_scam 0x%x, tagqng_able 0x%x\n",
7788 (unsigned)h->no_scam, (unsigned)h->tagqng_able);
7789
7790 printk(" chip_scsi_id 0x%x, cfg 0x%lx\n",
7791 (unsigned)h->chip_scsi_id, (ulong)h->cfg);
7792 }
7793
7794 /*
7795 * asc_prt_adv_dvc_cfg()
7796 *
7797 * Display an ADV_DVC_CFG structure.
7798 */
7799 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
7800 {
7801 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
7802
7803 printk(" disc_enable 0x%x, termination 0x%x\n",
7804 h->disc_enable, h->termination);
7805
7806 printk(" chip_version 0x%x, mcode_date 0x%x\n",
7807 h->chip_version, h->mcode_date);
7808
7809 printk(" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
7810 h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
7811
7812 printk(" control_flag 0x%x, pci_slot_info 0x%x\n",
7813 h->control_flag, h->pci_slot_info);
7814 }
7815
7816 /*
7817 * asc_prt_adv_scsi_req_q()
7818 *
7819 * Display an ADV_SCSI_REQ_Q structure.
7820 */
7821 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
7822 {
7823 int sg_blk_cnt;
7824 struct asc_sg_block *sg_ptr;
7825
7826 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
7827
7828 printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
7829 q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
7830
7831 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
7832 q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
7833
7834 printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7835 (ulong)le32_to_cpu(q->data_cnt),
7836 (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
7837
7838 printk
7839 (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
7840 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
7841
7842 printk(" sg_working_ix 0x%x, target_cmd %u\n",
7843 q->sg_working_ix, q->target_cmd);
7844
7845 printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
7846 (ulong)le32_to_cpu(q->scsiq_rptr),
7847 (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
7848
7849 /* Display the request's ADV_SG_BLOCK structures. */
7850 if (q->sg_list_ptr != NULL) {
7851 sg_blk_cnt = 0;
7852 while (1) {
7853 /*
7854 * 'sg_ptr' is a physical address. Convert it to a virtual
7855 * address by indexing 'sg_blk_cnt' into the virtual address
7856 * array 'sg_list_ptr'.
7857 *
7858 * XXX - Assumes all SG physical blocks are virtually contiguous.
7859 */
7860 sg_ptr =
7861 &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
7862 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
7863 if (sg_ptr->sg_ptr == 0) {
7864 break;
7865 }
7866 sg_blk_cnt++;
7867 }
7868 }
7869 }
7870
7871 /*
7872 * asc_prt_adv_sgblock()
7873 *
7874 * Display an ADV_SG_BLOCK structure.
7875 */
7876 static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
7877 {
7878 int i;
7879
7880 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
7881 (ulong)b, sgblockno);
7882 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
7883 b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
7884 ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
7885 if (b->sg_ptr != 0) {
7886 ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
7887 }
7888 for (i = 0; i < b->sg_cnt; i++) {
7889 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
7890 i, (ulong)b->sg_list[i].sg_addr,
7891 (ulong)b->sg_list[i].sg_count);
7892 }
7893 }
7894
7895 /*
7896 * asc_prt_hex()
7897 *
7898 * Print hexadecimal output in 4 byte groupings 32 bytes
7899 * or 8 double-words per line.
7900 */
7901 static void asc_prt_hex(char *f, uchar *s, int l)
7902 {
7903 int i;
7904 int j;
7905 int k;
7906 int m;
7907
7908 printk("%s: (%d bytes)\n", f, l);
7909
7910 for (i = 0; i < l; i += 32) {
7911
7912 /* Display a maximum of 8 double-words per line. */
7913 if ((k = (l - i) / 4) >= 8) {
7914 k = 8;
7915 m = 0;
7916 } else {
7917 m = (l - i) % 4;
7918 }
7919
7920 for (j = 0; j < k; j++) {
7921 printk(" %2.2X%2.2X%2.2X%2.2X",
7922 (unsigned)s[i + (j * 4)],
7923 (unsigned)s[i + (j * 4) + 1],
7924 (unsigned)s[i + (j * 4) + 2],
7925 (unsigned)s[i + (j * 4) + 3]);
7926 }
7927
7928 switch (m) {
7929 case 0:
7930 default:
7931 break;
7932 case 1:
7933 printk(" %2.2X", (unsigned)s[i + (j * 4)]);
7934 break;
7935 case 2:
7936 printk(" %2.2X%2.2X",
7937 (unsigned)s[i + (j * 4)],
7938 (unsigned)s[i + (j * 4) + 1]);
7939 break;
7940 case 3:
7941 printk(" %2.2X%2.2X%2.2X",
7942 (unsigned)s[i + (j * 4) + 1],
7943 (unsigned)s[i + (j * 4) + 2],
7944 (unsigned)s[i + (j * 4) + 3]);
7945 break;
7946 }
7947
7948 printk("\n");
7949 }
7950 }
7951 #endif /* ADVANSYS_DEBUG */
7952
7953 /*
7954 * --- Asc Library Functions
7955 */
7956
7957 static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
7958 {
7959 PortAddr eisa_cfg_iop;
7960
7961 eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
7962 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
7963 return (inpw(eisa_cfg_iop));
7964 }
7965
7966 static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
7967 {
7968 ushort cfg_lsw;
7969
7970 if (AscGetChipScsiID(iop_base) == new_host_id) {
7971 return (new_host_id);
7972 }
7973 cfg_lsw = AscGetChipCfgLsw(iop_base);
7974 cfg_lsw &= 0xF8FF;
7975 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
7976 AscSetChipCfgLsw(iop_base, cfg_lsw);
7977 return (AscGetChipScsiID(iop_base));
7978 }
7979
7980 static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base)
7981 {
7982 unsigned char sc;
7983
7984 AscSetBank(iop_base, 1);
7985 sc = inp(iop_base + IOP_REG_SC);
7986 AscSetBank(iop_base, 0);
7987 return sc;
7988 }
7989
7990 static unsigned char __devinit
7991 AscGetChipVersion(PortAddr iop_base, unsigned short bus_type)
7992 {
7993 if (bus_type & ASC_IS_EISA) {
7994 PortAddr eisa_iop;
7995 unsigned char revision;
7996 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
7997 (PortAddr) ASC_EISA_REV_IOP_MASK;
7998 revision = inp(eisa_iop);
7999 return ASC_CHIP_MIN_VER_EISA - 1 + revision;
8000 }
8001 return AscGetChipVerNo(iop_base);
8002 }
8003
8004 static ASC_DCNT
8005 AscLoadMicroCode(PortAddr iop_base,
8006 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
8007 {
8008 ASC_DCNT chksum;
8009 ushort mcode_word_size;
8010 ushort mcode_chksum;
8011
8012 /* Write the microcode buffer starting at LRAM address 0. */
8013 mcode_word_size = (ushort)(mcode_size >> 1);
8014 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
8015 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
8016
8017 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
8018 ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum);
8019 mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
8020 (ushort)ASC_CODE_SEC_BEG,
8021 (ushort)((mcode_size -
8022 s_addr - (ushort)
8023 ASC_CODE_SEC_BEG) /
8024 2));
8025 ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
8026 (ulong)mcode_chksum);
8027 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
8028 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
8029 return (chksum);
8030 }
8031
8032 static int AscFindSignature(PortAddr iop_base)
8033 {
8034 ushort sig_word;
8035
8036 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
8037 iop_base, AscGetChipSignatureByte(iop_base));
8038 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
8039 ASC_DBG2(1,
8040 "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
8041 iop_base, AscGetChipSignatureWord(iop_base));
8042 sig_word = AscGetChipSignatureWord(iop_base);
8043 if ((sig_word == (ushort)ASC_1000_ID0W) ||
8044 (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
8045 return (1);
8046 }
8047 }
8048 return (0);
8049 }
8050
8051 static void __devinit AscToggleIRQAct(PortAddr iop_base)
8052 {
8053 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
8054 AscSetChipStatus(iop_base, 0);
8055 return;
8056 }
8057
8058 static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
8059 {
8060 ushort cfg_lsw;
8061 uchar chip_irq;
8062
8063 if ((bus_type & ASC_IS_EISA) != 0) {
8064 cfg_lsw = AscGetEisaChipCfg(iop_base);
8065 chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10);
8066 if ((chip_irq == 13) || (chip_irq > 15)) {
8067 return (0);
8068 }
8069 return (chip_irq);
8070 }
8071 if ((bus_type & ASC_IS_VL) != 0) {
8072 cfg_lsw = AscGetChipCfgLsw(iop_base);
8073 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07));
8074 if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) {
8075 return (0);
8076 }
8077 return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1)));
8078 }
8079 cfg_lsw = AscGetChipCfgLsw(iop_base);
8080 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03));
8081 if (chip_irq == 3)
8082 chip_irq += (uchar)2;
8083 return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
8084 }
8085
8086 static uchar __devinit
8087 AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
8088 {
8089 ushort cfg_lsw;
8090
8091 if ((bus_type & ASC_IS_VL) != 0) {
8092 if (irq_no != 0) {
8093 if ((irq_no < ASC_MIN_IRQ_NO)
8094 || (irq_no > ASC_MAX_IRQ_NO)) {
8095 irq_no = 0;
8096 } else {
8097 irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1));
8098 }
8099 }
8100 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3);
8101 cfg_lsw |= (ushort)0x0010;
8102 AscSetChipCfgLsw(iop_base, cfg_lsw);
8103 AscToggleIRQAct(iop_base);
8104 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0);
8105 cfg_lsw |= (ushort)((irq_no & 0x07) << 2);
8106 AscSetChipCfgLsw(iop_base, cfg_lsw);
8107 AscToggleIRQAct(iop_base);
8108 return (AscGetChipIRQ(iop_base, bus_type));
8109 }
8110 if ((bus_type & (ASC_IS_ISA)) != 0) {
8111 if (irq_no == 15)
8112 irq_no -= (uchar)2;
8113 irq_no -= (uchar)ASC_MIN_IRQ_NO;
8114 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3);
8115 cfg_lsw |= (ushort)((irq_no & 0x03) << 2);
8116 AscSetChipCfgLsw(iop_base, cfg_lsw);
8117 return (AscGetChipIRQ(iop_base, bus_type));
8118 }
8119 return (0);
8120 }
8121
8122 #ifdef CONFIG_ISA
8123 static void __devinit AscEnableIsaDma(uchar dma_channel)
8124 {
8125 if (dma_channel < 4) {
8126 outp(0x000B, (ushort)(0xC0 | dma_channel));
8127 outp(0x000A, dma_channel);
8128 } else if (dma_channel < 8) {
8129 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
8130 outp(0x00D4, (ushort)(dma_channel - 4));
8131 }
8132 return;
8133 }
8134 #endif /* CONFIG_ISA */
8135
8136 static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
8137 {
8138 EXT_MSG ext_msg;
8139 EXT_MSG out_msg;
8140 ushort halt_q_addr;
8141 int sdtr_accept;
8142 ushort int_halt_code;
8143 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8144 ASC_SCSI_BIT_ID_TYPE target_id;
8145 PortAddr iop_base;
8146 uchar tag_code;
8147 uchar q_status;
8148 uchar halt_qp;
8149 uchar sdtr_data;
8150 uchar target_ix;
8151 uchar q_cntl, tid_no;
8152 uchar cur_dvc_qng;
8153 uchar asyn_sdtr;
8154 uchar scsi_status;
8155 asc_board_t *boardp;
8156
8157 ASC_ASSERT(asc_dvc->drv_ptr != NULL);
8158 boardp = asc_dvc->drv_ptr;
8159
8160 iop_base = asc_dvc->iop_base;
8161 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
8162
8163 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
8164 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
8165 target_ix = AscReadLramByte(iop_base,
8166 (ushort)(halt_q_addr +
8167 (ushort)ASC_SCSIQ_B_TARGET_IX));
8168 q_cntl =
8169 AscReadLramByte(iop_base,
8170 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8171 tid_no = ASC_TIX_TO_TID(target_ix);
8172 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
8173 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8174 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
8175 } else {
8176 asyn_sdtr = 0;
8177 }
8178 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
8179 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8180 AscSetChipSDTR(iop_base, 0, tid_no);
8181 boardp->sdtr_data[tid_no] = 0;
8182 }
8183 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8184 return (0);
8185 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
8186 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8187 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8188 boardp->sdtr_data[tid_no] = asyn_sdtr;
8189 }
8190 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8191 return (0);
8192 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
8193
8194 AscMemWordCopyPtrFromLram(iop_base,
8195 ASCV_MSGIN_BEG,
8196 (uchar *)&ext_msg,
8197 sizeof(EXT_MSG) >> 1);
8198
8199 if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8200 ext_msg.msg_req == EXTENDED_SDTR &&
8201 ext_msg.msg_len == MS_SDTR_LEN) {
8202 sdtr_accept = TRUE;
8203 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
8204
8205 sdtr_accept = FALSE;
8206 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
8207 }
8208 if ((ext_msg.xfer_period <
8209 asc_dvc->sdtr_period_tbl[asc_dvc->
8210 host_init_sdtr_index])
8211 || (ext_msg.xfer_period >
8212 asc_dvc->sdtr_period_tbl[asc_dvc->
8213 max_sdtr_index])) {
8214 sdtr_accept = FALSE;
8215 ext_msg.xfer_period =
8216 asc_dvc->sdtr_period_tbl[asc_dvc->
8217 host_init_sdtr_index];
8218 }
8219 if (sdtr_accept) {
8220 sdtr_data =
8221 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
8222 ext_msg.req_ack_offset);
8223 if ((sdtr_data == 0xFF)) {
8224
8225 q_cntl |= QC_MSG_OUT;
8226 asc_dvc->init_sdtr &= ~target_id;
8227 asc_dvc->sdtr_done &= ~target_id;
8228 AscSetChipSDTR(iop_base, asyn_sdtr,
8229 tid_no);
8230 boardp->sdtr_data[tid_no] = asyn_sdtr;
8231 }
8232 }
8233 if (ext_msg.req_ack_offset == 0) {
8234
8235 q_cntl &= ~QC_MSG_OUT;
8236 asc_dvc->init_sdtr &= ~target_id;
8237 asc_dvc->sdtr_done &= ~target_id;
8238 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8239 } else {
8240 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
8241
8242 q_cntl &= ~QC_MSG_OUT;
8243 asc_dvc->sdtr_done |= target_id;
8244 asc_dvc->init_sdtr |= target_id;
8245 asc_dvc->pci_fix_asyn_xfer &=
8246 ~target_id;
8247 sdtr_data =
8248 AscCalSDTRData(asc_dvc,
8249 ext_msg.xfer_period,
8250 ext_msg.
8251 req_ack_offset);
8252 AscSetChipSDTR(iop_base, sdtr_data,
8253 tid_no);
8254 boardp->sdtr_data[tid_no] = sdtr_data;
8255 } else {
8256
8257 q_cntl |= QC_MSG_OUT;
8258 AscMsgOutSDTR(asc_dvc,
8259 ext_msg.xfer_period,
8260 ext_msg.req_ack_offset);
8261 asc_dvc->pci_fix_asyn_xfer &=
8262 ~target_id;
8263 sdtr_data =
8264 AscCalSDTRData(asc_dvc,
8265 ext_msg.xfer_period,
8266 ext_msg.
8267 req_ack_offset);
8268 AscSetChipSDTR(iop_base, sdtr_data,
8269 tid_no);
8270 boardp->sdtr_data[tid_no] = sdtr_data;
8271 asc_dvc->sdtr_done |= target_id;
8272 asc_dvc->init_sdtr |= target_id;
8273 }
8274 }
8275
8276 AscWriteLramByte(iop_base,
8277 (ushort)(halt_q_addr +
8278 (ushort)ASC_SCSIQ_B_CNTL),
8279 q_cntl);
8280 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8281 return (0);
8282 } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8283 ext_msg.msg_req == EXTENDED_WDTR &&
8284 ext_msg.msg_len == MS_WDTR_LEN) {
8285
8286 ext_msg.wdtr_width = 0;
8287 AscMemWordCopyPtrToLram(iop_base,
8288 ASCV_MSGOUT_BEG,
8289 (uchar *)&ext_msg,
8290 sizeof(EXT_MSG) >> 1);
8291 q_cntl |= QC_MSG_OUT;
8292 AscWriteLramByte(iop_base,
8293 (ushort)(halt_q_addr +
8294 (ushort)ASC_SCSIQ_B_CNTL),
8295 q_cntl);
8296 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8297 return (0);
8298 } else {
8299
8300 ext_msg.msg_type = MESSAGE_REJECT;
8301 AscMemWordCopyPtrToLram(iop_base,
8302 ASCV_MSGOUT_BEG,
8303 (uchar *)&ext_msg,
8304 sizeof(EXT_MSG) >> 1);
8305 q_cntl |= QC_MSG_OUT;
8306 AscWriteLramByte(iop_base,
8307 (ushort)(halt_q_addr +
8308 (ushort)ASC_SCSIQ_B_CNTL),
8309 q_cntl);
8310 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8311 return (0);
8312 }
8313 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
8314
8315 q_cntl |= QC_REQ_SENSE;
8316
8317 if ((asc_dvc->init_sdtr & target_id) != 0) {
8318
8319 asc_dvc->sdtr_done &= ~target_id;
8320
8321 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8322 q_cntl |= QC_MSG_OUT;
8323 AscMsgOutSDTR(asc_dvc,
8324 asc_dvc->
8325 sdtr_period_tbl[(sdtr_data >> 4) &
8326 (uchar)(asc_dvc->
8327 max_sdtr_index -
8328 1)],
8329 (uchar)(sdtr_data & (uchar)
8330 ASC_SYN_MAX_OFFSET));
8331 }
8332
8333 AscWriteLramByte(iop_base,
8334 (ushort)(halt_q_addr +
8335 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8336
8337 tag_code = AscReadLramByte(iop_base,
8338 (ushort)(halt_q_addr + (ushort)
8339 ASC_SCSIQ_B_TAG_CODE));
8340 tag_code &= 0xDC;
8341 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
8342 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
8343 ) {
8344
8345 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
8346 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
8347
8348 }
8349 AscWriteLramByte(iop_base,
8350 (ushort)(halt_q_addr +
8351 (ushort)ASC_SCSIQ_B_TAG_CODE),
8352 tag_code);
8353
8354 q_status = AscReadLramByte(iop_base,
8355 (ushort)(halt_q_addr + (ushort)
8356 ASC_SCSIQ_B_STATUS));
8357 q_status |= (QS_READY | QS_BUSY);
8358 AscWriteLramByte(iop_base,
8359 (ushort)(halt_q_addr +
8360 (ushort)ASC_SCSIQ_B_STATUS),
8361 q_status);
8362
8363 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
8364 scsi_busy &= ~target_id;
8365 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8366
8367 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8368 return (0);
8369 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
8370
8371 AscMemWordCopyPtrFromLram(iop_base,
8372 ASCV_MSGOUT_BEG,
8373 (uchar *)&out_msg,
8374 sizeof(EXT_MSG) >> 1);
8375
8376 if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
8377 (out_msg.msg_len == MS_SDTR_LEN) &&
8378 (out_msg.msg_req == EXTENDED_SDTR)) {
8379
8380 asc_dvc->init_sdtr &= ~target_id;
8381 asc_dvc->sdtr_done &= ~target_id;
8382 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8383 boardp->sdtr_data[tid_no] = asyn_sdtr;
8384 }
8385 q_cntl &= ~QC_MSG_OUT;
8386 AscWriteLramByte(iop_base,
8387 (ushort)(halt_q_addr +
8388 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8389 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8390 return (0);
8391 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
8392
8393 scsi_status = AscReadLramByte(iop_base,
8394 (ushort)((ushort)halt_q_addr +
8395 (ushort)
8396 ASC_SCSIQ_SCSI_STATUS));
8397 cur_dvc_qng =
8398 AscReadLramByte(iop_base,
8399 (ushort)((ushort)ASC_QADR_BEG +
8400 (ushort)target_ix));
8401 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
8402
8403 scsi_busy = AscReadLramByte(iop_base,
8404 (ushort)ASCV_SCSIBUSY_B);
8405 scsi_busy |= target_id;
8406 AscWriteLramByte(iop_base,
8407 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8408 asc_dvc->queue_full_or_busy |= target_id;
8409
8410 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
8411 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
8412 cur_dvc_qng -= 1;
8413 asc_dvc->max_dvc_qng[tid_no] =
8414 cur_dvc_qng;
8415
8416 AscWriteLramByte(iop_base,
8417 (ushort)((ushort)
8418 ASCV_MAX_DVC_QNG_BEG
8419 + (ushort)
8420 tid_no),
8421 cur_dvc_qng);
8422
8423 /*
8424 * Set the device queue depth to the number of
8425 * active requests when the QUEUE FULL condition
8426 * was encountered.
8427 */
8428 boardp->queue_full |= target_id;
8429 boardp->queue_full_cnt[tid_no] =
8430 cur_dvc_qng;
8431 }
8432 }
8433 }
8434 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8435 return (0);
8436 }
8437 #if CC_VERY_LONG_SG_LIST
8438 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
8439 uchar q_no;
8440 ushort q_addr;
8441 uchar sg_wk_q_no;
8442 uchar first_sg_wk_q_no;
8443 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
8444 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
8445 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
8446 ushort sg_list_dwords;
8447 ushort sg_entry_cnt;
8448 uchar next_qp;
8449 int i;
8450
8451 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
8452 if (q_no == ASC_QLINK_END) {
8453 return (0);
8454 }
8455
8456 q_addr = ASC_QNO_TO_QADDR(q_no);
8457
8458 /*
8459 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
8460 * structure pointer using a macro provided by the driver.
8461 * The ASC_SCSI_REQ pointer provides a pointer to the
8462 * host ASC_SG_HEAD structure.
8463 */
8464 /* Read request's SRB pointer. */
8465 scsiq = (ASC_SCSI_Q *)
8466 ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
8467 (ushort)
8468 (q_addr +
8469 ASC_SCSIQ_D_SRBPTR))));
8470
8471 /*
8472 * Get request's first and working SG queue.
8473 */
8474 sg_wk_q_no = AscReadLramByte(iop_base,
8475 (ushort)(q_addr +
8476 ASC_SCSIQ_B_SG_WK_QP));
8477
8478 first_sg_wk_q_no = AscReadLramByte(iop_base,
8479 (ushort)(q_addr +
8480 ASC_SCSIQ_B_FIRST_SG_WK_QP));
8481
8482 /*
8483 * Reset request's working SG queue back to the
8484 * first SG queue.
8485 */
8486 AscWriteLramByte(iop_base,
8487 (ushort)(q_addr +
8488 (ushort)ASC_SCSIQ_B_SG_WK_QP),
8489 first_sg_wk_q_no);
8490
8491 sg_head = scsiq->sg_head;
8492
8493 /*
8494 * Set sg_entry_cnt to the number of SG elements
8495 * that will be completed on this interrupt.
8496 *
8497 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
8498 * SG elements. The data_cnt and data_addr fields which
8499 * add 1 to the SG element capacity are not used when
8500 * restarting SG handling after a halt.
8501 */
8502 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
8503 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
8504
8505 /*
8506 * Keep track of remaining number of SG elements that will
8507 * need to be handled on the next interrupt.
8508 */
8509 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
8510 } else {
8511 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
8512 scsiq->remain_sg_entry_cnt = 0;
8513 }
8514
8515 /*
8516 * Copy SG elements into the list of allocated SG queues.
8517 *
8518 * Last index completed is saved in scsiq->next_sg_index.
8519 */
8520 next_qp = first_sg_wk_q_no;
8521 q_addr = ASC_QNO_TO_QADDR(next_qp);
8522 scsi_sg_q.sg_head_qp = q_no;
8523 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
8524 for (i = 0; i < sg_head->queue_cnt; i++) {
8525 scsi_sg_q.seq_no = i + 1;
8526 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
8527 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
8528 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
8529 /*
8530 * After very first SG queue RISC FW uses next
8531 * SG queue first element then checks sg_list_cnt
8532 * against zero and then decrements, so set
8533 * sg_list_cnt 1 less than number of SG elements
8534 * in each SG queue.
8535 */
8536 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
8537 scsi_sg_q.sg_cur_list_cnt =
8538 ASC_SG_LIST_PER_Q - 1;
8539 } else {
8540 /*
8541 * This is the last SG queue in the list of
8542 * allocated SG queues. If there are more
8543 * SG elements than will fit in the allocated
8544 * queues, then set the QCSG_SG_XFER_MORE flag.
8545 */
8546 if (scsiq->remain_sg_entry_cnt != 0) {
8547 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
8548 } else {
8549 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
8550 }
8551 /* equals sg_entry_cnt * 2 */
8552 sg_list_dwords = sg_entry_cnt << 1;
8553 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
8554 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
8555 sg_entry_cnt = 0;
8556 }
8557
8558 scsi_sg_q.q_no = next_qp;
8559 AscMemWordCopyPtrToLram(iop_base,
8560 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
8561 (uchar *)&scsi_sg_q,
8562 sizeof(ASC_SG_LIST_Q) >> 1);
8563
8564 AscMemDWordCopyPtrToLram(iop_base,
8565 q_addr + ASC_SGQ_LIST_BEG,
8566 (uchar *)&sg_head->
8567 sg_list[scsiq->next_sg_index],
8568 sg_list_dwords);
8569
8570 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
8571
8572 /*
8573 * If the just completed SG queue contained the
8574 * last SG element, then no more SG queues need
8575 * to be written.
8576 */
8577 if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
8578 break;
8579 }
8580
8581 next_qp = AscReadLramByte(iop_base,
8582 (ushort)(q_addr +
8583 ASC_SCSIQ_B_FWD));
8584 q_addr = ASC_QNO_TO_QADDR(next_qp);
8585 }
8586
8587 /*
8588 * Clear the halt condition so the RISC will be restarted
8589 * after the return.
8590 */
8591 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8592 return (0);
8593 }
8594 #endif /* CC_VERY_LONG_SG_LIST */
8595 return (0);
8596 }
8597
8598 static uchar
8599 _AscCopyLramScsiDoneQ(PortAddr iop_base,
8600 ushort q_addr,
8601 ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
8602 {
8603 ushort _val;
8604 uchar sg_queue_cnt;
8605
8606 DvcGetQinfo(iop_base,
8607 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
8608 (uchar *)scsiq,
8609 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
8610
8611 _val = AscReadLramWord(iop_base,
8612 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
8613 scsiq->q_status = (uchar)_val;
8614 scsiq->q_no = (uchar)(_val >> 8);
8615 _val = AscReadLramWord(iop_base,
8616 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8617 scsiq->cntl = (uchar)_val;
8618 sg_queue_cnt = (uchar)(_val >> 8);
8619 _val = AscReadLramWord(iop_base,
8620 (ushort)(q_addr +
8621 (ushort)ASC_SCSIQ_B_SENSE_LEN));
8622 scsiq->sense_len = (uchar)_val;
8623 scsiq->extra_bytes = (uchar)(_val >> 8);
8624
8625 /*
8626 * Read high word of remain bytes from alternate location.
8627 */
8628 scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
8629 (ushort)(q_addr +
8630 (ushort)
8631 ASC_SCSIQ_W_ALT_DC1)))
8632 << 16);
8633 /*
8634 * Read low word of remain bytes from original location.
8635 */
8636 scsiq->remain_bytes += AscReadLramWord(iop_base,
8637 (ushort)(q_addr + (ushort)
8638 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
8639
8640 scsiq->remain_bytes &= max_dma_count;
8641 return (sg_queue_cnt);
8642 }
8643
8644 static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
8645 {
8646 uchar next_qp;
8647 uchar n_q_used;
8648 uchar sg_list_qp;
8649 uchar sg_queue_cnt;
8650 uchar q_cnt;
8651 uchar done_q_tail;
8652 uchar tid_no;
8653 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8654 ASC_SCSI_BIT_ID_TYPE target_id;
8655 PortAddr iop_base;
8656 ushort q_addr;
8657 ushort sg_q_addr;
8658 uchar cur_target_qng;
8659 ASC_QDONE_INFO scsiq_buf;
8660 ASC_QDONE_INFO *scsiq;
8661 int false_overrun;
8662 ASC_ISR_CALLBACK asc_isr_callback;
8663
8664 iop_base = asc_dvc->iop_base;
8665 asc_isr_callback = asc_dvc->isr_callback;
8666 n_q_used = 1;
8667 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
8668 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
8669 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
8670 next_qp = AscReadLramByte(iop_base,
8671 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
8672 if (next_qp != ASC_QLINK_END) {
8673 AscPutVarDoneQTail(iop_base, next_qp);
8674 q_addr = ASC_QNO_TO_QADDR(next_qp);
8675 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
8676 asc_dvc->max_dma_count);
8677 AscWriteLramByte(iop_base,
8678 (ushort)(q_addr +
8679 (ushort)ASC_SCSIQ_B_STATUS),
8680 (uchar)(scsiq->
8681 q_status & (uchar)~(QS_READY |
8682 QS_ABORTED)));
8683 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
8684 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
8685 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
8686 sg_q_addr = q_addr;
8687 sg_list_qp = next_qp;
8688 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
8689 sg_list_qp = AscReadLramByte(iop_base,
8690 (ushort)(sg_q_addr
8691 + (ushort)
8692 ASC_SCSIQ_B_FWD));
8693 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
8694 if (sg_list_qp == ASC_QLINK_END) {
8695 AscSetLibErrorCode(asc_dvc,
8696 ASCQ_ERR_SG_Q_LINKS);
8697 scsiq->d3.done_stat = QD_WITH_ERROR;
8698 scsiq->d3.host_stat =
8699 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
8700 goto FATAL_ERR_QDONE;
8701 }
8702 AscWriteLramByte(iop_base,
8703 (ushort)(sg_q_addr + (ushort)
8704 ASC_SCSIQ_B_STATUS),
8705 QS_FREE);
8706 }
8707 n_q_used = sg_queue_cnt + 1;
8708 AscPutVarDoneQTail(iop_base, sg_list_qp);
8709 }
8710 if (asc_dvc->queue_full_or_busy & target_id) {
8711 cur_target_qng = AscReadLramByte(iop_base,
8712 (ushort)((ushort)
8713 ASC_QADR_BEG
8714 + (ushort)
8715 scsiq->d2.
8716 target_ix));
8717 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
8718 scsi_busy = AscReadLramByte(iop_base, (ushort)
8719 ASCV_SCSIBUSY_B);
8720 scsi_busy &= ~target_id;
8721 AscWriteLramByte(iop_base,
8722 (ushort)ASCV_SCSIBUSY_B,
8723 scsi_busy);
8724 asc_dvc->queue_full_or_busy &= ~target_id;
8725 }
8726 }
8727 if (asc_dvc->cur_total_qng >= n_q_used) {
8728 asc_dvc->cur_total_qng -= n_q_used;
8729 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
8730 asc_dvc->cur_dvc_qng[tid_no]--;
8731 }
8732 } else {
8733 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
8734 scsiq->d3.done_stat = QD_WITH_ERROR;
8735 goto FATAL_ERR_QDONE;
8736 }
8737 if ((scsiq->d2.srb_ptr == 0UL) ||
8738 ((scsiq->q_status & QS_ABORTED) != 0)) {
8739 return (0x11);
8740 } else if (scsiq->q_status == QS_DONE) {
8741 false_overrun = FALSE;
8742 if (scsiq->extra_bytes != 0) {
8743 scsiq->remain_bytes +=
8744 (ADV_DCNT)scsiq->extra_bytes;
8745 }
8746 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
8747 if (scsiq->d3.host_stat ==
8748 QHSTA_M_DATA_OVER_RUN) {
8749 if ((scsiq->
8750 cntl & (QC_DATA_IN | QC_DATA_OUT))
8751 == 0) {
8752 scsiq->d3.done_stat =
8753 QD_NO_ERROR;
8754 scsiq->d3.host_stat =
8755 QHSTA_NO_ERROR;
8756 } else if (false_overrun) {
8757 scsiq->d3.done_stat =
8758 QD_NO_ERROR;
8759 scsiq->d3.host_stat =
8760 QHSTA_NO_ERROR;
8761 }
8762 } else if (scsiq->d3.host_stat ==
8763 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
8764 AscStopChip(iop_base);
8765 AscSetChipControl(iop_base,
8766 (uchar)(CC_SCSI_RESET
8767 | CC_HALT));
8768 DvcDelayNanoSecond(asc_dvc, 60000);
8769 AscSetChipControl(iop_base, CC_HALT);
8770 AscSetChipStatus(iop_base,
8771 CIW_CLR_SCSI_RESET_INT);
8772 AscSetChipStatus(iop_base, 0);
8773 AscSetChipControl(iop_base, 0);
8774 }
8775 }
8776 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
8777 (*asc_isr_callback) (asc_dvc, scsiq);
8778 } else {
8779 if ((AscReadLramByte(iop_base,
8780 (ushort)(q_addr + (ushort)
8781 ASC_SCSIQ_CDB_BEG))
8782 == START_STOP)) {
8783 asc_dvc->unit_not_ready &= ~target_id;
8784 if (scsiq->d3.done_stat != QD_NO_ERROR) {
8785 asc_dvc->start_motor &=
8786 ~target_id;
8787 }
8788 }
8789 }
8790 return (1);
8791 } else {
8792 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
8793 FATAL_ERR_QDONE:
8794 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
8795 (*asc_isr_callback) (asc_dvc, scsiq);
8796 }
8797 return (0x80);
8798 }
8799 }
8800 return (0);
8801 }
8802
8803 static int AscISR(ASC_DVC_VAR *asc_dvc)
8804 {
8805 ASC_CS_TYPE chipstat;
8806 PortAddr iop_base;
8807 ushort saved_ram_addr;
8808 uchar ctrl_reg;
8809 uchar saved_ctrl_reg;
8810 int int_pending;
8811 int status;
8812 uchar host_flag;
8813
8814 iop_base = asc_dvc->iop_base;
8815 int_pending = FALSE;
8816
8817 if (AscIsIntPending(iop_base) == 0) {
8818 return int_pending;
8819 }
8820
8821 if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
8822 || (asc_dvc->isr_callback == 0)
8823 ) {
8824 return (ERR);
8825 }
8826 if (asc_dvc->in_critical_cnt != 0) {
8827 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
8828 return (ERR);
8829 }
8830 if (asc_dvc->is_in_int) {
8831 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
8832 return (ERR);
8833 }
8834 asc_dvc->is_in_int = TRUE;
8835 ctrl_reg = AscGetChipControl(iop_base);
8836 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
8837 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
8838 chipstat = AscGetChipStatus(iop_base);
8839 if (chipstat & CSW_SCSI_RESET_LATCH) {
8840 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
8841 int i = 10;
8842 int_pending = TRUE;
8843 asc_dvc->sdtr_done = 0;
8844 saved_ctrl_reg &= (uchar)(~CC_HALT);
8845 while ((AscGetChipStatus(iop_base) &
8846 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
8847 DvcSleepMilliSecond(100);
8848 }
8849 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
8850 AscSetChipControl(iop_base, CC_HALT);
8851 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
8852 AscSetChipStatus(iop_base, 0);
8853 chipstat = AscGetChipStatus(iop_base);
8854 }
8855 }
8856 saved_ram_addr = AscGetChipLramAddr(iop_base);
8857 host_flag = AscReadLramByte(iop_base,
8858 ASCV_HOST_FLAG_B) &
8859 (uchar)(~ASC_HOST_FLAG_IN_ISR);
8860 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
8861 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
8862 if ((chipstat & CSW_INT_PENDING)
8863 || (int_pending)
8864 ) {
8865 AscAckInterrupt(iop_base);
8866 int_pending = TRUE;
8867 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
8868 if (AscIsrChipHalted(asc_dvc) == ERR) {
8869 goto ISR_REPORT_QDONE_FATAL_ERROR;
8870 } else {
8871 saved_ctrl_reg &= (uchar)(~CC_HALT);
8872 }
8873 } else {
8874 ISR_REPORT_QDONE_FATAL_ERROR:
8875 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
8876 while (((status =
8877 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
8878 }
8879 } else {
8880 do {
8881 if ((status =
8882 AscIsrQDone(asc_dvc)) == 1) {
8883 break;
8884 }
8885 } while (status == 0x11);
8886 }
8887 if ((status & 0x80) != 0)
8888 int_pending = ERR;
8889 }
8890 }
8891 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
8892 AscSetChipLramAddr(iop_base, saved_ram_addr);
8893 AscSetChipControl(iop_base, saved_ctrl_reg);
8894 asc_dvc->is_in_int = FALSE;
8895 return (int_pending);
8896 }
8897
8898 /* Microcode buffer is kept after initialization for error recovery. */
8899 static uchar _asc_mcode_buf[] = {
8900 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8901 0x00, 0x00, 0x00, 0x00,
8902 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00,
8903 0x00, 0x00, 0x00, 0x00,
8904 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8905 0x00, 0x00, 0x00, 0x00,
8906 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8907 0x00, 0x00, 0x00, 0x00,
8908 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00,
8909 0x00, 0xFF, 0x00, 0x00,
8910 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00,
8911 0x00, 0x00, 0x00, 0x00,
8912 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
8913 0x00, 0x00, 0x00, 0x00,
8914 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88,
8915 0x00, 0x00, 0x00, 0x00,
8916 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73,
8917 0x03, 0x23, 0x36, 0x40,
8918 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
8919 0xC2, 0x00, 0x92, 0x80,
8920 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60,
8921 0xB6, 0x00, 0x92, 0x80,
8922 0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00,
8923 0x92, 0x80, 0x80, 0x62,
8924 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
8925 0xCD, 0x04, 0x4D, 0x00,
8926 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01,
8927 0xE6, 0x84, 0xD2, 0xC1,
8928 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97,
8929 0xC6, 0x81, 0xC2, 0x88,
8930 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
8931 0x84, 0x97, 0x07, 0xA6,
8932 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE,
8933 0xC2, 0x88, 0xCE, 0x00,
8934 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01,
8935 0x80, 0x63, 0x07, 0xA6,
8936 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
8937 0x34, 0x01, 0x00, 0x33,
8938 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23,
8939 0x68, 0x98, 0x4D, 0x04,
8940 0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23,
8941 0xF8, 0x88, 0xFB, 0x23,
8942 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
8943 0x00, 0x33, 0x0A, 0x00,
8944 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00,
8945 0xC2, 0x88, 0xCD, 0x04,
8946 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81,
8947 0x06, 0xAB, 0x82, 0x01,
8948 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
8949 0x3C, 0x01, 0x00, 0x05,
8950 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01,
8951 0x15, 0x23, 0xA1, 0x01,
8952 0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00,
8953 0x06, 0x61, 0x00, 0xA0,
8954 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
8955 0xC2, 0x88, 0x06, 0x23,
8956 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01,
8957 0x57, 0x60, 0x00, 0xA0,
8958 0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73,
8959 0x4B, 0x00, 0x06, 0x61,
8960 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
8961 0x4F, 0x00, 0x84, 0x97,
8962 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97,
8963 0x48, 0x04, 0x84, 0x80,
8964 0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00,
8965 0x81, 0x73, 0x06, 0x29,
8966 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
8967 0x04, 0x98, 0xF0, 0x80,
8968 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6,
8969 0x34, 0x02, 0x03, 0xA6,
8970 0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96,
8971 0x46, 0x82, 0xFE, 0x95,
8972 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
8973 0x07, 0xA6, 0x5A, 0x02,
8974 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95,
8975 0x48, 0x82, 0x60, 0x96,
8976 0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84,
8977 0x04, 0x01, 0x0C, 0xDC,
8978 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
8979 0x6F, 0x00, 0xA5, 0x01,
8980 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01,
8981 0x02, 0xA6, 0xAA, 0x02,
8982 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04,
8983 0x01, 0xA6, 0xB4, 0x02,
8984 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
8985 0x80, 0x63, 0x00, 0x43,
8986 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23,
8987 0x04, 0x61, 0x84, 0x01,
8988 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F,
8989 0x00, 0x00, 0xEA, 0x82,
8990 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
8991 0x00, 0x33, 0x1F, 0x00,
8992 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98,
8993 0xB6, 0x2D, 0x01, 0xA6,
8994 0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6,
8995 0x10, 0x03, 0x03, 0xA6,
8996 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
8997 0x7C, 0x95, 0xEE, 0x82,
8998 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4,
8999 0x04, 0x01, 0x2D, 0xC8,
9000 0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01,
9001 0x05, 0x05, 0x86, 0x98,
9002 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
9003 0x3C, 0x04, 0x06, 0xA6,
9004 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88,
9005 0x7C, 0x95, 0x32, 0x83,
9006 0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05,
9007 0xEB, 0x04, 0x00, 0x33,
9008 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
9009 0xFF, 0xA2, 0x7A, 0x03,
9010 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01,
9011 0x00, 0xA2, 0x9A, 0x03,
9012 0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00,
9013 0x01, 0xA6, 0x96, 0x03,
9014 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
9015 0xA4, 0x03, 0x00, 0xA6,
9016 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03,
9017 0x07, 0xA6, 0xB2, 0x03,
9018 0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88,
9019 0xA8, 0x98, 0x80, 0x42,
9020 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
9021 0xC0, 0x83, 0x00, 0x33,
9022 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23,
9023 0xA0, 0x01, 0x12, 0x23,
9024 0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B,
9025 0x80, 0x67, 0x05, 0x23,
9026 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
9027 0x06, 0xA6, 0x0A, 0x04,
9028 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96,
9029 0xF4, 0x83, 0x20, 0x84,
9030 0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
9031 0x83, 0x03, 0x80, 0x63,
9032 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
9033 0x38, 0x04, 0x00, 0x33,
9034 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84,
9035 0x1D, 0x01, 0x06, 0xCC,
9036 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62,
9037 0xA2, 0x0D, 0x80, 0x63,
9038 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
9039 0x80, 0x63, 0xA3, 0x01,
9040 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0,
9041 0x76, 0x04, 0xE0, 0x00,
9042 0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00,
9043 0x00, 0x33, 0x1E, 0x00,
9044 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
9045 0x08, 0x23, 0x22, 0xA3,
9046 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3,
9047 0xC4, 0x04, 0x42, 0x23,
9048 0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23,
9049 0xF8, 0x88, 0x04, 0x98,
9050 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
9051 0x81, 0x62, 0xE8, 0x81,
9052 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98,
9053 0x00, 0x33, 0x00, 0x81,
9054 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23,
9055 0xF8, 0x88, 0x04, 0x23,
9056 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
9057 0xF4, 0x04, 0x00, 0x33,
9058 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01,
9059 0x04, 0x23, 0xA0, 0x01,
9060 0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00,
9061 0x00, 0xA3, 0x22, 0x05,
9062 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
9063 0x46, 0x97, 0xCD, 0x04,
9064 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23,
9065 0x82, 0x01, 0x34, 0x85,
9066 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05,
9067 0x1D, 0x01, 0x04, 0xD6,
9068 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
9069 0x49, 0x00, 0x81, 0x01,
9070 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01,
9071 0x49, 0x04, 0x80, 0x01,
9072 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04,
9073 0x01, 0x23, 0xEA, 0x00,
9074 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
9075 0x07, 0xA4, 0xF8, 0x05,
9076 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00,
9077 0xC2, 0x88, 0x04, 0xA0,
9078 0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61,
9079 0x00, 0xA2, 0xA4, 0x05,
9080 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
9081 0x62, 0x97, 0x04, 0x85,
9082 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05,
9083 0xF4, 0x85, 0x03, 0xA0,
9084 0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63,
9085 0xCC, 0x86, 0x07, 0xA0,
9086 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
9087 0x80, 0x67, 0x80, 0x63,
9088 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23,
9089 0xF8, 0x88, 0x07, 0x23,
9090 0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00,
9091 0x00, 0x63, 0x4A, 0x00,
9092 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
9093 0x07, 0x41, 0x83, 0x03,
9094 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88,
9095 0x1D, 0x01, 0x01, 0xD6,
9096 0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00,
9097 0x07, 0xA6, 0x7C, 0x05,
9098 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
9099 0x52, 0x00, 0x06, 0x61,
9100 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41,
9101 0x00, 0x63, 0x1D, 0x01,
9102 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23,
9103 0x07, 0x41, 0x00, 0x63,
9104 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
9105 0xDF, 0x00, 0x06, 0xA6,
9106 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33,
9107 0x00, 0x40, 0xC0, 0x20,
9108 0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63,
9109 0x06, 0xA6, 0x94, 0x06,
9110 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
9111 0x40, 0x0E, 0x80, 0x63,
9112 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E,
9113 0x80, 0x63, 0x00, 0x43,
9114 0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05,
9115 0x80, 0x67, 0x40, 0x0E,
9116 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
9117 0x07, 0xA6, 0xD6, 0x06,
9118 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00,
9119 0x0A, 0x2B, 0x07, 0xA6,
9120 0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2,
9121 0xF4, 0x06, 0xC0, 0x0E,
9122 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
9123 0x81, 0x62, 0x04, 0x01,
9124 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6,
9125 0x8C, 0x06, 0x00, 0x33,
9126 0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03,
9127 0x80, 0x63, 0x06, 0xA6,
9128 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
9129 0x00, 0x00, 0x80, 0x67,
9130 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05,
9131 0xBF, 0x23, 0x04, 0x61,
9132 0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00,
9133 0x00, 0x01, 0xF2, 0x00,
9134 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
9135 0x80, 0x05, 0x81, 0x05,
9136 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00,
9137 0x70, 0x00, 0x81, 0x01,
9138 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04,
9139 0x70, 0x00, 0x80, 0x01,
9140 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
9141 0xF1, 0x00, 0x70, 0x00,
9142 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01,
9143 0x71, 0x04, 0x70, 0x00,
9144 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05,
9145 0xA3, 0x01, 0xA2, 0x01,
9146 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
9147 0xC4, 0x07, 0x00, 0x33,
9148 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8,
9149 0x48, 0x00, 0xB0, 0x01,
9150 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43,
9151 0x00, 0xA2, 0xE4, 0x07,
9152 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
9153 0x05, 0x05, 0x00, 0x63,
9154 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43,
9155 0x76, 0x08, 0x80, 0x02,
9156 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
9157 0x00, 0x02, 0x00, 0xA0,
9158 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
9159 0x00, 0x63, 0xF3, 0x04,
9160 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40,
9161 0x00, 0xA2, 0x44, 0x08,
9162 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1,
9163 0x24, 0x08, 0x04, 0x98,
9164 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
9165 0x5A, 0x88, 0x02, 0x01,
9166 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00,
9167 0x00, 0xA3, 0x64, 0x08,
9168 0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63,
9169 0x06, 0xA6, 0x76, 0x08,
9170 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
9171 0x00, 0x63, 0x38, 0x2B,
9172 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98,
9173 0x05, 0x05, 0xB2, 0x09,
9174 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63,
9175 0x80, 0x32, 0x80, 0x36,
9176 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
9177 0x40, 0x36, 0x40, 0x3A,
9178 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08,
9179 0x5D, 0x00, 0xFE, 0xC3,
9180 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73,
9181 0xFF, 0xFD, 0x80, 0x73,
9182 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
9183 0xA1, 0x23, 0xA1, 0x01,
9184 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2,
9185 0x80, 0x00, 0x03, 0xC2,
9186 0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23,
9187 0xA0, 0x01, 0xE6, 0x84,
9188 };
9189
9190 static ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
9191 static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
9192
9193 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
9194 static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
9195 INQUIRY,
9196 REQUEST_SENSE,
9197 READ_CAPACITY,
9198 READ_TOC,
9199 MODE_SELECT,
9200 MODE_SENSE,
9201 MODE_SELECT_10,
9202 MODE_SENSE_10,
9203 0xFF,
9204 0xFF,
9205 0xFF,
9206 0xFF,
9207 0xFF,
9208 0xFF,
9209 0xFF,
9210 0xFF
9211 };
9212
9213 static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
9214 {
9215 PortAddr iop_base;
9216 ulong last_int_level;
9217 int sta;
9218 int n_q_required;
9219 int disable_syn_offset_one_fix;
9220 int i;
9221 ASC_PADDR addr;
9222 ASC_EXE_CALLBACK asc_exe_callback;
9223 ushort sg_entry_cnt = 0;
9224 ushort sg_entry_cnt_minus_one = 0;
9225 uchar target_ix;
9226 uchar tid_no;
9227 uchar sdtr_data;
9228 uchar extra_bytes;
9229 uchar scsi_cmd;
9230 uchar disable_cmd;
9231 ASC_SG_HEAD *sg_head;
9232 ASC_DCNT data_cnt;
9233
9234 iop_base = asc_dvc->iop_base;
9235 sg_head = scsiq->sg_head;
9236 asc_exe_callback = asc_dvc->exe_callback;
9237 if (asc_dvc->err_code != 0)
9238 return (ERR);
9239 if (scsiq == (ASC_SCSI_Q *)0L) {
9240 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
9241 return (ERR);
9242 }
9243 scsiq->q1.q_no = 0;
9244 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
9245 scsiq->q1.extra_bytes = 0;
9246 }
9247 sta = 0;
9248 target_ix = scsiq->q2.target_ix;
9249 tid_no = ASC_TIX_TO_TID(target_ix);
9250 n_q_required = 1;
9251 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
9252 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
9253 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
9254 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9255 AscMsgOutSDTR(asc_dvc,
9256 asc_dvc->
9257 sdtr_period_tbl[(sdtr_data >> 4) &
9258 (uchar)(asc_dvc->
9259 max_sdtr_index -
9260 1)],
9261 (uchar)(sdtr_data & (uchar)
9262 ASC_SYN_MAX_OFFSET));
9263 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
9264 }
9265 }
9266 last_int_level = DvcEnterCritical();
9267 if (asc_dvc->in_critical_cnt != 0) {
9268 DvcLeaveCritical(last_int_level);
9269 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
9270 return (ERR);
9271 }
9272 asc_dvc->in_critical_cnt++;
9273 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9274 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
9275 asc_dvc->in_critical_cnt--;
9276 DvcLeaveCritical(last_int_level);
9277 return (ERR);
9278 }
9279 #if !CC_VERY_LONG_SG_LIST
9280 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9281 asc_dvc->in_critical_cnt--;
9282 DvcLeaveCritical(last_int_level);
9283 return (ERR);
9284 }
9285 #endif /* !CC_VERY_LONG_SG_LIST */
9286 if (sg_entry_cnt == 1) {
9287 scsiq->q1.data_addr =
9288 (ADV_PADDR)sg_head->sg_list[0].addr;
9289 scsiq->q1.data_cnt =
9290 (ADV_DCNT)sg_head->sg_list[0].bytes;
9291 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
9292 }
9293 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
9294 }
9295 scsi_cmd = scsiq->cdbptr[0];
9296 disable_syn_offset_one_fix = FALSE;
9297 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
9298 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
9299 if (scsiq->q1.cntl & QC_SG_HEAD) {
9300 data_cnt = 0;
9301 for (i = 0; i < sg_entry_cnt; i++) {
9302 data_cnt +=
9303 (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
9304 bytes);
9305 }
9306 } else {
9307 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
9308 }
9309 if (data_cnt != 0UL) {
9310 if (data_cnt < 512UL) {
9311 disable_syn_offset_one_fix = TRUE;
9312 } else {
9313 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
9314 i++) {
9315 disable_cmd =
9316 _syn_offset_one_disable_cmd[i];
9317 if (disable_cmd == 0xFF) {
9318 break;
9319 }
9320 if (scsi_cmd == disable_cmd) {
9321 disable_syn_offset_one_fix =
9322 TRUE;
9323 break;
9324 }
9325 }
9326 }
9327 }
9328 }
9329 if (disable_syn_offset_one_fix) {
9330 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9331 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
9332 ASC_TAG_FLAG_DISABLE_DISCONNECT);
9333 } else {
9334 scsiq->q2.tag_code &= 0x27;
9335 }
9336 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9337 if (asc_dvc->bug_fix_cntl) {
9338 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9339 if ((scsi_cmd == READ_6) ||
9340 (scsi_cmd == READ_10)) {
9341 addr =
9342 (ADV_PADDR)le32_to_cpu(sg_head->
9343 sg_list
9344 [sg_entry_cnt_minus_one].
9345 addr) +
9346 (ADV_DCNT)le32_to_cpu(sg_head->
9347 sg_list
9348 [sg_entry_cnt_minus_one].
9349 bytes);
9350 extra_bytes =
9351 (uchar)((ushort)addr & 0x0003);
9352 if ((extra_bytes != 0)
9353 &&
9354 ((scsiq->q2.
9355 tag_code &
9356 ASC_TAG_FLAG_EXTRA_BYTES)
9357 == 0)) {
9358 scsiq->q2.tag_code |=
9359 ASC_TAG_FLAG_EXTRA_BYTES;
9360 scsiq->q1.extra_bytes =
9361 extra_bytes;
9362 data_cnt =
9363 le32_to_cpu(sg_head->
9364 sg_list
9365 [sg_entry_cnt_minus_one].
9366 bytes);
9367 data_cnt -=
9368 (ASC_DCNT) extra_bytes;
9369 sg_head->
9370 sg_list
9371 [sg_entry_cnt_minus_one].
9372 bytes =
9373 cpu_to_le32(data_cnt);
9374 }
9375 }
9376 }
9377 }
9378 sg_head->entry_to_copy = sg_head->entry_cnt;
9379 #if CC_VERY_LONG_SG_LIST
9380 /*
9381 * Set the sg_entry_cnt to the maximum possible. The rest of
9382 * the SG elements will be copied when the RISC completes the
9383 * SG elements that fit and halts.
9384 */
9385 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9386 sg_entry_cnt = ASC_MAX_SG_LIST;
9387 }
9388 #endif /* CC_VERY_LONG_SG_LIST */
9389 n_q_required = AscSgListToQueue(sg_entry_cnt);
9390 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
9391 (uint) n_q_required)
9392 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9393 if ((sta =
9394 AscSendScsiQueue(asc_dvc, scsiq,
9395 n_q_required)) == 1) {
9396 asc_dvc->in_critical_cnt--;
9397 if (asc_exe_callback != 0) {
9398 (*asc_exe_callback) (asc_dvc, scsiq);
9399 }
9400 DvcLeaveCritical(last_int_level);
9401 return (sta);
9402 }
9403 }
9404 } else {
9405 if (asc_dvc->bug_fix_cntl) {
9406 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9407 if ((scsi_cmd == READ_6) ||
9408 (scsi_cmd == READ_10)) {
9409 addr =
9410 le32_to_cpu(scsiq->q1.data_addr) +
9411 le32_to_cpu(scsiq->q1.data_cnt);
9412 extra_bytes =
9413 (uchar)((ushort)addr & 0x0003);
9414 if ((extra_bytes != 0)
9415 &&
9416 ((scsiq->q2.
9417 tag_code &
9418 ASC_TAG_FLAG_EXTRA_BYTES)
9419 == 0)) {
9420 data_cnt =
9421 le32_to_cpu(scsiq->q1.
9422 data_cnt);
9423 if (((ushort)data_cnt & 0x01FF)
9424 == 0) {
9425 scsiq->q2.tag_code |=
9426 ASC_TAG_FLAG_EXTRA_BYTES;
9427 data_cnt -= (ASC_DCNT)
9428 extra_bytes;
9429 scsiq->q1.data_cnt =
9430 cpu_to_le32
9431 (data_cnt);
9432 scsiq->q1.extra_bytes =
9433 extra_bytes;
9434 }
9435 }
9436 }
9437 }
9438 }
9439 n_q_required = 1;
9440 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
9441 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9442 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
9443 n_q_required)) == 1) {
9444 asc_dvc->in_critical_cnt--;
9445 if (asc_exe_callback != 0) {
9446 (*asc_exe_callback) (asc_dvc, scsiq);
9447 }
9448 DvcLeaveCritical(last_int_level);
9449 return (sta);
9450 }
9451 }
9452 }
9453 asc_dvc->in_critical_cnt--;
9454 DvcLeaveCritical(last_int_level);
9455 return (sta);
9456 }
9457
9458 static int
9459 AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
9460 {
9461 PortAddr iop_base;
9462 uchar free_q_head;
9463 uchar next_qp;
9464 uchar tid_no;
9465 uchar target_ix;
9466 int sta;
9467
9468 iop_base = asc_dvc->iop_base;
9469 target_ix = scsiq->q2.target_ix;
9470 tid_no = ASC_TIX_TO_TID(target_ix);
9471 sta = 0;
9472 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
9473 if (n_q_required > 1) {
9474 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
9475 free_q_head, (uchar)
9476 (n_q_required)))
9477 != (uchar)ASC_QLINK_END) {
9478 asc_dvc->last_q_shortage = 0;
9479 scsiq->sg_head->queue_cnt = n_q_required - 1;
9480 scsiq->q1.q_no = free_q_head;
9481 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
9482 free_q_head)) == 1) {
9483 AscPutVarFreeQHead(iop_base, next_qp);
9484 asc_dvc->cur_total_qng += (uchar)(n_q_required);
9485 asc_dvc->cur_dvc_qng[tid_no]++;
9486 }
9487 return (sta);
9488 }
9489 } else if (n_q_required == 1) {
9490 if ((next_qp = AscAllocFreeQueue(iop_base,
9491 free_q_head)) !=
9492 ASC_QLINK_END) {
9493 scsiq->q1.q_no = free_q_head;
9494 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
9495 free_q_head)) == 1) {
9496 AscPutVarFreeQHead(iop_base, next_qp);
9497 asc_dvc->cur_total_qng++;
9498 asc_dvc->cur_dvc_qng[tid_no]++;
9499 }
9500 return (sta);
9501 }
9502 }
9503 return (sta);
9504 }
9505
9506 static int AscSgListToQueue(int sg_list)
9507 {
9508 int n_sg_list_qs;
9509
9510 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
9511 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
9512 n_sg_list_qs++;
9513 return (n_sg_list_qs + 1);
9514 }
9515
9516 static uint
9517 AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
9518 {
9519 uint cur_used_qs;
9520 uint cur_free_qs;
9521 ASC_SCSI_BIT_ID_TYPE target_id;
9522 uchar tid_no;
9523
9524 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
9525 tid_no = ASC_TIX_TO_TID(target_ix);
9526 if ((asc_dvc->unit_not_ready & target_id) ||
9527 (asc_dvc->queue_full_or_busy & target_id)) {
9528 return (0);
9529 }
9530 if (n_qs == 1) {
9531 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9532 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
9533 } else {
9534 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9535 (uint) ASC_MIN_FREE_Q;
9536 }
9537 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
9538 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
9539 if (asc_dvc->cur_dvc_qng[tid_no] >=
9540 asc_dvc->max_dvc_qng[tid_no]) {
9541 return (0);
9542 }
9543 return (cur_free_qs);
9544 }
9545 if (n_qs > 1) {
9546 if ((n_qs > asc_dvc->last_q_shortage)
9547 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
9548 asc_dvc->last_q_shortage = n_qs;
9549 }
9550 }
9551 return (0);
9552 }
9553
9554 static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
9555 {
9556 ushort q_addr;
9557 uchar tid_no;
9558 uchar sdtr_data;
9559 uchar syn_period_ix;
9560 uchar syn_offset;
9561 PortAddr iop_base;
9562
9563 iop_base = asc_dvc->iop_base;
9564 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
9565 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
9566 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
9567 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9568 syn_period_ix =
9569 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
9570 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
9571 AscMsgOutSDTR(asc_dvc,
9572 asc_dvc->sdtr_period_tbl[syn_period_ix],
9573 syn_offset);
9574 scsiq->q1.cntl |= QC_MSG_OUT;
9575 }
9576 q_addr = ASC_QNO_TO_QADDR(q_no);
9577 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
9578 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9579 }
9580 scsiq->q1.status = QS_FREE;
9581 AscMemWordCopyPtrToLram(iop_base,
9582 q_addr + ASC_SCSIQ_CDB_BEG,
9583 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
9584
9585 DvcPutScsiQ(iop_base,
9586 q_addr + ASC_SCSIQ_CPY_BEG,
9587 (uchar *)&scsiq->q1.cntl,
9588 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
9589 AscWriteLramWord(iop_base,
9590 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
9591 (ushort)(((ushort)scsiq->q1.
9592 q_no << 8) | (ushort)QS_READY));
9593 return (1);
9594 }
9595
9596 static int
9597 AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
9598 {
9599 int sta;
9600 int i;
9601 ASC_SG_HEAD *sg_head;
9602 ASC_SG_LIST_Q scsi_sg_q;
9603 ASC_DCNT saved_data_addr;
9604 ASC_DCNT saved_data_cnt;
9605 PortAddr iop_base;
9606 ushort sg_list_dwords;
9607 ushort sg_index;
9608 ushort sg_entry_cnt;
9609 ushort q_addr;
9610 uchar next_qp;
9611
9612 iop_base = asc_dvc->iop_base;
9613 sg_head = scsiq->sg_head;
9614 saved_data_addr = scsiq->q1.data_addr;
9615 saved_data_cnt = scsiq->q1.data_cnt;
9616 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
9617 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
9618 #if CC_VERY_LONG_SG_LIST
9619 /*
9620 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
9621 * then not all SG elements will fit in the allocated queues.
9622 * The rest of the SG elements will be copied when the RISC
9623 * completes the SG elements that fit and halts.
9624 */
9625 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9626 /*
9627 * Set sg_entry_cnt to be the number of SG elements that
9628 * will fit in the allocated SG queues. It is minus 1, because
9629 * the first SG element is handled above. ASC_MAX_SG_LIST is
9630 * already inflated by 1 to account for this. For example it
9631 * may be 50 which is 1 + 7 queues * 7 SG elements.
9632 */
9633 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
9634
9635 /*
9636 * Keep track of remaining number of SG elements that will
9637 * need to be handled from a_isr.c.
9638 */
9639 scsiq->remain_sg_entry_cnt =
9640 sg_head->entry_cnt - ASC_MAX_SG_LIST;
9641 } else {
9642 #endif /* CC_VERY_LONG_SG_LIST */
9643 /*
9644 * Set sg_entry_cnt to be the number of SG elements that
9645 * will fit in the allocated SG queues. It is minus 1, because
9646 * the first SG element is handled above.
9647 */
9648 sg_entry_cnt = sg_head->entry_cnt - 1;
9649 #if CC_VERY_LONG_SG_LIST
9650 }
9651 #endif /* CC_VERY_LONG_SG_LIST */
9652 if (sg_entry_cnt != 0) {
9653 scsiq->q1.cntl |= QC_SG_HEAD;
9654 q_addr = ASC_QNO_TO_QADDR(q_no);
9655 sg_index = 1;
9656 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
9657 scsi_sg_q.sg_head_qp = q_no;
9658 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
9659 for (i = 0; i < sg_head->queue_cnt; i++) {
9660 scsi_sg_q.seq_no = i + 1;
9661 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
9662 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
9663 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
9664 if (i == 0) {
9665 scsi_sg_q.sg_list_cnt =
9666 ASC_SG_LIST_PER_Q;
9667 scsi_sg_q.sg_cur_list_cnt =
9668 ASC_SG_LIST_PER_Q;
9669 } else {
9670 scsi_sg_q.sg_list_cnt =
9671 ASC_SG_LIST_PER_Q - 1;
9672 scsi_sg_q.sg_cur_list_cnt =
9673 ASC_SG_LIST_PER_Q - 1;
9674 }
9675 } else {
9676 #if CC_VERY_LONG_SG_LIST
9677 /*
9678 * This is the last SG queue in the list of
9679 * allocated SG queues. If there are more
9680 * SG elements than will fit in the allocated
9681 * queues, then set the QCSG_SG_XFER_MORE flag.
9682 */
9683 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9684 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
9685 } else {
9686 #endif /* CC_VERY_LONG_SG_LIST */
9687 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
9688 #if CC_VERY_LONG_SG_LIST
9689 }
9690 #endif /* CC_VERY_LONG_SG_LIST */
9691 sg_list_dwords = sg_entry_cnt << 1;
9692 if (i == 0) {
9693 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
9694 scsi_sg_q.sg_cur_list_cnt =
9695 sg_entry_cnt;
9696 } else {
9697 scsi_sg_q.sg_list_cnt =
9698 sg_entry_cnt - 1;
9699 scsi_sg_q.sg_cur_list_cnt =
9700 sg_entry_cnt - 1;
9701 }
9702 sg_entry_cnt = 0;
9703 }
9704 next_qp = AscReadLramByte(iop_base,
9705 (ushort)(q_addr +
9706 ASC_SCSIQ_B_FWD));
9707 scsi_sg_q.q_no = next_qp;
9708 q_addr = ASC_QNO_TO_QADDR(next_qp);
9709 AscMemWordCopyPtrToLram(iop_base,
9710 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
9711 (uchar *)&scsi_sg_q,
9712 sizeof(ASC_SG_LIST_Q) >> 1);
9713 AscMemDWordCopyPtrToLram(iop_base,
9714 q_addr + ASC_SGQ_LIST_BEG,
9715 (uchar *)&sg_head->
9716 sg_list[sg_index],
9717 sg_list_dwords);
9718 sg_index += ASC_SG_LIST_PER_Q;
9719 scsiq->next_sg_index = sg_index;
9720 }
9721 } else {
9722 scsiq->q1.cntl &= ~QC_SG_HEAD;
9723 }
9724 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
9725 scsiq->q1.data_addr = saved_data_addr;
9726 scsiq->q1.data_cnt = saved_data_cnt;
9727 return (sta);
9728 }
9729
9730 static int
9731 AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
9732 {
9733 int sta = FALSE;
9734
9735 if (AscHostReqRiscHalt(iop_base)) {
9736 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9737 AscStartChip(iop_base);
9738 return (sta);
9739 }
9740 return (sta);
9741 }
9742
9743 static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
9744 {
9745 ASC_SCSI_BIT_ID_TYPE org_id;
9746 int i;
9747 int sta = TRUE;
9748
9749 AscSetBank(iop_base, 1);
9750 org_id = AscReadChipDvcID(iop_base);
9751 for (i = 0; i <= ASC_MAX_TID; i++) {
9752 if (org_id == (0x01 << i))
9753 break;
9754 }
9755 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
9756 AscWriteChipDvcID(iop_base, id);
9757 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
9758 AscSetBank(iop_base, 0);
9759 AscSetChipSyn(iop_base, sdtr_data);
9760 if (AscGetChipSyn(iop_base) != sdtr_data) {
9761 sta = FALSE;
9762 }
9763 } else {
9764 sta = FALSE;
9765 }
9766 AscSetBank(iop_base, 1);
9767 AscWriteChipDvcID(iop_base, org_id);
9768 AscSetBank(iop_base, 0);
9769 return (sta);
9770 }
9771
9772 static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
9773 {
9774 uchar i;
9775 ushort s_addr;
9776 PortAddr iop_base;
9777 ushort warn_code;
9778
9779 iop_base = asc_dvc->iop_base;
9780 warn_code = 0;
9781 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
9782 (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
9783 64) >> 1)
9784 );
9785 i = ASC_MIN_ACTIVE_QNO;
9786 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
9787 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9788 (uchar)(i + 1));
9789 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9790 (uchar)(asc_dvc->max_total_qng));
9791 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9792 (uchar)i);
9793 i++;
9794 s_addr += ASC_QBLK_SIZE;
9795 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
9796 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9797 (uchar)(i + 1));
9798 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9799 (uchar)(i - 1));
9800 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9801 (uchar)i);
9802 }
9803 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9804 (uchar)ASC_QLINK_END);
9805 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9806 (uchar)(asc_dvc->max_total_qng - 1));
9807 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9808 (uchar)asc_dvc->max_total_qng);
9809 i++;
9810 s_addr += ASC_QBLK_SIZE;
9811 for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
9812 i++, s_addr += ASC_QBLK_SIZE) {
9813 AscWriteLramByte(iop_base,
9814 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
9815 AscWriteLramByte(iop_base,
9816 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
9817 AscWriteLramByte(iop_base,
9818 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
9819 }
9820 return (warn_code);
9821 }
9822
9823 static ushort AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
9824 {
9825 PortAddr iop_base;
9826 int i;
9827 ushort lram_addr;
9828
9829 iop_base = asc_dvc->iop_base;
9830 AscPutRiscVarFreeQHead(iop_base, 1);
9831 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
9832 AscPutVarFreeQHead(iop_base, 1);
9833 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
9834 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
9835 (uchar)((int)asc_dvc->max_total_qng + 1));
9836 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
9837 (uchar)((int)asc_dvc->max_total_qng + 2));
9838 AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
9839 asc_dvc->max_total_qng);
9840 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
9841 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9842 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
9843 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
9844 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
9845 AscPutQDoneInProgress(iop_base, 0);
9846 lram_addr = ASC_QADR_BEG;
9847 for (i = 0; i < 32; i++, lram_addr += 2) {
9848 AscWriteLramWord(iop_base, lram_addr, 0);
9849 }
9850 return (0);
9851 }
9852
9853 static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
9854 {
9855 if (asc_dvc->err_code == 0) {
9856 asc_dvc->err_code = err_code;
9857 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
9858 err_code);
9859 }
9860 return (err_code);
9861 }
9862
9863 static uchar
9864 AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
9865 {
9866 EXT_MSG sdtr_buf;
9867 uchar sdtr_period_index;
9868 PortAddr iop_base;
9869
9870 iop_base = asc_dvc->iop_base;
9871 sdtr_buf.msg_type = EXTENDED_MESSAGE;
9872 sdtr_buf.msg_len = MS_SDTR_LEN;
9873 sdtr_buf.msg_req = EXTENDED_SDTR;
9874 sdtr_buf.xfer_period = sdtr_period;
9875 sdtr_offset &= ASC_SYN_MAX_OFFSET;
9876 sdtr_buf.req_ack_offset = sdtr_offset;
9877 if ((sdtr_period_index =
9878 AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
9879 asc_dvc->max_sdtr_index) {
9880 AscMemWordCopyPtrToLram(iop_base,
9881 ASCV_MSGOUT_BEG,
9882 (uchar *)&sdtr_buf,
9883 sizeof(EXT_MSG) >> 1);
9884 return ((sdtr_period_index << 4) | sdtr_offset);
9885 } else {
9886
9887 sdtr_buf.req_ack_offset = 0;
9888 AscMemWordCopyPtrToLram(iop_base,
9889 ASCV_MSGOUT_BEG,
9890 (uchar *)&sdtr_buf,
9891 sizeof(EXT_MSG) >> 1);
9892 return (0);
9893 }
9894 }
9895
9896 static uchar
9897 AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
9898 {
9899 uchar byte;
9900 uchar sdtr_period_ix;
9901
9902 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
9903 if ((sdtr_period_ix > asc_dvc->max_sdtr_index)
9904 ) {
9905 return (0xFF);
9906 }
9907 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
9908 return (byte);
9909 }
9910
9911 static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
9912 {
9913 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9914 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
9915 return;
9916 }
9917
9918 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
9919 {
9920 uchar *period_table;
9921 int max_index;
9922 int min_index;
9923 int i;
9924
9925 period_table = asc_dvc->sdtr_period_tbl;
9926 max_index = (int)asc_dvc->max_sdtr_index;
9927 min_index = (int)asc_dvc->host_init_sdtr_index;
9928 if ((syn_time <= period_table[max_index])) {
9929 for (i = min_index; i < (max_index - 1); i++) {
9930 if (syn_time <= period_table[i]) {
9931 return ((uchar)i);
9932 }
9933 }
9934 return ((uchar)max_index);
9935 } else {
9936 return ((uchar)(max_index + 1));
9937 }
9938 }
9939
9940 static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
9941 {
9942 ushort q_addr;
9943 uchar next_qp;
9944 uchar q_status;
9945
9946 q_addr = ASC_QNO_TO_QADDR(free_q_head);
9947 q_status = (uchar)AscReadLramByte(iop_base,
9948 (ushort)(q_addr +
9949 ASC_SCSIQ_B_STATUS));
9950 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
9951 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
9952 return (next_qp);
9953 }
9954 return (ASC_QLINK_END);
9955 }
9956
9957 static uchar
9958 AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
9959 {
9960 uchar i;
9961
9962 for (i = 0; i < n_free_q; i++) {
9963 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
9964 == ASC_QLINK_END) {
9965 return (ASC_QLINK_END);
9966 }
9967 }
9968 return (free_q_head);
9969 }
9970
9971 static int AscHostReqRiscHalt(PortAddr iop_base)
9972 {
9973 int count = 0;
9974 int sta = 0;
9975 uchar saved_stop_code;
9976
9977 if (AscIsChipHalted(iop_base))
9978 return (1);
9979 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
9980 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
9981 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
9982 do {
9983 if (AscIsChipHalted(iop_base)) {
9984 sta = 1;
9985 break;
9986 }
9987 DvcSleepMilliSecond(100);
9988 } while (count++ < 20);
9989 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
9990 return (sta);
9991 }
9992
9993 static int AscStopQueueExe(PortAddr iop_base)
9994 {
9995 int count = 0;
9996
9997 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
9998 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
9999 ASC_STOP_REQ_RISC_STOP);
10000 do {
10001 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
10002 ASC_STOP_ACK_RISC_STOP) {
10003 return (1);
10004 }
10005 DvcSleepMilliSecond(100);
10006 } while (count++ < 20);
10007 }
10008 return (0);
10009 }
10010
10011 static void DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
10012 {
10013 udelay(micro_sec);
10014 }
10015
10016 static void DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
10017 {
10018 udelay((nano_sec + 999) / 1000);
10019 }
10020
10021 static int AscStartChip(PortAddr iop_base)
10022 {
10023 AscSetChipControl(iop_base, 0);
10024 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
10025 return (0);
10026 }
10027 return (1);
10028 }
10029
10030 static int AscStopChip(PortAddr iop_base)
10031 {
10032 uchar cc_val;
10033
10034 cc_val =
10035 AscGetChipControl(iop_base) &
10036 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
10037 AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
10038 AscSetChipIH(iop_base, INS_HALT);
10039 AscSetChipIH(iop_base, INS_RFLAG_WTM);
10040 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
10041 return (0);
10042 }
10043 return (1);
10044 }
10045
10046 static int AscIsChipHalted(PortAddr iop_base)
10047 {
10048 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
10049 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
10050 return (1);
10051 }
10052 }
10053 return (0);
10054 }
10055
10056 static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
10057 {
10058 AscSetBank(iop_base, 1);
10059 AscWriteChipIH(iop_base, ins_code);
10060 AscSetBank(iop_base, 0);
10061 return;
10062 }
10063
10064 static void AscAckInterrupt(PortAddr iop_base)
10065 {
10066 uchar host_flag;
10067 uchar risc_flag;
10068 ushort loop;
10069
10070 loop = 0;
10071 do {
10072 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
10073 if (loop++ > 0x7FFF) {
10074 break;
10075 }
10076 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
10077 host_flag =
10078 AscReadLramByte(iop_base,
10079 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
10080 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10081 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
10082 AscSetChipStatus(iop_base, CIW_INT_ACK);
10083 loop = 0;
10084 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
10085 AscSetChipStatus(iop_base, CIW_INT_ACK);
10086 if (loop++ > 3) {
10087 break;
10088 }
10089 }
10090 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10091 return;
10092 }
10093
10094 static void AscDisableInterrupt(PortAddr iop_base)
10095 {
10096 ushort cfg;
10097
10098 cfg = AscGetChipCfgLsw(iop_base);
10099 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
10100 return;
10101 }
10102
10103 static void AscEnableInterrupt(PortAddr iop_base)
10104 {
10105 ushort cfg;
10106
10107 cfg = AscGetChipCfgLsw(iop_base);
10108 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
10109 return;
10110 }
10111
10112 static void AscSetBank(PortAddr iop_base, uchar bank)
10113 {
10114 uchar val;
10115
10116 val = AscGetChipControl(iop_base) &
10117 (~
10118 (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
10119 CC_CHIP_RESET));
10120 if (bank == 1) {
10121 val |= CC_BANK_ONE;
10122 } else if (bank == 2) {
10123 val |= CC_DIAG | CC_BANK_ONE;
10124 } else {
10125 val &= ~CC_BANK_ONE;
10126 }
10127 AscSetChipControl(iop_base, val);
10128 return;
10129 }
10130
10131 static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
10132 {
10133 PortAddr iop_base;
10134 int i = 10;
10135
10136 iop_base = asc_dvc->iop_base;
10137 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
10138 && (i-- > 0)) {
10139 DvcSleepMilliSecond(100);
10140 }
10141 AscStopChip(iop_base);
10142 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
10143 DvcDelayNanoSecond(asc_dvc, 60000);
10144 AscSetChipIH(iop_base, INS_RFLAG_WTM);
10145 AscSetChipIH(iop_base, INS_HALT);
10146 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
10147 AscSetChipControl(iop_base, CC_HALT);
10148 DvcSleepMilliSecond(200);
10149 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10150 AscSetChipStatus(iop_base, 0);
10151 return (AscIsChipHalted(iop_base));
10152 }
10153
10154 static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
10155 {
10156 if (bus_type & ASC_IS_ISA)
10157 return (ASC_MAX_ISA_DMA_COUNT);
10158 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
10159 return (ASC_MAX_VL_DMA_COUNT);
10160 return (ASC_MAX_PCI_DMA_COUNT);
10161 }
10162
10163 #ifdef CONFIG_ISA
10164 static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
10165 {
10166 ushort channel;
10167
10168 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
10169 if (channel == 0x03)
10170 return (0);
10171 else if (channel == 0x00)
10172 return (7);
10173 return (channel + 4);
10174 }
10175
10176 static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
10177 {
10178 ushort cfg_lsw;
10179 uchar value;
10180
10181 if ((dma_channel >= 5) && (dma_channel <= 7)) {
10182 if (dma_channel == 7)
10183 value = 0x00;
10184 else
10185 value = dma_channel - 4;
10186 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
10187 cfg_lsw |= value;
10188 AscSetChipCfgLsw(iop_base, cfg_lsw);
10189 return (AscGetIsaDmaChannel(iop_base));
10190 }
10191 return (0);
10192 }
10193
10194 static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
10195 {
10196 speed_value &= 0x07;
10197 AscSetBank(iop_base, 1);
10198 AscWriteChipDmaSpeed(iop_base, speed_value);
10199 AscSetBank(iop_base, 0);
10200 return (AscGetIsaDmaSpeed(iop_base));
10201 }
10202
10203 static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
10204 {
10205 uchar speed_value;
10206
10207 AscSetBank(iop_base, 1);
10208 speed_value = AscReadChipDmaSpeed(iop_base);
10209 speed_value &= 0x07;
10210 AscSetBank(iop_base, 0);
10211 return (speed_value);
10212 }
10213 #endif /* CONFIG_ISA */
10214
10215 static ushort __devinit AscInitGetConfig(ASC_DVC_VAR *asc_dvc)
10216 {
10217 unsigned short warn_code = 0;
10218
10219 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
10220 if (asc_dvc->err_code != 0)
10221 return (UW_ERR);
10222
10223 if (AscFindSignature(asc_dvc->iop_base)) {
10224 warn_code |= AscInitAscDvcVar(asc_dvc);
10225 warn_code |= AscInitFromEEP(asc_dvc);
10226 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
10227 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
10228 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
10229 } else {
10230 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10231 }
10232 return warn_code;
10233 }
10234
10235 static ushort __devinit AscInitSetConfig(ASC_DVC_VAR *asc_dvc)
10236 {
10237 ushort warn_code = 0;
10238
10239 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
10240 if (asc_dvc->err_code != 0)
10241 return (UW_ERR);
10242 if (AscFindSignature(asc_dvc->iop_base)) {
10243 warn_code |= AscInitFromAscDvcVar(asc_dvc);
10244 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
10245 } else {
10246 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10247 }
10248 return (warn_code);
10249 }
10250
10251 static ushort __devinit AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc)
10252 {
10253 PortAddr iop_base;
10254 ushort cfg_msw;
10255 ushort warn_code;
10256
10257 iop_base = asc_dvc->iop_base;
10258 warn_code = 0;
10259 cfg_msw = AscGetChipCfgMsw(iop_base);
10260 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10261 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10262 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10263 AscSetChipCfgMsw(iop_base, cfg_msw);
10264 }
10265 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
10266 asc_dvc->cfg->cmd_qng_enabled) {
10267 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
10268 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10269 }
10270 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10271 warn_code |= ASC_WARN_AUTO_CONFIG;
10272 }
10273 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
10274 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
10275 != asc_dvc->irq_no) {
10276 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
10277 }
10278 }
10279 #ifdef CONFIG_PCI
10280 if (asc_dvc->bus_type & ASC_IS_PCI) {
10281 struct pci_dev *pdev = to_pci_dev(asc_dvc->cfg->dev);
10282 cfg_msw &= 0xFFC0;
10283 AscSetChipCfgMsw(iop_base, cfg_msw);
10284 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
10285 } else {
10286 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
10287 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
10288 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
10289 asc_dvc->bug_fix_cntl |=
10290 ASC_BUG_FIX_ASYN_USE_SYN;
10291 }
10292 }
10293 } else
10294 #endif /* CONFIG_PCI */
10295 if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
10296 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
10297 == ASC_CHIP_VER_ASYN_BUG) {
10298 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
10299 }
10300 }
10301 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
10302 asc_dvc->cfg->chip_scsi_id) {
10303 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
10304 }
10305 #ifdef CONFIG_ISA
10306 if (asc_dvc->bus_type & ASC_IS_ISA) {
10307 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
10308 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
10309 }
10310 #endif /* CONFIG_ISA */
10311 return (warn_code);
10312 }
10313
10314 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
10315 {
10316 ushort warn_code;
10317 PortAddr iop_base;
10318
10319 iop_base = asc_dvc->iop_base;
10320 warn_code = 0;
10321 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
10322 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
10323 AscResetChipAndScsiBus(asc_dvc);
10324 DvcSleepMilliSecond((ASC_DCNT)
10325 ((ushort)asc_dvc->scsi_reset_wait * 1000));
10326 }
10327 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
10328 if (asc_dvc->err_code != 0)
10329 return (UW_ERR);
10330 if (!AscFindSignature(asc_dvc->iop_base)) {
10331 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10332 return (warn_code);
10333 }
10334 AscDisableInterrupt(iop_base);
10335 warn_code |= AscInitLram(asc_dvc);
10336 if (asc_dvc->err_code != 0)
10337 return (UW_ERR);
10338 ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
10339 (ulong)_asc_mcode_chksum);
10340 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
10341 _asc_mcode_size) != _asc_mcode_chksum) {
10342 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
10343 return (warn_code);
10344 }
10345 warn_code |= AscInitMicroCodeVar(asc_dvc);
10346 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
10347 AscEnableInterrupt(iop_base);
10348 return (warn_code);
10349 }
10350
10351 static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
10352 {
10353 int i;
10354 PortAddr iop_base;
10355 ushort warn_code;
10356 uchar chip_version;
10357
10358 iop_base = asc_dvc->iop_base;
10359 warn_code = 0;
10360 asc_dvc->err_code = 0;
10361 if ((asc_dvc->bus_type &
10362 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
10363 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
10364 }
10365 AscSetChipControl(iop_base, CC_HALT);
10366 AscSetChipStatus(iop_base, 0);
10367 asc_dvc->bug_fix_cntl = 0;
10368 asc_dvc->pci_fix_asyn_xfer = 0;
10369 asc_dvc->pci_fix_asyn_xfer_always = 0;
10370 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
10371 asc_dvc->sdtr_done = 0;
10372 asc_dvc->cur_total_qng = 0;
10373 asc_dvc->is_in_int = 0;
10374 asc_dvc->in_critical_cnt = 0;
10375 asc_dvc->last_q_shortage = 0;
10376 asc_dvc->use_tagged_qng = 0;
10377 asc_dvc->no_scam = 0;
10378 asc_dvc->unit_not_ready = 0;
10379 asc_dvc->queue_full_or_busy = 0;
10380 asc_dvc->redo_scam = 0;
10381 asc_dvc->res2 = 0;
10382 asc_dvc->host_init_sdtr_index = 0;
10383 asc_dvc->cfg->can_tagged_qng = 0;
10384 asc_dvc->cfg->cmd_qng_enabled = 0;
10385 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
10386 asc_dvc->init_sdtr = 0;
10387 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
10388 asc_dvc->scsi_reset_wait = 3;
10389 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
10390 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
10391 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
10392 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
10393 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
10394 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
10395 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
10396 ASC_LIB_VERSION_MINOR;
10397 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
10398 asc_dvc->cfg->chip_version = chip_version;
10399 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
10400 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
10401 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
10402 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
10403 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
10404 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
10405 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
10406 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
10407 asc_dvc->max_sdtr_index = 7;
10408 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
10409 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
10410 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
10411 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
10412 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
10413 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
10414 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
10415 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
10416 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
10417 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
10418 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
10419 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
10420 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
10421 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
10422 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
10423 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
10424 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
10425 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
10426 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
10427 asc_dvc->max_sdtr_index = 15;
10428 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
10429 AscSetExtraControl(iop_base,
10430 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10431 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
10432 AscSetExtraControl(iop_base,
10433 (SEC_ACTIVE_NEGATE |
10434 SEC_ENABLE_FILTER));
10435 }
10436 }
10437 if (asc_dvc->bus_type == ASC_IS_PCI) {
10438 AscSetExtraControl(iop_base,
10439 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10440 }
10441
10442 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
10443 #ifdef CONFIG_ISA
10444 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
10445 if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) {
10446 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
10447 asc_dvc->bus_type = ASC_IS_ISAPNP;
10448 }
10449 asc_dvc->cfg->isa_dma_channel =
10450 (uchar)AscGetIsaDmaChannel(iop_base);
10451 }
10452 #endif /* CONFIG_ISA */
10453 for (i = 0; i <= ASC_MAX_TID; i++) {
10454 asc_dvc->cur_dvc_qng[i] = 0;
10455 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
10456 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
10457 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
10458 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
10459 }
10460 return (warn_code);
10461 }
10462
10463 static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
10464 {
10465 ASCEEP_CONFIG eep_config_buf;
10466 ASCEEP_CONFIG *eep_config;
10467 PortAddr iop_base;
10468 ushort chksum;
10469 ushort warn_code;
10470 ushort cfg_msw, cfg_lsw;
10471 int i;
10472 int write_eep = 0;
10473
10474 iop_base = asc_dvc->iop_base;
10475 warn_code = 0;
10476 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
10477 AscStopQueueExe(iop_base);
10478 if ((AscStopChip(iop_base) == FALSE) ||
10479 (AscGetChipScsiCtrl(iop_base) != 0)) {
10480 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
10481 AscResetChipAndScsiBus(asc_dvc);
10482 DvcSleepMilliSecond((ASC_DCNT)
10483 ((ushort)asc_dvc->scsi_reset_wait * 1000));
10484 }
10485 if (AscIsChipHalted(iop_base) == FALSE) {
10486 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10487 return (warn_code);
10488 }
10489 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10490 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10491 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10492 return (warn_code);
10493 }
10494 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
10495 cfg_msw = AscGetChipCfgMsw(iop_base);
10496 cfg_lsw = AscGetChipCfgLsw(iop_base);
10497 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10498 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10499 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10500 AscSetChipCfgMsw(iop_base, cfg_msw);
10501 }
10502 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
10503 ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
10504 if (chksum == 0) {
10505 chksum = 0xaa55;
10506 }
10507 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10508 warn_code |= ASC_WARN_AUTO_CONFIG;
10509 if (asc_dvc->cfg->chip_version == 3) {
10510 if (eep_config->cfg_lsw != cfg_lsw) {
10511 warn_code |= ASC_WARN_EEPROM_RECOVER;
10512 eep_config->cfg_lsw =
10513 AscGetChipCfgLsw(iop_base);
10514 }
10515 if (eep_config->cfg_msw != cfg_msw) {
10516 warn_code |= ASC_WARN_EEPROM_RECOVER;
10517 eep_config->cfg_msw =
10518 AscGetChipCfgMsw(iop_base);
10519 }
10520 }
10521 }
10522 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
10523 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
10524 ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
10525 eep_config->chksum);
10526 if (chksum != eep_config->chksum) {
10527 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
10528 ASC_CHIP_VER_PCI_ULTRA_3050) {
10529 ASC_DBG(1,
10530 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
10531 eep_config->init_sdtr = 0xFF;
10532 eep_config->disc_enable = 0xFF;
10533 eep_config->start_motor = 0xFF;
10534 eep_config->use_cmd_qng = 0;
10535 eep_config->max_total_qng = 0xF0;
10536 eep_config->max_tag_qng = 0x20;
10537 eep_config->cntl = 0xBFFF;
10538 ASC_EEP_SET_CHIP_ID(eep_config, 7);
10539 eep_config->no_scam = 0;
10540 eep_config->adapter_info[0] = 0;
10541 eep_config->adapter_info[1] = 0;
10542 eep_config->adapter_info[2] = 0;
10543 eep_config->adapter_info[3] = 0;
10544 eep_config->adapter_info[4] = 0;
10545 /* Indicate EEPROM-less board. */
10546 eep_config->adapter_info[5] = 0xBB;
10547 } else {
10548 ASC_PRINT
10549 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
10550 write_eep = 1;
10551 warn_code |= ASC_WARN_EEPROM_CHKSUM;
10552 }
10553 }
10554 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
10555 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
10556 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
10557 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
10558 asc_dvc->start_motor = eep_config->start_motor;
10559 asc_dvc->dvc_cntl = eep_config->cntl;
10560 asc_dvc->no_scam = eep_config->no_scam;
10561 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
10562 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
10563 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
10564 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
10565 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
10566 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
10567 if (!AscTestExternalLram(asc_dvc)) {
10568 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
10569 ASC_IS_PCI_ULTRA)) {
10570 eep_config->max_total_qng =
10571 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
10572 eep_config->max_tag_qng =
10573 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
10574 } else {
10575 eep_config->cfg_msw |= 0x0800;
10576 cfg_msw |= 0x0800;
10577 AscSetChipCfgMsw(iop_base, cfg_msw);
10578 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
10579 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
10580 }
10581 } else {
10582 }
10583 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
10584 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
10585 }
10586 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
10587 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
10588 }
10589 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
10590 eep_config->max_tag_qng = eep_config->max_total_qng;
10591 }
10592 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
10593 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
10594 }
10595 asc_dvc->max_total_qng = eep_config->max_total_qng;
10596 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
10597 eep_config->use_cmd_qng) {
10598 eep_config->disc_enable = eep_config->use_cmd_qng;
10599 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10600 }
10601 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
10602 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
10603 }
10604 ASC_EEP_SET_CHIP_ID(eep_config,
10605 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
10606 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
10607 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
10608 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
10609 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
10610 }
10611
10612 for (i = 0; i <= ASC_MAX_TID; i++) {
10613 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
10614 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
10615 asc_dvc->cfg->sdtr_period_offset[i] =
10616 (uchar)(ASC_DEF_SDTR_OFFSET |
10617 (asc_dvc->host_init_sdtr_index << 4));
10618 }
10619 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
10620 if (write_eep) {
10621 if ((i =
10622 AscSetEEPConfig(iop_base, eep_config,
10623 asc_dvc->bus_type)) != 0) {
10624 ASC_PRINT1
10625 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
10626 i);
10627 } else {
10628 ASC_PRINT
10629 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
10630 }
10631 }
10632 return (warn_code);
10633 }
10634
10635 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
10636 {
10637 int i;
10638 ushort warn_code;
10639 PortAddr iop_base;
10640 ASC_PADDR phy_addr;
10641 ASC_DCNT phy_size;
10642
10643 iop_base = asc_dvc->iop_base;
10644 warn_code = 0;
10645 for (i = 0; i <= ASC_MAX_TID; i++) {
10646 AscPutMCodeInitSDTRAtID(iop_base, i,
10647 asc_dvc->cfg->sdtr_period_offset[i]
10648 );
10649 }
10650
10651 AscInitQLinkVar(asc_dvc);
10652 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
10653 asc_dvc->cfg->disc_enable);
10654 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
10655 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
10656
10657 /* Align overrun buffer on an 8 byte boundary. */
10658 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
10659 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
10660 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
10661 (uchar *)&phy_addr, 1);
10662 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
10663 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
10664 (uchar *)&phy_size, 1);
10665
10666 asc_dvc->cfg->mcode_date =
10667 AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
10668 asc_dvc->cfg->mcode_version =
10669 AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
10670
10671 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10672 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10673 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10674 return (warn_code);
10675 }
10676 if (AscStartChip(iop_base) != 1) {
10677 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10678 return (warn_code);
10679 }
10680
10681 return (warn_code);
10682 }
10683
10684 static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
10685 {
10686 PortAddr iop_base;
10687 ushort q_addr;
10688 ushort saved_word;
10689 int sta;
10690
10691 iop_base = asc_dvc->iop_base;
10692 sta = 0;
10693 q_addr = ASC_QNO_TO_QADDR(241);
10694 saved_word = AscReadLramWord(iop_base, q_addr);
10695 AscSetChipLramAddr(iop_base, q_addr);
10696 AscSetChipLramData(iop_base, 0x55AA);
10697 DvcSleepMilliSecond(10);
10698 AscSetChipLramAddr(iop_base, q_addr);
10699 if (AscGetChipLramData(iop_base) == 0x55AA) {
10700 sta = 1;
10701 AscWriteLramWord(iop_base, q_addr, saved_word);
10702 }
10703 return (sta);
10704 }
10705
10706 static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
10707 {
10708 uchar read_back;
10709 int retry;
10710
10711 retry = 0;
10712 while (TRUE) {
10713 AscSetChipEEPCmd(iop_base, cmd_reg);
10714 DvcSleepMilliSecond(1);
10715 read_back = AscGetChipEEPCmd(iop_base);
10716 if (read_back == cmd_reg) {
10717 return (1);
10718 }
10719 if (retry++ > ASC_EEP_MAX_RETRY) {
10720 return (0);
10721 }
10722 }
10723 }
10724
10725 static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
10726 {
10727 ushort read_back;
10728 int retry;
10729
10730 retry = 0;
10731 while (TRUE) {
10732 AscSetChipEEPData(iop_base, data_reg);
10733 DvcSleepMilliSecond(1);
10734 read_back = AscGetChipEEPData(iop_base);
10735 if (read_back == data_reg) {
10736 return (1);
10737 }
10738 if (retry++ > ASC_EEP_MAX_RETRY) {
10739 return (0);
10740 }
10741 }
10742 }
10743
10744 static void __devinit AscWaitEEPRead(void)
10745 {
10746 DvcSleepMilliSecond(1);
10747 return;
10748 }
10749
10750 static void __devinit AscWaitEEPWrite(void)
10751 {
10752 DvcSleepMilliSecond(20);
10753 return;
10754 }
10755
10756 static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
10757 {
10758 ushort read_wval;
10759 uchar cmd_reg;
10760
10761 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
10762 AscWaitEEPRead();
10763 cmd_reg = addr | ASC_EEP_CMD_READ;
10764 AscWriteEEPCmdReg(iop_base, cmd_reg);
10765 AscWaitEEPRead();
10766 read_wval = AscGetChipEEPData(iop_base);
10767 AscWaitEEPRead();
10768 return (read_wval);
10769 }
10770
10771 static ushort __devinit
10772 AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
10773 {
10774 ushort read_wval;
10775
10776 read_wval = AscReadEEPWord(iop_base, addr);
10777 if (read_wval != word_val) {
10778 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
10779 AscWaitEEPRead();
10780 AscWriteEEPDataReg(iop_base, word_val);
10781 AscWaitEEPRead();
10782 AscWriteEEPCmdReg(iop_base,
10783 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
10784 AscWaitEEPWrite();
10785 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
10786 AscWaitEEPRead();
10787 return (AscReadEEPWord(iop_base, addr));
10788 }
10789 return (read_wval);
10790 }
10791
10792 static ushort __devinit
10793 AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
10794 {
10795 ushort wval;
10796 ushort sum;
10797 ushort *wbuf;
10798 int cfg_beg;
10799 int cfg_end;
10800 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
10801 int s_addr;
10802
10803 wbuf = (ushort *)cfg_buf;
10804 sum = 0;
10805 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
10806 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10807 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
10808 sum += *wbuf;
10809 }
10810 if (bus_type & ASC_IS_VL) {
10811 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10812 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10813 } else {
10814 cfg_beg = ASC_EEP_DVC_CFG_BEG;
10815 cfg_end = ASC_EEP_MAX_DVC_ADDR;
10816 }
10817 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
10818 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
10819 if (s_addr <= uchar_end_in_config) {
10820 /*
10821 * Swap all char fields - must unswap bytes already swapped
10822 * by AscReadEEPWord().
10823 */
10824 *wbuf = le16_to_cpu(wval);
10825 } else {
10826 /* Don't swap word field at the end - cntl field. */
10827 *wbuf = wval;
10828 }
10829 sum += wval; /* Checksum treats all EEPROM data as words. */
10830 }
10831 /*
10832 * Read the checksum word which will be compared against 'sum'
10833 * by the caller. Word field already swapped.
10834 */
10835 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
10836 return (sum);
10837 }
10838
10839 static int __devinit
10840 AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
10841 {
10842 int n_error;
10843 ushort *wbuf;
10844 ushort word;
10845 ushort sum;
10846 int s_addr;
10847 int cfg_beg;
10848 int cfg_end;
10849 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
10850
10851 wbuf = (ushort *)cfg_buf;
10852 n_error = 0;
10853 sum = 0;
10854 /* Write two config words; AscWriteEEPWord() will swap bytes. */
10855 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10856 sum += *wbuf;
10857 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
10858 n_error++;
10859 }
10860 }
10861 if (bus_type & ASC_IS_VL) {
10862 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10863 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10864 } else {
10865 cfg_beg = ASC_EEP_DVC_CFG_BEG;
10866 cfg_end = ASC_EEP_MAX_DVC_ADDR;
10867 }
10868 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
10869 if (s_addr <= uchar_end_in_config) {
10870 /*
10871 * This is a char field. Swap char fields before they are
10872 * swapped again by AscWriteEEPWord().
10873 */
10874 word = cpu_to_le16(*wbuf);
10875 if (word !=
10876 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
10877 n_error++;
10878 }
10879 } else {
10880 /* Don't swap word field at the end - cntl field. */
10881 if (*wbuf !=
10882 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
10883 n_error++;
10884 }
10885 }
10886 sum += *wbuf; /* Checksum calculated from word values. */
10887 }
10888 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
10889 *wbuf = sum;
10890 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
10891 n_error++;
10892 }
10893
10894 /* Read EEPROM back again. */
10895 wbuf = (ushort *)cfg_buf;
10896 /*
10897 * Read two config words; Byte-swapping done by AscReadEEPWord().
10898 */
10899 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10900 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
10901 n_error++;
10902 }
10903 }
10904 if (bus_type & ASC_IS_VL) {
10905 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10906 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10907 } else {
10908 cfg_beg = ASC_EEP_DVC_CFG_BEG;
10909 cfg_end = ASC_EEP_MAX_DVC_ADDR;
10910 }
10911 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
10912 if (s_addr <= uchar_end_in_config) {
10913 /*
10914 * Swap all char fields. Must unswap bytes already swapped
10915 * by AscReadEEPWord().
10916 */
10917 word =
10918 le16_to_cpu(AscReadEEPWord
10919 (iop_base, (uchar)s_addr));
10920 } else {
10921 /* Don't swap word field at the end - cntl field. */
10922 word = AscReadEEPWord(iop_base, (uchar)s_addr);
10923 }
10924 if (*wbuf != word) {
10925 n_error++;
10926 }
10927 }
10928 /* Read checksum; Byte swapping not needed. */
10929 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
10930 n_error++;
10931 }
10932 return (n_error);
10933 }
10934
10935 static int __devinit
10936 AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
10937 {
10938 int retry;
10939 int n_error;
10940
10941 retry = 0;
10942 while (TRUE) {
10943 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
10944 bus_type)) == 0) {
10945 break;
10946 }
10947 if (++retry > ASC_EEP_MAX_RETRY) {
10948 break;
10949 }
10950 }
10951 return (n_error);
10952 }
10953
10954 static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
10955 {
10956 char type = sdev->type;
10957 ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
10958
10959 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
10960 if (!(asc_dvc->init_sdtr & tid_bits)) {
10961 if ((type == TYPE_ROM) &&
10962 (strncmp(sdev->vendor, "HP ", 3) == 0)) {
10963 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
10964 }
10965 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
10966 if ((type == TYPE_PROCESSOR) ||
10967 (type == TYPE_SCANNER) || (type == TYPE_ROM) ||
10968 (type == TYPE_TAPE)) {
10969 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
10970 }
10971
10972 if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
10973 AscSetRunChipSynRegAtID(asc_dvc->iop_base,
10974 sdev->id,
10975 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
10976 }
10977 }
10978 }
10979 }
10980
10981 static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
10982 {
10983 uchar byte_data;
10984 ushort word_data;
10985
10986 if (isodd_word(addr)) {
10987 AscSetChipLramAddr(iop_base, addr - 1);
10988 word_data = AscGetChipLramData(iop_base);
10989 byte_data = (uchar)((word_data >> 8) & 0xFF);
10990 } else {
10991 AscSetChipLramAddr(iop_base, addr);
10992 word_data = AscGetChipLramData(iop_base);
10993 byte_data = (uchar)(word_data & 0xFF);
10994 }
10995 return (byte_data);
10996 }
10997
10998 static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
10999 {
11000 ushort word_data;
11001
11002 AscSetChipLramAddr(iop_base, addr);
11003 word_data = AscGetChipLramData(iop_base);
11004 return (word_data);
11005 }
11006
11007 #if CC_VERY_LONG_SG_LIST
11008 static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
11009 {
11010 ushort val_low, val_high;
11011 ASC_DCNT dword_data;
11012
11013 AscSetChipLramAddr(iop_base, addr);
11014 val_low = AscGetChipLramData(iop_base);
11015 val_high = AscGetChipLramData(iop_base);
11016 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
11017 return (dword_data);
11018 }
11019 #endif /* CC_VERY_LONG_SG_LIST */
11020
11021 static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
11022 {
11023 AscSetChipLramAddr(iop_base, addr);
11024 AscSetChipLramData(iop_base, word_val);
11025 return;
11026 }
11027
11028 static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
11029 {
11030 ushort word_data;
11031
11032 if (isodd_word(addr)) {
11033 addr--;
11034 word_data = AscReadLramWord(iop_base, addr);
11035 word_data &= 0x00FF;
11036 word_data |= (((ushort)byte_val << 8) & 0xFF00);
11037 } else {
11038 word_data = AscReadLramWord(iop_base, addr);
11039 word_data &= 0xFF00;
11040 word_data |= ((ushort)byte_val & 0x00FF);
11041 }
11042 AscWriteLramWord(iop_base, addr, word_data);
11043 return;
11044 }
11045
11046 /*
11047 * Copy 2 bytes to LRAM.
11048 *
11049 * The source data is assumed to be in little-endian order in memory
11050 * and is maintained in little-endian order when written to LRAM.
11051 */
11052 static void
11053 AscMemWordCopyPtrToLram(PortAddr iop_base,
11054 ushort s_addr, uchar *s_buffer, int words)
11055 {
11056 int i;
11057
11058 AscSetChipLramAddr(iop_base, s_addr);
11059 for (i = 0; i < 2 * words; i += 2) {
11060 /*
11061 * On a little-endian system the second argument below
11062 * produces a little-endian ushort which is written to
11063 * LRAM in little-endian order. On a big-endian system
11064 * the second argument produces a big-endian ushort which
11065 * is "transparently" byte-swapped by outpw() and written
11066 * in little-endian order to LRAM.
11067 */
11068 outpw(iop_base + IOP_RAM_DATA,
11069 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
11070 }
11071 return;
11072 }
11073
11074 /*
11075 * Copy 4 bytes to LRAM.
11076 *
11077 * The source data is assumed to be in little-endian order in memory
11078 * and is maintained in little-endian order when writen to LRAM.
11079 */
11080 static void
11081 AscMemDWordCopyPtrToLram(PortAddr iop_base,
11082 ushort s_addr, uchar *s_buffer, int dwords)
11083 {
11084 int i;
11085
11086 AscSetChipLramAddr(iop_base, s_addr);
11087 for (i = 0; i < 4 * dwords; i += 4) {
11088 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
11089 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
11090 }
11091 return;
11092 }
11093
11094 /*
11095 * Copy 2 bytes from LRAM.
11096 *
11097 * The source data is assumed to be in little-endian order in LRAM
11098 * and is maintained in little-endian order when written to memory.
11099 */
11100 static void
11101 AscMemWordCopyPtrFromLram(PortAddr iop_base,
11102 ushort s_addr, uchar *d_buffer, int words)
11103 {
11104 int i;
11105 ushort word;
11106
11107 AscSetChipLramAddr(iop_base, s_addr);
11108 for (i = 0; i < 2 * words; i += 2) {
11109 word = inpw(iop_base + IOP_RAM_DATA);
11110 d_buffer[i] = word & 0xff;
11111 d_buffer[i + 1] = (word >> 8) & 0xff;
11112 }
11113 return;
11114 }
11115
11116 static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
11117 {
11118 ASC_DCNT sum;
11119 int i;
11120
11121 sum = 0L;
11122 for (i = 0; i < words; i++, s_addr += 2) {
11123 sum += AscReadLramWord(iop_base, s_addr);
11124 }
11125 return (sum);
11126 }
11127
11128 static void
11129 AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
11130 {
11131 int i;
11132
11133 AscSetChipLramAddr(iop_base, s_addr);
11134 for (i = 0; i < words; i++) {
11135 AscSetChipLramData(iop_base, set_wval);
11136 }
11137 return;
11138 }
11139
11140 /*
11141 * --- Adv Library Functions
11142 */
11143
11144 /* a_mcode.h */
11145
11146 /* Microcode buffer is kept after initialization for error recovery. */
11147 static unsigned char _adv_asc3550_buf[] = {
11148 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
11149 0x01, 0x00, 0x48, 0xe4,
11150 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff,
11151 0x28, 0x0e, 0x9e, 0xe7,
11152 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7,
11153 0x55, 0xf0, 0x01, 0xf6,
11154 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
11155 0x00, 0xec, 0x85, 0xf0,
11156 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0,
11157 0x86, 0xf0, 0xb4, 0x00,
11158 0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00,
11159 0xaa, 0x18, 0x02, 0x80,
11160 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
11161 0x00, 0x57, 0x01, 0xea,
11162 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80,
11163 0x03, 0xe6, 0xb6, 0x00,
11164 0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12,
11165 0x02, 0x4a, 0xb9, 0x54,
11166 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
11167 0x3e, 0x00, 0x80, 0x00,
11168 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
11169 0x74, 0x01, 0x76, 0x01,
11170 0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13,
11171 0x4c, 0x1c, 0xbb, 0x55,
11172 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
11173 0x03, 0xf7, 0x06, 0xf7,
11174 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08,
11175 0x30, 0x13, 0x64, 0x15,
11176 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c,
11177 0x04, 0xea, 0x5d, 0xf0,
11178 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
11179 0xcc, 0x00, 0x20, 0x01,
11180 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13,
11181 0x40, 0x13, 0x30, 0x1c,
11182 0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
11183 0x59, 0xf0, 0xa7, 0xf0,
11184 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
11185 0xa4, 0x00, 0xb5, 0x00,
11186 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a,
11187 0x14, 0x0e, 0x02, 0x10,
11188 0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13,
11189 0x10, 0x15, 0x14, 0x15,
11190 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
11191 0x91, 0x44, 0x0a, 0x45,
11192 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58,
11193 0x83, 0x59, 0x05, 0xe6,
11194 0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8,
11195 0x02, 0xfa, 0x03, 0xfa,
11196 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
11197 0x9e, 0x00, 0xa8, 0x00,
11198 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01,
11199 0x7a, 0x01, 0xc0, 0x01,
11200 0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08,
11201 0x69, 0x08, 0xba, 0x08,
11202 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
11203 0xf1, 0x10, 0x06, 0x12,
11204 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14,
11205 0x8a, 0x15, 0xc6, 0x17,
11206 0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
11207 0x0e, 0x47, 0x48, 0x47,
11208 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
11209 0x14, 0x56, 0x77, 0x57,
11210 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c,
11211 0xf0, 0x29, 0x02, 0xfe,
11212 0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf,
11213 0xfe, 0x80, 0x01, 0xff,
11214 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
11215 0x00, 0xfe, 0x57, 0x24,
11216 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09,
11217 0x00, 0x00, 0xff, 0x08,
11218 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
11219 0xff, 0xff, 0xff, 0x0f,
11220 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
11221 0xfe, 0x04, 0xf7, 0xcf,
11222 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67,
11223 0x0b, 0x3c, 0x2a, 0xfe,
11224 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0,
11225 0xfe, 0xf0, 0x01, 0xfe,
11226 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
11227 0x02, 0xfe, 0xd4, 0x0c,
11228 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
11229 0x1c, 0x05, 0xfe, 0xa6,
11230 0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48,
11231 0xf0, 0xfe, 0x86, 0x02,
11232 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
11233 0xfe, 0x46, 0xf0, 0xfe,
11234 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
11235 0x44, 0x02, 0xfe, 0x44,
11236 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b,
11237 0xa0, 0x17, 0x06, 0x18,
11238 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
11239 0x1e, 0x1c, 0xfe, 0xe9,
11240 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7,
11241 0x0a, 0x6b, 0x01, 0x9e,
11242 0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b,
11243 0x01, 0x82, 0xfe, 0xbd,
11244 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
11245 0x58, 0x1c, 0x17, 0x06,
11246 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21,
11247 0xfe, 0x94, 0x02, 0xfe,
11248 0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97,
11249 0x01, 0xfe, 0x54, 0x0f,
11250 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
11251 0x69, 0x10, 0x17, 0x06,
11252 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05,
11253 0xf6, 0xc7, 0x01, 0xfe,
11254 0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6,
11255 0x02, 0x29, 0x0a, 0x40,
11256 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
11257 0x58, 0x0a, 0x99, 0x01,
11258 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29,
11259 0x2a, 0x46, 0xfe, 0x02,
11260 0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc,
11261 0x01, 0xfe, 0x07, 0x4b,
11262 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
11263 0xfe, 0x56, 0x03, 0xfe,
11264 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10,
11265 0xfe, 0x9f, 0xf0, 0xfe,
11266 0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48,
11267 0x1c, 0xeb, 0x09, 0x04,
11268 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
11269 0x01, 0x0e, 0xac, 0x75,
11270 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2,
11271 0xfe, 0x82, 0xf0, 0xfe,
11272 0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25,
11273 0x32, 0x1f, 0xfe, 0xb4,
11274 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
11275 0x0a, 0xf0, 0xfe, 0x7a,
11276 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c,
11277 0x01, 0x33, 0x8f, 0xfe,
11278 0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8,
11279 0xf7, 0xfe, 0x48, 0x1c,
11280 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
11281 0x0a, 0xca, 0x01, 0x0e,
11282 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14,
11283 0x2c, 0x01, 0x33, 0x8f,
11284 0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65,
11285 0xfe, 0x3c, 0x04, 0x1f,
11286 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
11287 0x12, 0x2b, 0xff, 0x02,
11288 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f,
11289 0x22, 0x30, 0x2e, 0xd5,
11290 0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c,
11291 0xfe, 0x4c, 0x54, 0x64,
11292 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
11293 0xfe, 0x2a, 0x13, 0x2f,
11294 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
11295 0xd3, 0xfa, 0xef, 0x86,
11296 0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04,
11297 0x1d, 0xfe, 0x1c, 0x12,
11298 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
11299 0x70, 0x0c, 0x02, 0x22,
11300 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92,
11301 0x01, 0x33, 0x02, 0x29,
11302 0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87,
11303 0x80, 0xfe, 0x31, 0xe4,
11304 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
11305 0xfe, 0x70, 0x12, 0x49,
11306 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe,
11307 0x80, 0x05, 0xfe, 0x31,
11308 0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00,
11309 0x28, 0xfe, 0x42, 0x12,
11310 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
11311 0x11, 0xfe, 0xe3, 0x00,
11312 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
11313 0x64, 0x05, 0x83, 0x24,
11314 0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe,
11315 0x09, 0x48, 0x01, 0x08,
11316 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
11317 0x86, 0x24, 0x06, 0x12,
11318 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47,
11319 0x01, 0xa7, 0x14, 0x92,
11320 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c,
11321 0x02, 0x22, 0x05, 0xfe,
11322 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
11323 0x47, 0x01, 0xa7, 0x26,
11324 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f,
11325 0x01, 0xfe, 0xaa, 0x14,
11326 0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00,
11327 0x05, 0x50, 0xb4, 0x0c,
11328 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
11329 0x13, 0x01, 0xfe, 0x14,
11330 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c,
11331 0xff, 0x02, 0x00, 0x57,
11332 0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe,
11333 0x72, 0x06, 0x49, 0x04,
11334 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
11335 0x06, 0x11, 0x9a, 0x01,
11336 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06,
11337 0x01, 0xa7, 0xec, 0x72,
11338 0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32,
11339 0xfe, 0x0a, 0xf0, 0xfe,
11340 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
11341 0x8d, 0x81, 0x02, 0x22,
11342 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00,
11343 0x01, 0x08, 0x15, 0x00,
11344 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15,
11345 0x00, 0x02, 0xfe, 0x32,
11346 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
11347 0xfe, 0x1b, 0x00, 0x01,
11348 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
11349 0x08, 0x15, 0x06, 0x01,
11350 0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe,
11351 0x9a, 0x81, 0x4b, 0x1d,
11352 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
11353 0x45, 0xfe, 0x32, 0x12,
11354 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0,
11355 0xfe, 0x32, 0x07, 0x8d,
11356 0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a,
11357 0x06, 0x15, 0x19, 0x02,
11358 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
11359 0x90, 0x77, 0xfe, 0xca,
11360 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07,
11361 0x10, 0xfe, 0x0e, 0x12,
11362 0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe,
11363 0x83, 0xe7, 0xc4, 0xa1,
11364 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
11365 0x40, 0x12, 0x58, 0x01,
11366 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6,
11367 0x51, 0x83, 0xfb, 0xfe,
11368 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90,
11369 0xfe, 0x40, 0x50, 0xfe,
11370 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
11371 0xfe, 0x2a, 0x12, 0xfe,
11372 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f,
11373 0x85, 0x01, 0xa8, 0xfe,
11374 0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56,
11375 0x18, 0x57, 0xfb, 0xfe,
11376 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
11377 0x0c, 0x39, 0x18, 0x3a,
11378 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e,
11379 0x11, 0x65, 0xfe, 0x48,
11380 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73,
11381 0xdd, 0xb8, 0xfe, 0x80,
11382 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
11383 0xfe, 0x7a, 0x08, 0x8d,
11384 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9,
11385 0x10, 0x61, 0x04, 0x06,
11386 0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68,
11387 0x12, 0xfe, 0x2e, 0x1c,
11388 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
11389 0x52, 0x12, 0xfe, 0x2c,
11390 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe,
11391 0x08, 0xfe, 0x8a, 0x10,
11392 0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe,
11393 0x24, 0x0a, 0xab, 0xfe,
11394 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
11395 0x1c, 0x12, 0xb5, 0xfe,
11396 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb,
11397 0x1c, 0x06, 0x16, 0x9d,
11398 0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b,
11399 0x14, 0x92, 0x01, 0x33,
11400 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
11401 0xfe, 0x74, 0x18, 0x1c,
11402 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b,
11403 0x01, 0xe6, 0x1e, 0x27,
11404 0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a,
11405 0x09, 0x04, 0x6a, 0xfe,
11406 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
11407 0xfe, 0x83, 0x80, 0xfe,
11408 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63,
11409 0x27, 0xfe, 0x40, 0x59,
11410 0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18,
11411 0x7c, 0xbe, 0x54, 0xbf,
11412 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
11413 0x79, 0x56, 0x68, 0x57,
11414 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5,
11415 0xa2, 0x23, 0x0c, 0x7b,
11416 0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19,
11417 0x16, 0xd7, 0x79, 0x39,
11418 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
11419 0xfe, 0x10, 0x58, 0xfe,
11420 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04,
11421 0x19, 0x16, 0xd7, 0x09,
11422 0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f,
11423 0xfe, 0x10, 0x90, 0xfe,
11424 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
11425 0x11, 0x9b, 0x09, 0x04,
11426 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08,
11427 0xfe, 0x0c, 0x58, 0xfe,
11428 0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04,
11429 0x0b, 0xfe, 0x1a, 0x12,
11430 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
11431 0x14, 0x7a, 0x01, 0x33,
11432 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39,
11433 0xfe, 0xed, 0x19, 0xbf,
11434 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff,
11435 0x34, 0xfe, 0x74, 0x10,
11436 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
11437 0x84, 0x05, 0xcb, 0x1c,
11438 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1,
11439 0xf0, 0xfe, 0xc4, 0x0a,
11440 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe,
11441 0xce, 0xf0, 0xfe, 0xca,
11442 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
11443 0x22, 0x00, 0x02, 0x5a,
11444 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a,
11445 0xfe, 0xd0, 0xf0, 0xfe,
11446 0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f,
11447 0x4c, 0xfe, 0x10, 0x10,
11448 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
11449 0x2a, 0x13, 0xfe, 0x4e,
11450 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1,
11451 0x16, 0x32, 0x2a, 0x73,
11452 0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25,
11453 0x32, 0x8c, 0xfe, 0x48,
11454 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
11455 0xdb, 0x10, 0x11, 0xfe,
11456 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0,
11457 0x22, 0x30, 0x2e, 0xd8,
11458 0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1,
11459 0x45, 0x0f, 0xfe, 0x42,
11460 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
11461 0x09, 0x04, 0x0b, 0xfe,
11462 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28,
11463 0x00, 0x21, 0xfe, 0xa6,
11464 0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00,
11465 0xfe, 0xe2, 0x10, 0x01,
11466 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
11467 0x01, 0x6f, 0x02, 0x29,
11468 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10,
11469 0x01, 0x86, 0x3e, 0x0b,
11470 0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3,
11471 0x3e, 0x0b, 0x0f, 0xfe,
11472 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
11473 0xe8, 0x59, 0x11, 0x2d,
11474 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09,
11475 0x04, 0x0b, 0x84, 0x3e,
11476 0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12,
11477 0x09, 0x04, 0x1b, 0xfe,
11478 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
11479 0x1c, 0x1c, 0xfe, 0x9d,
11480 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f,
11481 0xfe, 0x15, 0x00, 0xfe,
11482 0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10,
11483 0x0f, 0xfe, 0x47, 0x00,
11484 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
11485 0xab, 0x70, 0x05, 0x6b,
11486 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe,
11487 0x1c, 0x42, 0x59, 0x01,
11488 0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31,
11489 0x00, 0x37, 0x97, 0x01,
11490 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
11491 0x1d, 0xfe, 0xce, 0x45,
11492 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75,
11493 0x57, 0x05, 0x51, 0xfe,
11494 0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48,
11495 0x46, 0x09, 0x04, 0x1d,
11496 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
11497 0x99, 0x01, 0x0e, 0xfe,
11498 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51,
11499 0xfe, 0xee, 0x14, 0xee,
11500 0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad,
11501 0x13, 0x02, 0x29, 0x1e,
11502 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
11503 0xce, 0x1e, 0x2d, 0x47,
11504 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06,
11505 0x12, 0x4d, 0x01, 0xfe,
11506 0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe,
11507 0xf0, 0x0d, 0xfe, 0x02,
11508 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
11509 0xf6, 0xfe, 0x34, 0x01,
11510 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13,
11511 0xaf, 0xfe, 0x02, 0xea,
11512 0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c,
11513 0x05, 0xfe, 0x38, 0x01,
11514 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
11515 0x0c, 0xfe, 0x62, 0x01,
11516 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06,
11517 0x03, 0x23, 0x03, 0x1e,
11518 0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe,
11519 0x71, 0x13, 0xfe, 0x24,
11520 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
11521 0xdc, 0xfe, 0x73, 0x57,
11522 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe,
11523 0x80, 0x5d, 0x03, 0xfe,
11524 0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6,
11525 0x75, 0x03, 0x09, 0x04,
11526 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
11527 0xfe, 0x1e, 0x80, 0xe1,
11528 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e,
11529 0x90, 0xa3, 0xfe, 0x3c,
11530 0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82,
11531 0x16, 0x2f, 0x07, 0x2d,
11532 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
11533 0xe8, 0x11, 0xfe, 0xe9,
11534 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe,
11535 0x1e, 0x1c, 0xfe, 0x14,
11536 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01,
11537 0x09, 0x04, 0x4f, 0xfe,
11538 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
11539 0x40, 0x12, 0x20, 0x63,
11540 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08,
11541 0x1c, 0x05, 0xfe, 0xac,
11542 0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05,
11543 0xfe, 0xb0, 0x00, 0xfe,
11544 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
11545 0x24, 0x69, 0x12, 0xc9,
11546 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe,
11547 0x90, 0x4d, 0xfe, 0x91,
11548 0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c,
11549 0xfe, 0x90, 0x4d, 0xfe,
11550 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
11551 0x46, 0x1e, 0x20, 0xed,
11552 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea,
11553 0x70, 0xfe, 0x14, 0x1c,
11554 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee,
11555 0xfe, 0x07, 0xe6, 0x1d,
11556 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
11557 0xfa, 0xef, 0xfe, 0x42,
11558 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0,
11559 0xfe, 0x36, 0x12, 0xf0,
11560 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
11561 0x3d, 0x75, 0x07, 0x10,
11562 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
11563 0x10, 0x07, 0x7e, 0x45,
11564 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74,
11565 0xfe, 0x01, 0xec, 0x97,
11566 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76,
11567 0x27, 0x01, 0xda, 0xfe,
11568 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
11569 0xfe, 0x48, 0x12, 0x07,
11570 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16,
11571 0xfe, 0x3e, 0x11, 0x07,
11572 0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8,
11573 0x11, 0x07, 0x19, 0xfe,
11574 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
11575 0x01, 0x08, 0x8c, 0x43,
11576 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11,
11577 0x7e, 0x02, 0x29, 0x2b,
11578 0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe,
11579 0xfc, 0x10, 0x09, 0x04,
11580 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
11581 0xc6, 0x10, 0x1e, 0x58,
11582 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c,
11583 0x54, 0x18, 0x55, 0x23,
11584 0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01,
11585 0xa5, 0xc0, 0x38, 0xc1,
11586 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
11587 0x05, 0xfa, 0x4e, 0xfe,
11588 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56,
11589 0x0c, 0x56, 0x18, 0x57,
11590 0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe,
11591 0x00, 0x56, 0xfe, 0xa1,
11592 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
11593 0x58, 0xfe, 0x1f, 0x40,
11594 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56,
11595 0x31, 0x57, 0xfe, 0x44,
11596 0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe,
11597 0x8a, 0x50, 0x05, 0x39,
11598 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
11599 0x12, 0xcd, 0x02, 0x5b,
11600 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44,
11601 0x2f, 0x07, 0x9b, 0x21,
11602 0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79,
11603 0x39, 0x68, 0x3a, 0xfe,
11604 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
11605 0x51, 0xfe, 0x8e, 0x51,
11606 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b,
11607 0x01, 0x08, 0x25, 0x32,
11608 0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b,
11609 0x3b, 0x02, 0x44, 0x01,
11610 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
11611 0x01, 0x08, 0x1f, 0xa2,
11612 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c,
11613 0x00, 0x28, 0x84, 0x49,
11614 0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06,
11615 0x78, 0x3d, 0xfe, 0xda,
11616 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
11617 0x05, 0xc6, 0x28, 0x84,
11618 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8,
11619 0x14, 0xfe, 0x03, 0x17,
11620 0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01,
11621 0xfe, 0xaa, 0x14, 0x02,
11622 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
11623 0x21, 0x44, 0x01, 0xfe,
11624 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87,
11625 0xfe, 0x4a, 0xf4, 0x0b,
11626 0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a,
11627 0x85, 0x02, 0x5b, 0x05,
11628 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
11629 0xd8, 0x14, 0x02, 0x5c,
11630 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1,
11631 0x01, 0x08, 0x23, 0x72,
11632 0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca,
11633 0x12, 0x5e, 0x2b, 0x01,
11634 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
11635 0x1c, 0xfe, 0xff, 0x7f,
11636 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00,
11637 0x57, 0x48, 0x8b, 0x1c,
11638 0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02,
11639 0x00, 0x57, 0x48, 0x8b,
11640 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
11641 0x03, 0x0a, 0x50, 0x01,
11642 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00,
11643 0x54, 0xfe, 0x00, 0xf4,
11644 0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe,
11645 0x03, 0x7c, 0x63, 0x27,
11646 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
11647 0xfe, 0x82, 0x4a, 0xfe,
11648 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe,
11649 0x42, 0x48, 0x5f, 0x60,
11650 0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08,
11651 0x1f, 0xfe, 0xa2, 0x14,
11652 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
11653 0xcc, 0x12, 0x49, 0x04,
11654 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe,
11655 0xe8, 0x13, 0x3b, 0x13,
11656 0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55,
11657 0xa1, 0xff, 0x02, 0x83,
11658 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
11659 0x13, 0x06, 0xfe, 0x56,
11660 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe,
11661 0x64, 0x00, 0x17, 0x93,
11662 0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe,
11663 0xc8, 0x00, 0x8e, 0xe4,
11664 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
11665 0x01, 0xba, 0xfe, 0x4e,
11666 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0,
11667 0xfe, 0x60, 0x14, 0xfe,
11668 0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01,
11669 0xfe, 0x22, 0x13, 0x1c,
11670 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
11671 0xfe, 0x9c, 0x14, 0xb7,
11672 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba,
11673 0xfe, 0x9c, 0x14, 0xb7,
11674 0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06,
11675 0xfe, 0xb4, 0x56, 0xfe,
11676 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
11677 0xe5, 0x15, 0x0b, 0x01,
11678 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89,
11679 0x49, 0x01, 0x08, 0x03,
11680 0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6,
11681 0x15, 0x06, 0x01, 0x08,
11682 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
11683 0x4a, 0x01, 0x08, 0x03,
11684 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc,
11685 0xfe, 0x49, 0xf4, 0x00,
11686 0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01,
11687 0x08, 0x2f, 0x07, 0xfe,
11688 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
11689 0x01, 0x43, 0x1e, 0xcd,
11690 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e,
11691 0xed, 0x88, 0x07, 0x10,
11692 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a,
11693 0x80, 0x01, 0x0e, 0x88,
11694 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
11695 0x88, 0x03, 0x0a, 0x42,
11696 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e,
11697 0xfe, 0x80, 0x80, 0xf2,
11698 0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51,
11699 0x01, 0x82, 0x03, 0x17,
11700 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
11701 0xfe, 0x24, 0x1c, 0xfe,
11702 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0,
11703 0x91, 0x1d, 0x66, 0xfe,
11704 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe,
11705 0xda, 0x10, 0x17, 0x10,
11706 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
11707 0x05, 0xfe, 0x66, 0x01,
11708 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06,
11709 0xfe, 0x3c, 0x50, 0x66,
11710 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe,
11711 0x40, 0x16, 0xfe, 0xb6,
11712 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
11713 0x10, 0x71, 0xfe, 0x83,
11714 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90,
11715 0xfe, 0x62, 0x16, 0xfe,
11716 0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19,
11717 0xfe, 0x98, 0xe7, 0x00,
11718 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
11719 0xfe, 0x30, 0xbc, 0xfe,
11720 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
11721 0xc5, 0x90, 0xfe, 0x9a,
11722 0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe,
11723 0x42, 0x10, 0xfe, 0x02,
11724 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
11725 0xfe, 0x1d, 0xf7, 0x4f,
11726 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f,
11727 0x47, 0xfe, 0x83, 0x58,
11728 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11,
11729 0xfe, 0xdd, 0x00, 0x63,
11730 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
11731 0x06, 0x37, 0x95, 0xa9,
11732 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e,
11733 0x18, 0x1c, 0x1a, 0x5d,
11734 0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe,
11735 0xe1, 0x10, 0x78, 0x2c,
11736 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
11737 0x13, 0x3c, 0x8a, 0x0a,
11738 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
11739 0xe3, 0xfe, 0x00, 0xcc,
11740 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01,
11741 0x0e, 0xf2, 0x01, 0x6f,
11742 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
11743 0xf6, 0xfe, 0xd6, 0xf0,
11744 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe,
11745 0x15, 0x00, 0x59, 0x76,
11746 0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35,
11747 0x11, 0x2d, 0x01, 0x6f,
11748 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
11749 0xc8, 0xfe, 0x48, 0x55,
11750 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a,
11751 0x99, 0x01, 0x0e, 0xf0,
11752 0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73,
11753 0x75, 0x03, 0x0a, 0x42,
11754 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
11755 0x0e, 0x73, 0x75, 0x03,
11756 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00,
11757 0xfe, 0x3a, 0x45, 0x5b,
11758 0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00,
11759 0xfe, 0x02, 0xe6, 0x1b,
11760 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
11761 0xfe, 0x94, 0x00, 0xfe,
11762 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02,
11763 0xe6, 0x2c, 0xfe, 0x4e,
11764 0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69,
11765 0x03, 0x07, 0x7a, 0xfe,
11766 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
11767 0x07, 0x1b, 0xfe, 0x5a,
11768 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d,
11769 0x24, 0x2c, 0xdc, 0x07,
11770 0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d,
11771 0x9f, 0xad, 0x03, 0x14,
11772 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
11773 0x03, 0x25, 0xfe, 0xca,
11774 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a,
11775 0x00, 0x00,
11776 };
11777
11778 static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
11779 static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
11780
11781 /* Microcode buffer is kept after initialization for error recovery. */
11782 static unsigned char _adv_asc38C0800_buf[] = {
11783 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
11784 0x01, 0x00, 0x48, 0xe4,
11785 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff,
11786 0x1c, 0x0f, 0x00, 0xf6,
11787 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6,
11788 0x09, 0xe7, 0x55, 0xf0,
11789 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
11790 0x18, 0xf4, 0x08, 0x00,
11791 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6,
11792 0x86, 0xf0, 0xb1, 0xf0,
11793 0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c,
11794 0x3c, 0x00, 0xbb, 0x00,
11795 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
11796 0xba, 0x13, 0x18, 0x40,
11797 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01,
11798 0x6e, 0x01, 0x74, 0x01,
11799 0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00,
11800 0xc0, 0x00, 0x01, 0x01,
11801 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
11802 0x08, 0x12, 0x02, 0x4a,
11803 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4,
11804 0x5d, 0xf0, 0x02, 0xfa,
11805 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01,
11806 0x68, 0x01, 0x6a, 0x01,
11807 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
11808 0x06, 0x13, 0x4c, 0x1c,
11809 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00,
11810 0x0f, 0x00, 0x47, 0x00,
11811 0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c,
11812 0x4e, 0x1c, 0x10, 0x44,
11813 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
11814 0x05, 0x00, 0x34, 0x00,
11815 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b,
11816 0x42, 0x0c, 0x12, 0x0f,
11817 0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48,
11818 0x00, 0x4e, 0x42, 0x54,
11819 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
11820 0x59, 0xf0, 0xb8, 0xf0,
11821 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00,
11822 0x19, 0x00, 0x33, 0x00,
11823 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00,
11824 0xe7, 0x00, 0xe2, 0x03,
11825 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
11826 0x12, 0x13, 0x24, 0x14,
11827 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c,
11828 0x36, 0x1c, 0x08, 0x44,
11829 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54,
11830 0x3a, 0x55, 0x83, 0x55,
11831 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
11832 0x0c, 0xf0, 0x04, 0xf8,
11833 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00,
11834 0xa8, 0x00, 0xaa, 0x00,
11835 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01,
11836 0xc4, 0x01, 0xc6, 0x01,
11837 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
11838 0x68, 0x08, 0x69, 0x08,
11839 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10,
11840 0xed, 0x10, 0xf1, 0x10,
11841 0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13,
11842 0x1e, 0x13, 0x46, 0x14,
11843 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
11844 0xca, 0x18, 0xe6, 0x19,
11845 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c,
11846 0xf0, 0x2b, 0x02, 0xfe,
11847 0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6,
11848 0xfe, 0x84, 0x01, 0xff,
11849 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
11850 0x00, 0xfe, 0x57, 0x24,
11851 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09,
11852 0x00, 0x00, 0xff, 0x08,
11853 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
11854 0xff, 0xff, 0xff, 0x11,
11855 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
11856 0xfe, 0x04, 0xf7, 0xd6,
11857 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99,
11858 0x0a, 0x42, 0x2c, 0xfe,
11859 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0,
11860 0xfe, 0xf4, 0x01, 0xfe,
11861 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
11862 0x02, 0xfe, 0xc8, 0x0d,
11863 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
11864 0x1c, 0x03, 0xfe, 0xa6,
11865 0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48,
11866 0xf0, 0xfe, 0x8a, 0x02,
11867 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
11868 0xfe, 0x46, 0xf0, 0xfe,
11869 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
11870 0x48, 0x02, 0xfe, 0x44,
11871 0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a,
11872 0xaa, 0x18, 0x06, 0x14,
11873 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
11874 0x1e, 0x1c, 0xfe, 0xe9,
11875 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce,
11876 0x09, 0x70, 0x01, 0xa8,
11877 0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70,
11878 0x01, 0x87, 0xfe, 0xbd,
11879 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
11880 0x58, 0x1c, 0x18, 0x06,
11881 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23,
11882 0xfe, 0x98, 0x02, 0xfe,
11883 0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2,
11884 0x01, 0xfe, 0x48, 0x10,
11885 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
11886 0x69, 0x10, 0x18, 0x06,
11887 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05,
11888 0xf6, 0xce, 0x01, 0xfe,
11889 0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe,
11890 0x82, 0x16, 0x02, 0x2b,
11891 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
11892 0xfe, 0x41, 0x58, 0x09,
11893 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe,
11894 0x82, 0x16, 0x02, 0x2b,
11895 0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43,
11896 0xfe, 0x77, 0x57, 0xfe,
11897 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
11898 0xfe, 0x40, 0x1c, 0x1c,
11899 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48,
11900 0x03, 0xfe, 0x11, 0xf0,
11901 0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10,
11902 0xfe, 0x11, 0x00, 0x02,
11903 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
11904 0x21, 0x22, 0xa3, 0xb7,
11905 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16,
11906 0x12, 0xd1, 0x1c, 0xd9,
11907 0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12,
11908 0xfe, 0xe4, 0x00, 0x27,
11909 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
11910 0x06, 0xf0, 0xfe, 0xc8,
11911 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03,
11912 0x70, 0x28, 0x17, 0xfe,
11913 0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8,
11914 0xf9, 0x2c, 0x99, 0x19,
11915 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
11916 0x74, 0x01, 0xaf, 0x8c,
11917 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e,
11918 0x8d, 0x51, 0x64, 0x79,
11919 0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b,
11920 0xfe, 0x6a, 0x02, 0x02,
11921 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
11922 0xfe, 0x3c, 0x04, 0x3b,
11923 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02,
11924 0x00, 0x10, 0x01, 0x0b,
11925 0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde,
11926 0xfe, 0x4c, 0x44, 0xfe,
11927 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
11928 0xda, 0x4f, 0x79, 0x2a,
11929 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b,
11930 0xfe, 0x2a, 0x13, 0x32,
11931 0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c,
11932 0x54, 0x6b, 0xda, 0xfe,
11933 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
11934 0x08, 0x13, 0x32, 0x07,
11935 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d,
11936 0x08, 0x05, 0x06, 0x4d,
11937 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24,
11938 0x2d, 0x12, 0xfe, 0xe6,
11939 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
11940 0x02, 0x2b, 0xfe, 0x42,
11941 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
11942 0xfe, 0x87, 0x80, 0xfe,
11943 0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80,
11944 0x07, 0x19, 0xfe, 0x7c,
11945 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
11946 0x17, 0xfe, 0x90, 0x05,
11947 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe,
11948 0xa0, 0x00, 0x28, 0xfe,
11949 0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c,
11950 0x34, 0xfe, 0x89, 0x48,
11951 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
11952 0x12, 0xfe, 0xe3, 0x00,
11953 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
11954 0x70, 0x05, 0x88, 0x25,
11955 0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe,
11956 0x09, 0x48, 0xff, 0x02,
11957 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
11958 0x08, 0x53, 0x05, 0xcb,
11959 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08,
11960 0x05, 0x1b, 0xfe, 0x22,
11961 0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe,
11962 0x0d, 0x00, 0x01, 0x36,
11963 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
11964 0x03, 0x5c, 0x28, 0xfe,
11965 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53,
11966 0x05, 0x1f, 0xfe, 0x02,
11967 0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5,
11968 0x01, 0x4b, 0x12, 0xfe,
11969 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
11970 0x12, 0x03, 0x45, 0x28,
11971 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe,
11972 0x43, 0x48, 0xc4, 0xcc,
11973 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4,
11974 0x6e, 0x41, 0x01, 0xb2,
11975 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
11976 0xfe, 0xcc, 0x15, 0x1d,
11977 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03,
11978 0x45, 0xc1, 0x0c, 0x45,
11979 0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe,
11980 0xe2, 0x00, 0x27, 0xdb,
11981 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
11982 0xfe, 0x06, 0xf0, 0xfe,
11983 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12,
11984 0x16, 0x19, 0x01, 0x0b,
11985 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
11986 0xfe, 0x99, 0xa4, 0x01,
11987 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
11988 0x12, 0x08, 0x05, 0x1a,
11989 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
11990 0x0b, 0x16, 0x00, 0x01,
11991 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02,
11992 0xe2, 0x6c, 0x58, 0xbe,
11993 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
11994 0xfe, 0x09, 0x6f, 0xba,
11995 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27,
11996 0xfe, 0x54, 0x07, 0x1c,
11997 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c,
11998 0x07, 0x02, 0x24, 0x01,
11999 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
12000 0x2c, 0x90, 0xfe, 0xae,
12001 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a,
12002 0x37, 0x22, 0x20, 0x07,
12003 0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a,
12004 0xfe, 0x06, 0x10, 0xfe,
12005 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
12006 0x37, 0x01, 0xb3, 0xb8,
12007 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a,
12008 0x50, 0xfe, 0x44, 0x51,
12009 0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e,
12010 0x14, 0x5f, 0xfe, 0x0c,
12011 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
12012 0x14, 0x3e, 0xfe, 0x4a,
12013 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
12014 0x90, 0x0c, 0x60, 0x14,
12015 0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62,
12016 0xfe, 0x44, 0x90, 0xfe,
12017 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
12018 0x0c, 0x5e, 0x14, 0x5f,
12019 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e,
12020 0x14, 0x3c, 0x21, 0x0c,
12021 0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11,
12022 0x27, 0xdd, 0xfe, 0x9e,
12023 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
12024 0x9a, 0x08, 0xc6, 0xfe,
12025 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08,
12026 0x95, 0x86, 0x02, 0x24,
12027 0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05,
12028 0x06, 0xfe, 0x10, 0x12,
12029 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
12030 0x1c, 0x02, 0xfe, 0x18,
12031 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe,
12032 0x2c, 0x1c, 0xfe, 0xaa,
12033 0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe,
12034 0xde, 0x09, 0xfe, 0xb7,
12035 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
12036 0xfe, 0xf1, 0x18, 0xfe,
12037 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe,
12038 0x14, 0x59, 0xfe, 0x95,
12039 0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0,
12040 0xfe, 0xf0, 0x08, 0xb5,
12041 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
12042 0x0b, 0xb6, 0xfe, 0xbf,
12043 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c,
12044 0x12, 0xc2, 0xfe, 0xd2,
12045 0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e,
12046 0x06, 0x17, 0x85, 0xc5,
12047 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
12048 0x9d, 0x01, 0x36, 0x10,
12049 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe,
12050 0x98, 0x80, 0xfe, 0x19,
12051 0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18,
12052 0xfe, 0x44, 0x54, 0xbe,
12053 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
12054 0x02, 0x4a, 0x08, 0x05,
12055 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e,
12056 0x9c, 0x3c, 0xfe, 0x6c,
12057 0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f,
12058 0x3b, 0x40, 0x03, 0x49,
12059 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
12060 0x8f, 0xfe, 0xe3, 0x54,
12061 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe,
12062 0xda, 0x09, 0xfe, 0x8b,
12063 0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa,
12064 0x0a, 0x3a, 0x49, 0x3b,
12065 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
12066 0xad, 0xfe, 0x01, 0x59,
12067 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a,
12068 0x49, 0x8f, 0xfe, 0xe3,
12069 0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02,
12070 0x4a, 0x3a, 0x49, 0x3b,
12071 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
12072 0x02, 0x4a, 0x08, 0x05,
12073 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62,
12074 0xb7, 0xfe, 0x03, 0xa1,
12075 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
12076 0xfe, 0x86, 0x91, 0x6a,
12077 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
12078 0x61, 0x0c, 0x7f, 0x14,
12079 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62,
12080 0x9b, 0x2e, 0x9c, 0x3c,
12081 0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05,
12082 0xfa, 0x3c, 0x01, 0xef,
12083 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
12084 0xe4, 0x08, 0x05, 0x1f,
12085 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37,
12086 0x03, 0x5e, 0x29, 0x5f,
12087 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe,
12088 0xf4, 0x09, 0x08, 0x05,
12089 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
12090 0x81, 0x50, 0xfe, 0x10,
12091 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe,
12092 0x08, 0x09, 0x12, 0xa6,
12093 0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe,
12094 0x08, 0x09, 0xfe, 0x0c,
12095 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
12096 0x08, 0x05, 0x0a, 0xfe,
12097 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1,
12098 0xf0, 0xe2, 0x15, 0x7e,
12099 0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19,
12100 0x57, 0x3d, 0xfe, 0xed,
12101 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
12102 0x00, 0xff, 0x35, 0xfe,
12103 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18,
12104 0x1e, 0x19, 0x8a, 0x03,
12105 0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65,
12106 0xfe, 0xd1, 0xf0, 0xfe,
12107 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
12108 0x10, 0xfe, 0xce, 0xf0,
12109 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b,
12110 0x10, 0xfe, 0x22, 0x00,
12111 0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00,
12112 0x02, 0x65, 0xfe, 0xd0,
12113 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
12114 0x0b, 0x10, 0x58, 0xfe,
12115 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe,
12116 0x12, 0x00, 0x2c, 0x0f,
12117 0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14,
12118 0x0c, 0xbc, 0x17, 0x34,
12119 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
12120 0x0c, 0x1c, 0x34, 0x94,
12121 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01,
12122 0x4b, 0xfe, 0xdb, 0x10,
12123 0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe,
12124 0x89, 0xf0, 0x24, 0x33,
12125 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
12126 0x33, 0x31, 0xdf, 0xbc,
12127 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49,
12128 0x17, 0xfe, 0x2c, 0x0d,
12129 0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54,
12130 0x12, 0x55, 0xfe, 0x28,
12131 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
12132 0x44, 0xfe, 0x28, 0x00,
12133 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26,
12134 0x0f, 0x64, 0x12, 0x2f,
12135 0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44,
12136 0x0a, 0xfe, 0xb4, 0x10,
12137 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
12138 0xfe, 0x34, 0x46, 0xac,
12139 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a,
12140 0x37, 0x01, 0xf5, 0x01,
12141 0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02,
12142 0xfe, 0x2e, 0x03, 0x08,
12143 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
12144 0x1a, 0xfe, 0x58, 0x12,
12145 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
12146 0xfe, 0x50, 0x0d, 0xfe,
12147 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37,
12148 0xfe, 0xa9, 0x10, 0x10,
12149 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
12150 0xfe, 0x13, 0x00, 0xfe,
12151 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe,
12152 0x24, 0x00, 0x8c, 0xb5,
12153 0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a,
12154 0xfe, 0x9d, 0x41, 0xfe,
12155 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
12156 0xb4, 0x15, 0xfe, 0x31,
12157 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06,
12158 0xec, 0xd0, 0xfc, 0x44,
12159 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47,
12160 0x4b, 0x91, 0xfe, 0x75,
12161 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
12162 0x0e, 0xfe, 0x44, 0x48,
12163 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41,
12164 0xfe, 0x41, 0x58, 0x09,
12165 0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe,
12166 0x2e, 0x03, 0x09, 0x5d,
12167 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
12168 0xce, 0x47, 0xfe, 0xad,
12169 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13,
12170 0x59, 0x13, 0x9f, 0x13,
12171 0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe,
12172 0xe0, 0x0e, 0x0f, 0x06,
12173 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
12174 0x3a, 0x01, 0x56, 0xfe,
12175 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec,
12176 0x20, 0x4f, 0xfe, 0x05,
12177 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe,
12178 0x48, 0xf4, 0x0d, 0xfe,
12179 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
12180 0x15, 0x1a, 0x39, 0xa0,
12181 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff,
12182 0x0c, 0xfe, 0x60, 0x01,
12183 0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25,
12184 0x06, 0x13, 0x2f, 0x12,
12185 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
12186 0x22, 0x9f, 0xb7, 0x13,
12187 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39,
12188 0xa0, 0xb4, 0xfe, 0xd9,
12189 0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04,
12190 0xc3, 0xfe, 0x03, 0xdc,
12191 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
12192 0xfe, 0x00, 0xcc, 0x04,
12193 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13,
12194 0xfe, 0x1c, 0x80, 0x07,
12195 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae,
12196 0xfe, 0x0c, 0x90, 0xfe,
12197 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
12198 0x0a, 0xfe, 0x3c, 0x50,
12199 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4,
12200 0x16, 0x08, 0x05, 0x1b,
12201 0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58,
12202 0xfe, 0x2c, 0x13, 0x01,
12203 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
12204 0x0c, 0xfe, 0x64, 0x01,
12205 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03,
12206 0x80, 0x8d, 0xfe, 0x01,
12207 0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64,
12208 0x22, 0x20, 0xfb, 0x79,
12209 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
12210 0x03, 0xfe, 0xae, 0x00,
12211
12212 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe,
12213 0xb2, 0x00, 0xfe, 0x09,
12214 0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c,
12215 0x45, 0x0f, 0x46, 0x52,
12216 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
12217 0x0f, 0x44, 0x11, 0x0f,
12218 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4,
12219 0x25, 0x11, 0x13, 0x20,
12220 0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14,
12221 0x56, 0xfe, 0xd6, 0xf0,
12222 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
12223 0x18, 0x1c, 0x04, 0x42,
12224 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe,
12225 0xf5, 0x13, 0x04, 0x01,
12226 0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
12227 0x13, 0x32, 0x07, 0x2f,
12228 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
12229 0x41, 0x48, 0xfe, 0x45,
12230 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78,
12231 0x07, 0x11, 0xac, 0x09,
12232 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07,
12233 0x82, 0x4e, 0xfe, 0x14,
12234 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
12235 0xfe, 0x01, 0xec, 0xa2,
12236 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79,
12237 0x2a, 0x01, 0xe3, 0xfe,
12238 0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a,
12239 0xfe, 0x48, 0x12, 0x07,
12240 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
12241 0xfe, 0x32, 0x12, 0x07,
12242 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07,
12243 0x1f, 0xfe, 0x12, 0x12,
12244 0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b,
12245 0x94, 0x4b, 0x04, 0x2d,
12246 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
12247 0x32, 0x07, 0xa6, 0xfe,
12248 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05,
12249 0x5a, 0xfe, 0x72, 0x12,
12250 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62,
12251 0xfe, 0x26, 0x13, 0x03,
12252 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
12253 0x0c, 0x7f, 0x0c, 0x80,
12254 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c,
12255 0x3c, 0xfe, 0x04, 0x55,
12256 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe,
12257 0x91, 0x10, 0x03, 0x3f,
12258 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
12259 0x88, 0x9b, 0x2e, 0x9c,
12260 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
12261 0x56, 0x0c, 0x5e, 0x14,
12262 0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40,
12263 0x03, 0x60, 0x29, 0x61,
12264 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
12265 0x50, 0xfe, 0xc6, 0x50,
12266 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d,
12267 0x29, 0x3e, 0xfe, 0x40,
12268 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72,
12269 0x2d, 0x01, 0x0b, 0x1d,
12270 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
12271 0x72, 0x01, 0xaf, 0x1e,
12272 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe,
12273 0x0a, 0x55, 0x35, 0xfe,
12274 0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51,
12275 0x02, 0x72, 0xfe, 0x19,
12276 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
12277 0x1d, 0xe8, 0x33, 0x31,
12278 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01,
12279 0x0b, 0x1c, 0x34, 0x1d,
12280 0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8,
12281 0x33, 0x31, 0xfe, 0xe8,
12282 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
12283 0x05, 0x1f, 0x35, 0xa9,
12284 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda,
12285 0x14, 0x01, 0xaf, 0x8c,
12286 0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a,
12287 0x03, 0x45, 0x28, 0x35,
12288 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
12289 0x03, 0x5c, 0xc1, 0x0c,
12290 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02,
12291 0x89, 0x01, 0x0b, 0x1c,
12292 0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1,
12293 0xfe, 0x42, 0x58, 0xf1,
12294 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
12295 0xf4, 0x06, 0xea, 0x32,
12296 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d,
12297 0x01, 0x0b, 0x26, 0x89,
12298 0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13,
12299 0x26, 0xfe, 0xd4, 0x13,
12300 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
12301 0x13, 0x1c, 0xfe, 0xd0,
12302 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10,
12303 0x0f, 0x71, 0xff, 0x02,
12304 0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe,
12305 0x00, 0x5c, 0x04, 0x0f,
12306 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
12307 0xfe, 0x00, 0x5c, 0x04,
12308 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff,
12309 0x02, 0x00, 0x57, 0x52,
12310 0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01,
12311 0x87, 0x04, 0xfe, 0x03,
12312 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
12313 0xfe, 0x00, 0x7d, 0xfe,
12314 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e,
12315 0x14, 0x5f, 0x57, 0x3f,
12316 0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83,
12317 0x5a, 0x8d, 0x04, 0x01,
12318 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
12319 0xfe, 0x96, 0x15, 0x33,
12320 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8,
12321 0x0a, 0xfe, 0xc1, 0x59,
12322 0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13,
12323 0x21, 0x69, 0x1a, 0xee,
12324 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
12325 0x30, 0xfe, 0x78, 0x10,
12326 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae,
12327 0x98, 0xfe, 0x30, 0x00,
12328 0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed,
12329 0x98, 0xfe, 0x64, 0x00,
12330 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
12331 0x10, 0x69, 0x06, 0xfe,
12332 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00,
12333 0x18, 0x59, 0x0f, 0x06,
12334 0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe,
12335 0x43, 0xf4, 0x9f, 0xfe,
12336 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
12337 0x9e, 0xfe, 0xf3, 0x10,
12338 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00,
12339 0x17, 0xfe, 0x4d, 0xe4,
12340 0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00,
12341 0x17, 0xfe, 0x4d, 0xe4,
12342 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
12343 0xf4, 0x00, 0xe9, 0x91,
12344 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a,
12345 0x04, 0x16, 0x06, 0x01,
12346 0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01,
12347 0x0b, 0x26, 0xf3, 0x76,
12348 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
12349 0x16, 0x19, 0x01, 0x0b,
12350 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01,
12351 0x0b, 0x26, 0xb1, 0x76,
12352 0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06,
12353 0xfe, 0x48, 0x13, 0xb8,
12354 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
12355 0xec, 0xfe, 0x27, 0x01,
12356 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32,
12357 0x07, 0xfe, 0xe3, 0x00,
12358 0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b,
12359 0x22, 0xd4, 0x07, 0x06,
12360 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
12361 0x07, 0x11, 0xae, 0x09,
12362 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01,
12363 0x0e, 0x8e, 0xfe, 0x80,
12364 0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04,
12365 0x09, 0x48, 0x01, 0x0e,
12366 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
12367 0x80, 0xfe, 0x80, 0x4c,
12368 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c,
12369 0x09, 0x5d, 0x01, 0x87,
12370 0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe,
12371 0x19, 0xde, 0xfe, 0x24,
12372 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
12373 0x17, 0xad, 0x9a, 0x1b,
12374 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde,
12375 0x16, 0xfe, 0xda, 0x10,
12376 0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe,
12377 0x18, 0x58, 0x03, 0xfe,
12378 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
12379 0xf4, 0x06, 0xfe, 0x3c,
12380 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f,
12381 0x97, 0xfe, 0x38, 0x17,
12382 0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c,
12383 0x10, 0x18, 0x11, 0x75,
12384 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
12385 0x2e, 0x97, 0xfe, 0x5a,
12386 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19,
12387 0xfe, 0x98, 0xe7, 0x00,
12388 0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75,
12389 0xfe, 0x30, 0xbc, 0xfe,
12390 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
12391 0xcb, 0x97, 0xfe, 0x92,
12392 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe,
12393 0x42, 0x10, 0xfe, 0x02,
12394 0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe,
12395 0x03, 0xa1, 0xfe, 0x1d,
12396 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
12397 0x9a, 0x5b, 0x41, 0xfe,
12398 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7,
12399 0x11, 0x12, 0xfe, 0xdd,
12400 0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8,
12401 0x17, 0x15, 0x06, 0x39,
12402 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
12403 0xfe, 0x7e, 0x18, 0x1e,
12404 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef,
12405 0x12, 0xfe, 0xe1, 0x10,
12406 0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42,
12407 0x13, 0x42, 0x92, 0x09,
12408 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
12409 0xf0, 0xfe, 0x00, 0xcc,
12410 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01,
12411 0x0e, 0xfe, 0x80, 0x4c,
12412 0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe,
12413 0x24, 0x12, 0xfe, 0x14,
12414 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
12415 0xe7, 0x0a, 0x10, 0xfe,
12416 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92,
12417 0x08, 0x54, 0x1b, 0x37,
12418 0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba,
12419 0x90, 0x3a, 0xce, 0x3b,
12420 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
12421 0x13, 0xa3, 0x04, 0x09,
12422 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49,
12423 0x44, 0x17, 0xfe, 0xe8,
12424 0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09,
12425 0x5d, 0x01, 0xa8, 0x09,
12426 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
12427 0x1c, 0x19, 0x03, 0xfe,
12428 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9,
12429 0x6b, 0xfe, 0x2e, 0x19,
12430 0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4,
12431 0xfe, 0x0b, 0x00, 0x6b,
12432 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
12433 0x08, 0x10, 0x03, 0xfe,
12434 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff,
12435 0x04, 0x68, 0x54, 0xe7,
12436 0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe,
12437 0x1a, 0xf4, 0xfe, 0x00,
12438 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
12439 0x04, 0x07, 0x7e, 0xfe,
12440 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
12441 0x07, 0x1a, 0xfe, 0x5a,
12442 0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66,
12443 0x25, 0x6d, 0xe5, 0x07,
12444 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
12445 0xa9, 0xb8, 0x04, 0x15,
12446 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe,
12447 0x40, 0x5c, 0x04, 0x1c,
12448 0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b,
12449 0xf7, 0xfe, 0x82, 0xf0,
12450 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
12451 };
12452
12453 static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
12454 static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
12455
12456 /* Microcode buffer is kept after initialization for error recovery. */
12457 static unsigned char _adv_asc38C1600_buf[] = {
12458 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
12459 0x18, 0xe4, 0x01, 0x00,
12460 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00,
12461 0x07, 0x17, 0xc0, 0x5f,
12462 0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7,
12463 0x85, 0xf0, 0x86, 0xf0,
12464 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
12465 0x98, 0x57, 0x01, 0xe6,
12466 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d,
12467 0x38, 0x54, 0x32, 0xf0,
12468 0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4,
12469 0x00, 0xe6, 0xb1, 0xf0,
12470 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
12471 0x06, 0x13, 0x0c, 0x1c,
12472 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12,
12473 0xb9, 0x54, 0x00, 0x80,
12474 0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56,
12475 0x03, 0xe6, 0x01, 0xea,
12476 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
12477 0x04, 0x13, 0xbb, 0x55,
12478 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00,
12479 0xbb, 0x00, 0xc0, 0x00,
12480 0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12,
12481 0x4c, 0x1c, 0x4e, 0x1c,
12482 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
12483 0x24, 0x01, 0x3c, 0x01,
12484 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01,
12485 0x78, 0x01, 0x7c, 0x01,
12486 0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c,
12487 0x6e, 0x1e, 0x02, 0x48,
12488 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
12489 0x03, 0xfc, 0x06, 0x00,
12490 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a,
12491 0x30, 0x1c, 0x38, 0x1c,
12492 0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea,
12493 0x5d, 0xf0, 0xa7, 0xf0,
12494 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
12495 0x33, 0x00, 0x34, 0x00,
12496 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01,
12497 0x79, 0x01, 0x3c, 0x09,
12498 0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13,
12499 0x40, 0x16, 0x50, 0x16,
12500 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
12501 0x05, 0xf0, 0x09, 0xf0,
12502 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00,
12503 0x9c, 0x00, 0xa4, 0x00,
12504 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08,
12505 0xe9, 0x09, 0x5c, 0x0c,
12506 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
12507 0x42, 0x1d, 0x08, 0x44,
12508 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54,
12509 0x83, 0x55, 0x83, 0x59,
12510 0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0,
12511 0x4b, 0xf4, 0x04, 0xf8,
12512 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
12513 0xa8, 0x00, 0xaa, 0x00,
12514 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01,
12515 0x7a, 0x01, 0x82, 0x01,
12516 0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07,
12517 0x68, 0x08, 0x10, 0x0d,
12518 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
12519 0xf3, 0x10, 0x06, 0x12,
12520 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c,
12521 0xf0, 0x35, 0x05, 0xfe,
12522 0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8,
12523 0xfe, 0x88, 0x01, 0xff,
12524 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
12525 0x00, 0xfe, 0x57, 0x24,
12526 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09,
12527 0x00, 0x00, 0xff, 0x08,
12528 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
12529 0xff, 0xff, 0xff, 0x13,
12530 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
12531 0xfe, 0x04, 0xf7, 0xe8,
12532 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d,
12533 0x0d, 0x51, 0x37, 0xfe,
12534 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0,
12535 0xfe, 0xf8, 0x01, 0xfe,
12536 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
12537 0x05, 0xfe, 0x08, 0x0f,
12538 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe,
12539 0x28, 0x1c, 0x03, 0xfe,
12540 0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe,
12541 0x48, 0xf0, 0xfe, 0x90,
12542 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
12543 0x02, 0xfe, 0x46, 0xf0,
12544 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0,
12545 0xfe, 0x4e, 0x02, 0xfe,
12546 0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c,
12547 0x0d, 0xa2, 0x1c, 0x07,
12548 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
12549 0x1c, 0xf5, 0xfe, 0x1e,
12550 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc,
12551 0xde, 0x0a, 0x81, 0x01,
12552 0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a,
12553 0x81, 0x01, 0x5c, 0xfe,
12554 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
12555 0xfe, 0x58, 0x1c, 0x1c,
12556 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02,
12557 0x2b, 0xfe, 0x9e, 0x02,
12558 0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30,
12559 0x00, 0x47, 0xb8, 0x01,
12560 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
12561 0x1a, 0x31, 0xfe, 0x69,
12562 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe,
12563 0x1e, 0x1e, 0x20, 0x2c,
12564 0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a,
12565 0x44, 0x15, 0x56, 0x51,
12566 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
12567 0x01, 0x18, 0x09, 0x00,
12568 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01,
12569 0x18, 0xfe, 0xc8, 0x54,
12570 0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60,
12571 0xfe, 0x02, 0xe8, 0x30,
12572 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
12573 0xfe, 0xe4, 0x01, 0xfe,
12574 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe,
12575 0x26, 0xf0, 0xfe, 0x66,
12576 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe,
12577 0xef, 0x10, 0xfe, 0x9f,
12578 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
12579 0x70, 0x37, 0xfe, 0x48,
12580 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26,
12581 0x21, 0xb9, 0xc7, 0x20,
12582 0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15,
12583 0xe1, 0x2a, 0xeb, 0xfe,
12584 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
12585 0x15, 0xfe, 0xe4, 0x00,
12586 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41,
12587 0xfe, 0x06, 0xf0, 0xfe,
12588 0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29,
12589 0x03, 0x81, 0x1e, 0x1b,
12590 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
12591 0xea, 0xfe, 0x46, 0x1c,
12592 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
12593 0xfe, 0x48, 0x1c, 0x75,
12594 0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a,
12595 0xe1, 0x01, 0x18, 0x77,
12596 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
12597 0x8f, 0xfe, 0x70, 0x02,
12598 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04,
12599 0x16, 0xfe, 0x4a, 0x04,
12600 0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff,
12601 0x02, 0x00, 0x10, 0x01,
12602 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
12603 0xee, 0xfe, 0x4c, 0x44,
12604 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54,
12605 0x7b, 0xec, 0x60, 0x8d,
12606 0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01,
12607 0x0c, 0x06, 0x28, 0xfe,
12608 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
12609 0x13, 0x34, 0xfe, 0x4c,
12610 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54,
12611 0x13, 0x01, 0x0c, 0x06,
12612 0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06,
12613 0x28, 0xf9, 0x1f, 0x7f,
12614 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
12615 0xfe, 0xa4, 0x0e, 0x05,
12616 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe,
12617 0x9c, 0x93, 0x3a, 0x0b,
12618 0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b,
12619 0x7d, 0x1d, 0xfe, 0x46,
12620 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
12621 0xfe, 0x87, 0x83, 0xfe,
12622 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98,
12623 0x13, 0x0f, 0xfe, 0x20,
12624 0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84,
12625 0x12, 0x01, 0x38, 0x06,
12626 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
12627 0x05, 0xd0, 0x54, 0x01,
12628 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe,
12629 0x50, 0x12, 0x5e, 0xff,
12630 0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02,
12631 0x00, 0x10, 0x2f, 0xfe,
12632 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
12633 0x38, 0xfe, 0x4a, 0xf0,
12634 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe,
12635 0x21, 0x00, 0xf1, 0x2e,
12636 0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00,
12637 0x10, 0x2f, 0xfe, 0xd0,
12638 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
12639 0x1c, 0x00, 0x4d, 0x01,
12640 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06,
12641 0x28, 0xfe, 0x24, 0x12,
12642 0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe,
12643 0x0d, 0x00, 0x01, 0x42,
12644 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
12645 0x03, 0xb6, 0x1e, 0xfe,
12646 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17,
12647 0xfe, 0x72, 0x06, 0x0a,
12648 0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56,
12649 0x19, 0x16, 0xfe, 0x68,
12650 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
12651 0x03, 0x9a, 0x1e, 0xfe,
12652 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12,
12653 0x48, 0xfe, 0x92, 0x06,
12654 0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13,
12655 0x58, 0xff, 0x02, 0x00,
12656 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
12657 0xfe, 0xea, 0x06, 0x01,
12658 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16,
12659 0xfe, 0xe0, 0x06, 0x15,
12660 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07,
12661 0x01, 0x84, 0xfe, 0xae,
12662 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
12663 0x1e, 0xfe, 0x1a, 0x12,
12664 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
12665 0x43, 0x48, 0x62, 0x80,
12666 0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24,
12667 0x36, 0xfe, 0x02, 0xf6,
12668 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
12669 0xd0, 0x0d, 0x17, 0xfe,
12670 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20,
12671 0x9e, 0x15, 0x82, 0x01,
12672 0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58,
12673 0x57, 0x10, 0xe6, 0x05,
12674 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
12675 0xfe, 0x9c, 0x32, 0x5f,
12676 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c,
12677 0xfe, 0x0a, 0xf0, 0xfe,
12678 0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08,
12679 0xaf, 0xa0, 0x05, 0x29,
12680 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
12681 0x00, 0x01, 0x08, 0x14,
12682 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08,
12683 0x14, 0x00, 0x05, 0xfe,
12684 0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06,
12685 0x12, 0xfe, 0x30, 0x13,
12686 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
12687 0x01, 0x08, 0x14, 0x00,
12688 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a,
12689 0x78, 0x4f, 0x0f, 0xfe,
12690 0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d,
12691 0x28, 0x48, 0xfe, 0x6c,
12692 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
12693 0x12, 0x53, 0x63, 0x4e,
12694 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe,
12695 0x6c, 0x08, 0xaf, 0xa0,
12696 0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24,
12697 0x05, 0xed, 0xfe, 0x9c,
12698 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
12699 0x1e, 0xfe, 0x99, 0x58,
12700 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a,
12701 0x22, 0x6b, 0x01, 0x0c,
12702 0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e,
12703 0x1e, 0x47, 0x2c, 0x7a,
12704 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
12705 0x01, 0x0c, 0x61, 0x65,
12706 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a,
12707 0x16, 0xfe, 0x08, 0x50,
12708 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10,
12709 0x01, 0xfe, 0xce, 0x1e,
12710 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
12711 0x01, 0xfe, 0xfe, 0x1e,
12712 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a,
12713 0x10, 0x01, 0x0c, 0x06,
12714 0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e,
12715 0x10, 0x6a, 0x22, 0x6b,
12716 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
12717 0xfe, 0x9f, 0x83, 0x33,
12718 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93,
12719 0x3a, 0x0b, 0xfe, 0xc6,
12720 0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d,
12721 0x01, 0xfe, 0xce, 0x1e,
12722 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
12723 0x04, 0xfe, 0xc0, 0x93,
12724 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e,
12725 0x10, 0x4b, 0x22, 0x4c,
12726 0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe,
12727 0x4e, 0x11, 0x2f, 0xfe,
12728 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
12729 0x3c, 0x37, 0x88, 0xf5,
12730 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a,
12731 0xd3, 0xfe, 0x42, 0x0a,
12732 0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0,
12733 0x05, 0x29, 0x01, 0x41,
12734 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
12735 0xfe, 0x14, 0x12, 0x01,
12736 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe,
12737 0x2e, 0x1c, 0x05, 0xfe,
12738 0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41,
12739 0xfe, 0x2c, 0x1c, 0xfe,
12740 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
12741 0x92, 0x10, 0xc4, 0xf6,
12742 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe,
12743 0xe7, 0x10, 0xfe, 0x2b,
12744 0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12,
12745 0xac, 0xfe, 0xd2, 0xf0,
12746 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
12747 0x1b, 0xbf, 0xd4, 0x5b,
12748 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75,
12749 0x5e, 0x32, 0x1f, 0x7f,
12750 0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98,
12751 0x05, 0x70, 0xfe, 0x74,
12752 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
12753 0x0f, 0x4d, 0x01, 0xfe,
12754 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06,
12755 0x0d, 0x2b, 0xfe, 0xe2,
12756 0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24,
12757 0xfe, 0x88, 0x13, 0x21,
12758 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
12759 0x83, 0x83, 0xfe, 0xc9,
12760 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04,
12761 0x91, 0x04, 0xfe, 0x84,
12762 0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93,
12763 0xfe, 0xcb, 0x57, 0x0b,
12764 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
12765 0x6a, 0x3b, 0x6b, 0x10,
12766 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30,
12767 0x20, 0x6e, 0xdb, 0x64,
12768 0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55,
12769 0xfe, 0x04, 0xfa, 0x64,
12770 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
12771 0x10, 0x98, 0x91, 0x6c,
12772 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91,
12773 0x4b, 0x7e, 0x4c, 0x01,
12774 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10,
12775 0x58, 0xfe, 0x91, 0x58,
12776 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
12777 0x1b, 0x40, 0x01, 0x0c,
12778 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f,
12779 0xfe, 0x10, 0x90, 0x04,
12780 0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93,
12781 0x79, 0x0b, 0x0e, 0xfe,
12782 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
12783 0x01, 0x0c, 0x06, 0x0d,
12784 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe,
12785 0x0c, 0x58, 0xfe, 0x8d,
12786 0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99,
12787 0x83, 0x33, 0x0b, 0x0e,
12788 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
12789 0x19, 0xfe, 0x19, 0x41,
12790 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42,
12791 0x19, 0xfe, 0x44, 0x00,
12792 0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda,
12793 0x4c, 0xfe, 0x0c, 0x51,
12794 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
12795 0x76, 0x10, 0xac, 0xfe,
12796 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03,
12797 0xe3, 0x23, 0x07, 0xfe,
12798 0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe,
12799 0xcc, 0x0c, 0x1f, 0x92,
12800 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
12801 0x0c, 0xfe, 0x3e, 0x10,
12802 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70,
12803 0xfe, 0xcb, 0xf0, 0xfe,
12804 0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe,
12805 0xf4, 0x0c, 0x19, 0x94,
12806 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
12807 0xfe, 0xcc, 0xf0, 0xef,
12808 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe,
12809 0x4e, 0x11, 0x2f, 0xfe,
12810 0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b,
12811 0x3c, 0x37, 0x88, 0xf5,
12812 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
12813 0x2f, 0xfe, 0x3e, 0x0d,
12814 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f,
12815 0xd2, 0x9f, 0xd3, 0x9f,
12816 0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4,
12817 0xc5, 0x75, 0xd7, 0x99,
12818 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
12819 0x9c, 0x2f, 0xfe, 0x8c,
12820 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe,
12821 0x42, 0x00, 0x05, 0x70,
12822 0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06,
12823 0x0d, 0xfe, 0x44, 0x13,
12824 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
12825 0xfe, 0xda, 0x0e, 0x0a,
12826 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa,
12827 0x10, 0x01, 0xfe, 0xf4,
12828 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40,
12829 0x15, 0x56, 0x01, 0x85,
12830 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
12831 0xcc, 0x10, 0x01, 0xa7,
12832 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04,
12833 0xfe, 0x99, 0x83, 0xfe,
12834 0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe,
12835 0x43, 0x00, 0xfe, 0xa2,
12836 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
12837 0x00, 0x1d, 0x40, 0x15,
12838 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05,
12839 0xfe, 0x3a, 0x03, 0x01,
12840 0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01,
12841 0x76, 0x06, 0x12, 0xfe,
12842 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
12843 0xfe, 0x9d, 0xf0, 0xfe,
12844 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01,
12845 0x0c, 0x61, 0x12, 0x44,
12846 0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f,
12847 0xfe, 0x2e, 0x10, 0x19,
12848 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
12849 0xfe, 0x41, 0x00, 0xa2,
12850 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b,
12851 0xea, 0x4f, 0xfe, 0x04,
12852 0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05,
12853 0x35, 0xfe, 0x12, 0x1c,
12854 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
12855 0xfe, 0xd4, 0x11, 0x05,
12856 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe,
12857 0xce, 0x45, 0x31, 0x51,
12858 0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03,
12859 0x67, 0xfe, 0x98, 0x56,
12860 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
12861 0x0c, 0x06, 0x28, 0xfe,
12862 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba,
12863 0xfe, 0xfa, 0x14, 0xfe,
12864 0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67,
12865 0xfe, 0xe0, 0x14, 0xfe,
12866 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
12867 0xfe, 0xad, 0x13, 0x05,
12868 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20,
12869 0xe7, 0xfe, 0x08, 0x1c,
12870 0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe,
12871 0x48, 0x55, 0xa5, 0x3b,
12872 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
12873 0xf0, 0x1a, 0x03, 0xfe,
12874 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02,
12875 0xec, 0xe7, 0x53, 0x00,
12876 0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
12877 0x01, 0xfe, 0x62, 0x1b,
12878 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
12879 0xea, 0xe7, 0x53, 0x92,
12880 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03,
12881 0xfe, 0x38, 0x01, 0x23,
12882 0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62,
12883 0x01, 0x01, 0xfe, 0x1e,
12884 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
12885 0x26, 0x02, 0x21, 0x96,
12886 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5,
12887 0xc3, 0xfe, 0xe1, 0x10,
12888 0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf,
12889 0xfe, 0x03, 0xdc, 0xfe,
12890 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
12891 0x00, 0xcc, 0x02, 0xfe,
12892 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13,
12893 0x0f, 0xfe, 0x1c, 0x80,
12894 0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13,
12895 0x0f, 0xfe, 0x1e, 0x80,
12896 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
12897 0x1d, 0x80, 0x04, 0xfe,
12898 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee,
12899 0x1e, 0xac, 0xfe, 0x14,
12900 0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e,
12901 0x1f, 0xfe, 0x30, 0xf4,
12902 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
12903 0x56, 0xfb, 0x01, 0xfe,
12904 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01,
12905 0xfe, 0x00, 0x1d, 0x15,
12906 0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe,
12907 0x22, 0x1b, 0xfe, 0x1e,
12908 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
12909 0x96, 0x90, 0x04, 0xfe,
12910 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66,
12911 0x01, 0x01, 0x0c, 0x06,
12912 0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b,
12913 0x0e, 0x77, 0xfe, 0x01,
12914 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
12915 0x21, 0x2c, 0xfe, 0x00,
12916 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe,
12917 0x06, 0x58, 0x03, 0xfe,
12918 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58,
12919 0x03, 0xfe, 0xb2, 0x00,
12920 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
12921 0x66, 0x10, 0x55, 0x10,
12922 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91,
12923 0x54, 0x2b, 0xfe, 0x88,
12924 0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe,
12925 0x91, 0x54, 0x2b, 0xfe,
12926 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
12927 0x00, 0x40, 0x8d, 0x2c,
12928 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe,
12929 0x12, 0x1c, 0x75, 0xfe,
12930 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c,
12931 0x14, 0xfe, 0x0e, 0x47,
12932 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
12933 0xa7, 0x90, 0x34, 0x60,
12934 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80,
12935 0x09, 0x56, 0xfe, 0x34,
12936 0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48,
12937 0xfe, 0x45, 0x48, 0x01,
12938 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
12939 0x09, 0x1a, 0xa5, 0x0a,
12940 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4,
12941 0xfe, 0x14, 0x56, 0xfe,
12942 0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01,
12943 0xec, 0xb8, 0xfe, 0x9e,
12944 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
12945 0xf4, 0xfe, 0xdd, 0x10,
12946 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48,
12947 0x12, 0x09, 0x0d, 0xfe,
12948 0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4,
12949 0x13, 0x09, 0xfe, 0x23,
12950 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
12951 0x24, 0xfe, 0x12, 0x12,
12952 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08,
12953 0xae, 0x41, 0x02, 0x32,
12954 0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05,
12955 0x35, 0x32, 0x01, 0x43,
12956 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
12957 0x13, 0x01, 0x0c, 0x06,
12958 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe,
12959 0xe5, 0x55, 0xb0, 0xfe,
12960 0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e,
12961 0xfe, 0xb6, 0x0e, 0x10,
12962 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
12963 0x88, 0x20, 0x6e, 0x01,
12964 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5,
12965 0x55, 0xfe, 0x04, 0xfa,
12966 0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d,
12967 0xfe, 0x40, 0x56, 0xfe,
12968 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
12969 0x44, 0x55, 0xfe, 0xe5,
12970 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10,
12971 0x68, 0x22, 0x69, 0x01,
12972 0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b,
12973 0x6b, 0xfe, 0x2c, 0x50,
12974 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
12975 0x50, 0x03, 0x68, 0x3b,
12976 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe,
12977 0x40, 0x50, 0xfe, 0xc2,
12978 0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08,
12979 0x16, 0x3d, 0x27, 0x25,
12980 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
12981 0xa6, 0x23, 0x3f, 0x1b,
12982 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c,
12983 0xfe, 0x0a, 0x55, 0x31,
12984 0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e,
12985 0x51, 0x05, 0x72, 0x01,
12986 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
12987 0x2a, 0x3c, 0x16, 0xc0,
12988 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b,
12989 0xfe, 0x66, 0x15, 0x05,
12990 0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d,
12991 0x2b, 0x3d, 0x01, 0x08,
12992 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
12993 0xb6, 0x1e, 0x83, 0x01,
12994 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46,
12995 0x07, 0x90, 0x3f, 0x01,
12996 0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13,
12997 0x01, 0x43, 0x09, 0x82,
12998 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
12999 0x05, 0x72, 0xfe, 0xc0,
13000 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e,
13001 0x32, 0x01, 0x08, 0x17,
13002 0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16,
13003 0x3d, 0x27, 0x25, 0xbd,
13004 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
13005 0xe8, 0x14, 0x01, 0xa6,
13006 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe,
13007 0x0e, 0x12, 0x01, 0x43,
13008 0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32,
13009 0x01, 0x08, 0x17, 0x73,
13010 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
13011 0x27, 0x25, 0xbd, 0x09,
13012 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe,
13013 0xb6, 0x14, 0x86, 0xa8,
13014 0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09,
13015 0x82, 0x4e, 0x05, 0x72,
13016 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
13017 0xfe, 0xc0, 0x19, 0x05,
13018 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f,
13019 0xcc, 0x01, 0x08, 0x26,
13020 0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe,
13021 0xcc, 0x15, 0x5e, 0x32,
13022 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
13023 0xad, 0x23, 0xfe, 0xff,
13024 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02,
13025 0x00, 0x57, 0x52, 0xad,
13026 0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff,
13027 0x02, 0x00, 0x57, 0x52,
13028 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
13029 0x02, 0x13, 0x58, 0xff,
13030 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01,
13031 0x5c, 0x0a, 0x55, 0x01,
13032 0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a,
13033 0xff, 0x03, 0x00, 0x54,
13034 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
13035 0x7c, 0x3a, 0x0b, 0x0e,
13036 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19,
13037 0xfe, 0x1a, 0xf7, 0x00,
13038 0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c,
13039 0xda, 0x6d, 0x02, 0xfe,
13040 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
13041 0x02, 0x01, 0xc6, 0xfe,
13042 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27,
13043 0x25, 0xbe, 0x01, 0x08,
13044 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59,
13045 0x03, 0x9a, 0x1e, 0xfe,
13046 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
13047 0x48, 0xfe, 0x08, 0x17,
13048 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26,
13049 0x17, 0x4d, 0x13, 0x07,
13050 0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1,
13051 0xff, 0x02, 0x83, 0x55,
13052 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
13053 0x17, 0x1c, 0x63, 0x13,
13054 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64,
13055 0x00, 0xb0, 0xfe, 0x80,
13056 0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10,
13057 0x53, 0x07, 0xfe, 0x60,
13058 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
13059 0x00, 0x1c, 0x95, 0x13,
13060 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3,
13061 0xfe, 0x43, 0xf4, 0x96,
13062 0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43,
13063 0xf4, 0x94, 0xf6, 0x8b,
13064 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
13065 0xda, 0x17, 0x62, 0x49,
13066 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80,
13067 0x71, 0x50, 0x26, 0xfe,
13068 0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3,
13069 0x58, 0x02, 0x50, 0x13,
13070 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
13071 0x25, 0xbe, 0xfe, 0x03,
13072 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9,
13073 0x0a, 0x01, 0x08, 0x16,
13074 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01,
13075 0x01, 0x08, 0x16, 0xa9,
13076 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
13077 0x08, 0x16, 0xa9, 0x27,
13078 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83,
13079 0x01, 0x38, 0x06, 0x24,
13080 0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1,
13081 0x78, 0x03, 0x9a, 0x1e,
13082 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
13083 0xfe, 0x40, 0x5a, 0x23,
13084 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c,
13085 0x80, 0x48, 0xfe, 0xaa,
13086 0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01,
13087 0xfe, 0xac, 0x1d, 0xfe,
13088 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
13089 0x43, 0x48, 0x2d, 0x93,
13090 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4,
13091 0x36, 0xfe, 0x34, 0xf4,
13092 0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe,
13093 0x28, 0x10, 0xfe, 0xc0,
13094 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
13095 0x18, 0x45, 0xfe, 0x1c,
13096 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c,
13097 0x19, 0xfe, 0x04, 0xf4,
13098 0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d,
13099 0x21, 0xfe, 0x7f, 0x01,
13100 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
13101 0x7e, 0x01, 0xfe, 0xc8,
13102 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa,
13103 0x21, 0xfe, 0x81, 0x01,
13104 0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50,
13105 0x13, 0x0d, 0x02, 0x14,
13106 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
13107 0xfe, 0x82, 0x19, 0x14,
13108 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01,
13109 0x08, 0x02, 0x14, 0x07,
13110 0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07,
13111 0x01, 0x08, 0x17, 0xc1,
13112 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
13113 0x08, 0x02, 0x50, 0x02,
13114 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74,
13115 0x14, 0x12, 0x01, 0x08,
13116 0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01,
13117 0x08, 0x17, 0x74, 0xfe,
13118 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
13119 0x74, 0x5f, 0xcc, 0x01,
13120 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4,
13121 0xfe, 0x49, 0xf4, 0x00,
13122 0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff,
13123 0x02, 0x00, 0x10, 0x2f,
13124 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
13125 0x16, 0xfe, 0x64, 0x1a,
13126 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c,
13127 0x61, 0x07, 0x44, 0x02,
13128 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12,
13129 0x13, 0x0a, 0x9d, 0x01,
13130 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
13131 0xfe, 0x80, 0xe7, 0x1a,
13132 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02,
13133 0x0a, 0x5a, 0x01, 0x18,
13134 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe,
13135 0x7e, 0x1e, 0xfe, 0x80,
13136 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
13137 0xfe, 0x80, 0x4c, 0x0a,
13138 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf,
13139 0xfe, 0x19, 0xde, 0xfe,
13140 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe,
13141 0x2a, 0x1c, 0xfa, 0xb3,
13142 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
13143 0xf4, 0x1a, 0xfe, 0xfa,
13144 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24,
13145 0xfe, 0x18, 0x58, 0x03,
13146 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f,
13147 0xfe, 0x30, 0xf4, 0x07,
13148 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
13149 0xf7, 0x24, 0xb1, 0xfe,
13150 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b,
13151 0xfe, 0xba, 0x10, 0x1c,
13152 0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
13153 0x1d, 0xf7, 0x54, 0xb1,
13154 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
13155 0xaf, 0x19, 0xfe, 0x98,
13156 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c,
13157 0x1a, 0x87, 0x8b, 0x0f,
13158 0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58,
13159 0xfe, 0x32, 0x90, 0x04,
13160 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
13161 0x7c, 0x12, 0xfe, 0x0f,
13162 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14,
13163 0x31, 0x02, 0xc9, 0x2b,
13164 0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe,
13165 0x6a, 0xfe, 0x19, 0xfe,
13166 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
13167 0x1b, 0xfe, 0x36, 0x14,
13168 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19,
13169 0xfe, 0x80, 0xe7, 0x1a,
13170 0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a,
13171 0x30, 0xfe, 0x12, 0x45,
13172 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
13173 0x39, 0xf0, 0x75, 0x26,
13174 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03,
13175 0xe3, 0x23, 0x07, 0xfe,
13176 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09,
13177 0x56, 0xfe, 0x3c, 0x13,
13178 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
13179 0x01, 0x18, 0xcb, 0xfe,
13180 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16,
13181 0xfe, 0x00, 0xcc, 0xcb,
13182 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18,
13183 0xfe, 0x80, 0x4c, 0x01,
13184 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
13185 0x12, 0xfe, 0x14, 0x56,
13186 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7,
13187 0x0d, 0x19, 0xfe, 0x15,
13188 0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06,
13189 0x83, 0xfe, 0x18, 0x80,
13190 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
13191 0x90, 0xfe, 0xba, 0x90,
13192 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02,
13193 0x21, 0xb9, 0x88, 0x20,
13194 0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01,
13195 0x18, 0xfe, 0x49, 0x44,
13196 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
13197 0x1a, 0xa4, 0x0a, 0x67,
13198 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4,
13199 0x1d, 0x7b, 0xfe, 0x52,
13200 0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe,
13201 0x4e, 0xe4, 0xdd, 0x7b,
13202 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
13203 0xfe, 0x4e, 0xe4, 0xfe,
13204 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24,
13205 0xfe, 0x08, 0x10, 0x03,
13206 0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04,
13207 0x68, 0x54, 0xfe, 0xf1,
13208 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
13209 0xfe, 0x1a, 0xf4, 0xfe,
13210 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02,
13211 0x09, 0x92, 0xfe, 0x5a,
13212 0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe,
13213 0x5a, 0xf0, 0xfe, 0xc8,
13214 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
13215 0x1a, 0x10, 0x09, 0x0d,
13216 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02,
13217 0x1f, 0x93, 0x01, 0x42,
13218 0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e,
13219 0xfe, 0x14, 0xf0, 0x08,
13220 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
13221 0xfe, 0x82, 0xf0, 0xfe,
13222 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e,
13223 0x02, 0x0f, 0xfe, 0x18,
13224 0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02,
13225 0x80, 0x04, 0xfe, 0x82,
13226 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
13227 0x83, 0x33, 0x0b, 0x0e,
13228 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e,
13229 0x02, 0x0f, 0xfe, 0x04,
13230 0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80,
13231 0x80, 0x04, 0xfe, 0x80,
13232 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
13233 0xfe, 0x99, 0x83, 0xfe,
13234 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86,
13235 0x83, 0xfe, 0xce, 0x47,
13236 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a,
13237 0x0b, 0x0e, 0x02, 0x0f,
13238 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13239 0xfe, 0x08, 0x90, 0x04,
13240 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04,
13241 0xfe, 0x8a, 0x93, 0x79,
13242 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a,
13243 0x0b, 0x0e, 0x02, 0x0f,
13244 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13245 0xfe, 0x3c, 0x90, 0x04,
13246 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80,
13247 0x04, 0xfe, 0x83, 0x83,
13248 0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
13249 };
13250
13251 static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
13252 static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
13253
13254 /* a_init.c */
13255 /*
13256 * EEPROM Configuration.
13257 *
13258 * All drivers should use this structure to set the default EEPROM
13259 * configuration. The BIOS now uses this structure when it is built.
13260 * Additional structure information can be found in a_condor.h where
13261 * the structure is defined.
13262 *
13263 * The *_Field_IsChar structs are needed to correct for endianness.
13264 * These values are read from the board 16 bits at a time directly
13265 * into the structs. Because some fields are char, the values will be
13266 * in the wrong order. The *_Field_IsChar tells when to flip the
13267 * bytes. Data read and written to PCI memory is automatically swapped
13268 * on big-endian platforms so char fields read as words are actually being
13269 * unswapped on big-endian platforms.
13270 */
13271 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
13272 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
13273 0x0000, /* cfg_msw */
13274 0xFFFF, /* disc_enable */
13275 0xFFFF, /* wdtr_able */
13276 0xFFFF, /* sdtr_able */
13277 0xFFFF, /* start_motor */
13278 0xFFFF, /* tagqng_able */
13279 0xFFFF, /* bios_scan */
13280 0, /* scam_tolerant */
13281 7, /* adapter_scsi_id */
13282 0, /* bios_boot_delay */
13283 3, /* scsi_reset_delay */
13284 0, /* bios_id_lun */
13285 0, /* termination */
13286 0, /* reserved1 */
13287 0xFFE7, /* bios_ctrl */
13288 0xFFFF, /* ultra_able */
13289 0, /* reserved2 */
13290 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
13291 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13292 0, /* dvc_cntl */
13293 0, /* bug_fix */
13294 0, /* serial_number_word1 */
13295 0, /* serial_number_word2 */
13296 0, /* serial_number_word3 */
13297 0, /* check_sum */
13298 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13299 , /* oem_name[16] */
13300 0, /* dvc_err_code */
13301 0, /* adv_err_code */
13302 0, /* adv_err_addr */
13303 0, /* saved_dvc_err_code */
13304 0, /* saved_adv_err_code */
13305 0, /* saved_adv_err_addr */
13306 0 /* num_of_err */
13307 };
13308
13309 static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
13310 0, /* cfg_lsw */
13311 0, /* cfg_msw */
13312 0, /* -disc_enable */
13313 0, /* wdtr_able */
13314 0, /* sdtr_able */
13315 0, /* start_motor */
13316 0, /* tagqng_able */
13317 0, /* bios_scan */
13318 0, /* scam_tolerant */
13319 1, /* adapter_scsi_id */
13320 1, /* bios_boot_delay */
13321 1, /* scsi_reset_delay */
13322 1, /* bios_id_lun */
13323 1, /* termination */
13324 1, /* reserved1 */
13325 0, /* bios_ctrl */
13326 0, /* ultra_able */
13327 0, /* reserved2 */
13328 1, /* max_host_qng */
13329 1, /* max_dvc_qng */
13330 0, /* dvc_cntl */
13331 0, /* bug_fix */
13332 0, /* serial_number_word1 */
13333 0, /* serial_number_word2 */
13334 0, /* serial_number_word3 */
13335 0, /* check_sum */
13336 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13337 , /* oem_name[16] */
13338 0, /* dvc_err_code */
13339 0, /* adv_err_code */
13340 0, /* adv_err_addr */
13341 0, /* saved_dvc_err_code */
13342 0, /* saved_adv_err_code */
13343 0, /* saved_adv_err_addr */
13344 0 /* num_of_err */
13345 };
13346
13347 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
13348 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13349 0x0000, /* 01 cfg_msw */
13350 0xFFFF, /* 02 disc_enable */
13351 0xFFFF, /* 03 wdtr_able */
13352 0x4444, /* 04 sdtr_speed1 */
13353 0xFFFF, /* 05 start_motor */
13354 0xFFFF, /* 06 tagqng_able */
13355 0xFFFF, /* 07 bios_scan */
13356 0, /* 08 scam_tolerant */
13357 7, /* 09 adapter_scsi_id */
13358 0, /* bios_boot_delay */
13359 3, /* 10 scsi_reset_delay */
13360 0, /* bios_id_lun */
13361 0, /* 11 termination_se */
13362 0, /* termination_lvd */
13363 0xFFE7, /* 12 bios_ctrl */
13364 0x4444, /* 13 sdtr_speed2 */
13365 0x4444, /* 14 sdtr_speed3 */
13366 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
13367 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13368 0, /* 16 dvc_cntl */
13369 0x4444, /* 17 sdtr_speed4 */
13370 0, /* 18 serial_number_word1 */
13371 0, /* 19 serial_number_word2 */
13372 0, /* 20 serial_number_word3 */
13373 0, /* 21 check_sum */
13374 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13375 , /* 22-29 oem_name[16] */
13376 0, /* 30 dvc_err_code */
13377 0, /* 31 adv_err_code */
13378 0, /* 32 adv_err_addr */
13379 0, /* 33 saved_dvc_err_code */
13380 0, /* 34 saved_adv_err_code */
13381 0, /* 35 saved_adv_err_addr */
13382 0, /* 36 reserved */
13383 0, /* 37 reserved */
13384 0, /* 38 reserved */
13385 0, /* 39 reserved */
13386 0, /* 40 reserved */
13387 0, /* 41 reserved */
13388 0, /* 42 reserved */
13389 0, /* 43 reserved */
13390 0, /* 44 reserved */
13391 0, /* 45 reserved */
13392 0, /* 46 reserved */
13393 0, /* 47 reserved */
13394 0, /* 48 reserved */
13395 0, /* 49 reserved */
13396 0, /* 50 reserved */
13397 0, /* 51 reserved */
13398 0, /* 52 reserved */
13399 0, /* 53 reserved */
13400 0, /* 54 reserved */
13401 0, /* 55 reserved */
13402 0, /* 56 cisptr_lsw */
13403 0, /* 57 cisprt_msw */
13404 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
13405 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
13406 0, /* 60 reserved */
13407 0, /* 61 reserved */
13408 0, /* 62 reserved */
13409 0 /* 63 reserved */
13410 };
13411
13412 static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
13413 0, /* 00 cfg_lsw */
13414 0, /* 01 cfg_msw */
13415 0, /* 02 disc_enable */
13416 0, /* 03 wdtr_able */
13417 0, /* 04 sdtr_speed1 */
13418 0, /* 05 start_motor */
13419 0, /* 06 tagqng_able */
13420 0, /* 07 bios_scan */
13421 0, /* 08 scam_tolerant */
13422 1, /* 09 adapter_scsi_id */
13423 1, /* bios_boot_delay */
13424 1, /* 10 scsi_reset_delay */
13425 1, /* bios_id_lun */
13426 1, /* 11 termination_se */
13427 1, /* termination_lvd */
13428 0, /* 12 bios_ctrl */
13429 0, /* 13 sdtr_speed2 */
13430 0, /* 14 sdtr_speed3 */
13431 1, /* 15 max_host_qng */
13432 1, /* max_dvc_qng */
13433 0, /* 16 dvc_cntl */
13434 0, /* 17 sdtr_speed4 */
13435 0, /* 18 serial_number_word1 */
13436 0, /* 19 serial_number_word2 */
13437 0, /* 20 serial_number_word3 */
13438 0, /* 21 check_sum */
13439 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13440 , /* 22-29 oem_name[16] */
13441 0, /* 30 dvc_err_code */
13442 0, /* 31 adv_err_code */
13443 0, /* 32 adv_err_addr */
13444 0, /* 33 saved_dvc_err_code */
13445 0, /* 34 saved_adv_err_code */
13446 0, /* 35 saved_adv_err_addr */
13447 0, /* 36 reserved */
13448 0, /* 37 reserved */
13449 0, /* 38 reserved */
13450 0, /* 39 reserved */
13451 0, /* 40 reserved */
13452 0, /* 41 reserved */
13453 0, /* 42 reserved */
13454 0, /* 43 reserved */
13455 0, /* 44 reserved */
13456 0, /* 45 reserved */
13457 0, /* 46 reserved */
13458 0, /* 47 reserved */
13459 0, /* 48 reserved */
13460 0, /* 49 reserved */
13461 0, /* 50 reserved */
13462 0, /* 51 reserved */
13463 0, /* 52 reserved */
13464 0, /* 53 reserved */
13465 0, /* 54 reserved */
13466 0, /* 55 reserved */
13467 0, /* 56 cisptr_lsw */
13468 0, /* 57 cisprt_msw */
13469 0, /* 58 subsysvid */
13470 0, /* 59 subsysid */
13471 0, /* 60 reserved */
13472 0, /* 61 reserved */
13473 0, /* 62 reserved */
13474 0 /* 63 reserved */
13475 };
13476
13477 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
13478 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13479 0x0000, /* 01 cfg_msw */
13480 0xFFFF, /* 02 disc_enable */
13481 0xFFFF, /* 03 wdtr_able */
13482 0x5555, /* 04 sdtr_speed1 */
13483 0xFFFF, /* 05 start_motor */
13484 0xFFFF, /* 06 tagqng_able */
13485 0xFFFF, /* 07 bios_scan */
13486 0, /* 08 scam_tolerant */
13487 7, /* 09 adapter_scsi_id */
13488 0, /* bios_boot_delay */
13489 3, /* 10 scsi_reset_delay */
13490 0, /* bios_id_lun */
13491 0, /* 11 termination_se */
13492 0, /* termination_lvd */
13493 0xFFE7, /* 12 bios_ctrl */
13494 0x5555, /* 13 sdtr_speed2 */
13495 0x5555, /* 14 sdtr_speed3 */
13496 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
13497 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13498 0, /* 16 dvc_cntl */
13499 0x5555, /* 17 sdtr_speed4 */
13500 0, /* 18 serial_number_word1 */
13501 0, /* 19 serial_number_word2 */
13502 0, /* 20 serial_number_word3 */
13503 0, /* 21 check_sum */
13504 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13505 , /* 22-29 oem_name[16] */
13506 0, /* 30 dvc_err_code */
13507 0, /* 31 adv_err_code */
13508 0, /* 32 adv_err_addr */
13509 0, /* 33 saved_dvc_err_code */
13510 0, /* 34 saved_adv_err_code */
13511 0, /* 35 saved_adv_err_addr */
13512 0, /* 36 reserved */
13513 0, /* 37 reserved */
13514 0, /* 38 reserved */
13515 0, /* 39 reserved */
13516 0, /* 40 reserved */
13517 0, /* 41 reserved */
13518 0, /* 42 reserved */
13519 0, /* 43 reserved */
13520 0, /* 44 reserved */
13521 0, /* 45 reserved */
13522 0, /* 46 reserved */
13523 0, /* 47 reserved */
13524 0, /* 48 reserved */
13525 0, /* 49 reserved */
13526 0, /* 50 reserved */
13527 0, /* 51 reserved */
13528 0, /* 52 reserved */
13529 0, /* 53 reserved */
13530 0, /* 54 reserved */
13531 0, /* 55 reserved */
13532 0, /* 56 cisptr_lsw */
13533 0, /* 57 cisprt_msw */
13534 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
13535 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
13536 0, /* 60 reserved */
13537 0, /* 61 reserved */
13538 0, /* 62 reserved */
13539 0 /* 63 reserved */
13540 };
13541
13542 static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
13543 0, /* 00 cfg_lsw */
13544 0, /* 01 cfg_msw */
13545 0, /* 02 disc_enable */
13546 0, /* 03 wdtr_able */
13547 0, /* 04 sdtr_speed1 */
13548 0, /* 05 start_motor */
13549 0, /* 06 tagqng_able */
13550 0, /* 07 bios_scan */
13551 0, /* 08 scam_tolerant */
13552 1, /* 09 adapter_scsi_id */
13553 1, /* bios_boot_delay */
13554 1, /* 10 scsi_reset_delay */
13555 1, /* bios_id_lun */
13556 1, /* 11 termination_se */
13557 1, /* termination_lvd */
13558 0, /* 12 bios_ctrl */
13559 0, /* 13 sdtr_speed2 */
13560 0, /* 14 sdtr_speed3 */
13561 1, /* 15 max_host_qng */
13562 1, /* max_dvc_qng */
13563 0, /* 16 dvc_cntl */
13564 0, /* 17 sdtr_speed4 */
13565 0, /* 18 serial_number_word1 */
13566 0, /* 19 serial_number_word2 */
13567 0, /* 20 serial_number_word3 */
13568 0, /* 21 check_sum */
13569 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13570 , /* 22-29 oem_name[16] */
13571 0, /* 30 dvc_err_code */
13572 0, /* 31 adv_err_code */
13573 0, /* 32 adv_err_addr */
13574 0, /* 33 saved_dvc_err_code */
13575 0, /* 34 saved_adv_err_code */
13576 0, /* 35 saved_adv_err_addr */
13577 0, /* 36 reserved */
13578 0, /* 37 reserved */
13579 0, /* 38 reserved */
13580 0, /* 39 reserved */
13581 0, /* 40 reserved */
13582 0, /* 41 reserved */
13583 0, /* 42 reserved */
13584 0, /* 43 reserved */
13585 0, /* 44 reserved */
13586 0, /* 45 reserved */
13587 0, /* 46 reserved */
13588 0, /* 47 reserved */
13589 0, /* 48 reserved */
13590 0, /* 49 reserved */
13591 0, /* 50 reserved */
13592 0, /* 51 reserved */
13593 0, /* 52 reserved */
13594 0, /* 53 reserved */
13595 0, /* 54 reserved */
13596 0, /* 55 reserved */
13597 0, /* 56 cisptr_lsw */
13598 0, /* 57 cisprt_msw */
13599 0, /* 58 subsysvid */
13600 0, /* 59 subsysid */
13601 0, /* 60 reserved */
13602 0, /* 61 reserved */
13603 0, /* 62 reserved */
13604 0 /* 63 reserved */
13605 };
13606
13607 /*
13608 * Initialize the ADV_DVC_VAR structure.
13609 *
13610 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13611 *
13612 * For a non-fatal error return a warning code. If there are no warnings
13613 * then 0 is returned.
13614 */
13615 static int __devinit AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
13616 {
13617 unsigned short warn_code = 0;
13618 AdvPortAddr iop_base = asc_dvc->iop_base;
13619 struct pci_dev *pdev = to_pci_dev(asc_dvc->cfg->dev);
13620 u16 cmd;
13621 int status;
13622
13623 asc_dvc->err_code = 0;
13624
13625 /*
13626 * Save the state of the PCI Configuration Command Register
13627 * "Parity Error Response Control" Bit. If the bit is clear (0),
13628 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
13629 * DMA parity errors.
13630 */
13631 asc_dvc->cfg->control_flag = 0;
13632 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
13633 if ((cmd & PCI_COMMAND_PARITY) == 0)
13634 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
13635
13636 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
13637 ADV_LIB_VERSION_MINOR;
13638 asc_dvc->cfg->chip_version =
13639 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
13640
13641 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
13642 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
13643 (ushort)ADV_CHIP_ID_BYTE);
13644
13645 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
13646 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
13647 (ushort)ADV_CHIP_ID_WORD);
13648
13649 /*
13650 * Reset the chip to start and allow register writes.
13651 */
13652 if (AdvFindSignature(iop_base) == 0) {
13653 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
13654 return ADV_ERROR;
13655 } else {
13656 /*
13657 * The caller must set 'chip_type' to a valid setting.
13658 */
13659 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
13660 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
13661 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
13662 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
13663 return ADV_ERROR;
13664 }
13665
13666 /*
13667 * Reset Chip.
13668 */
13669 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13670 ADV_CTRL_REG_CMD_RESET);
13671 DvcSleepMilliSecond(100);
13672 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13673 ADV_CTRL_REG_CMD_WR_IO_REG);
13674
13675 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13676 status = AdvInitFrom38C1600EEP(asc_dvc);
13677 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13678 status = AdvInitFrom38C0800EEP(asc_dvc);
13679 } else {
13680 status = AdvInitFrom3550EEP(asc_dvc);
13681 }
13682 warn_code |= status;
13683 }
13684
13685 return warn_code;
13686 }
13687
13688 /*
13689 * Initialize the ASC-3550.
13690 *
13691 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13692 *
13693 * For a non-fatal error return a warning code. If there are no warnings
13694 * then 0 is returned.
13695 *
13696 * Needed after initialization for error recovery.
13697 */
13698 static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
13699 {
13700 AdvPortAddr iop_base;
13701 ushort warn_code;
13702 ADV_DCNT sum;
13703 int begin_addr;
13704 int end_addr;
13705 ushort code_sum;
13706 int word;
13707 int j;
13708 int adv_asc3550_expanded_size;
13709 ADV_CARR_T *carrp;
13710 ADV_DCNT contig_len;
13711 ADV_SDCNT buf_size;
13712 ADV_PADDR carr_paddr;
13713 int i;
13714 ushort scsi_cfg1;
13715 uchar tid;
13716 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
13717 ushort wdtr_able = 0, sdtr_able, tagqng_able;
13718 uchar max_cmd[ADV_MAX_TID + 1];
13719
13720 /* If there is already an error, don't continue. */
13721 if (asc_dvc->err_code != 0) {
13722 return ADV_ERROR;
13723 }
13724
13725 /*
13726 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
13727 */
13728 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
13729 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
13730 return ADV_ERROR;
13731 }
13732
13733 warn_code = 0;
13734 iop_base = asc_dvc->iop_base;
13735
13736 /*
13737 * Save the RISC memory BIOS region before writing the microcode.
13738 * The BIOS may already be loaded and using its RISC LRAM region
13739 * so its region must be saved and restored.
13740 *
13741 * Note: This code makes the assumption, which is currently true,
13742 * that a chip reset does not clear RISC LRAM.
13743 */
13744 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
13745 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
13746 bios_mem[i]);
13747 }
13748
13749 /*
13750 * Save current per TID negotiated values.
13751 */
13752 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
13753 ushort bios_version, major, minor;
13754
13755 bios_version =
13756 bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
13757 major = (bios_version >> 12) & 0xF;
13758 minor = (bios_version >> 8) & 0xF;
13759 if (major < 3 || (major == 3 && minor == 1)) {
13760 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
13761 AdvReadWordLram(iop_base, 0x120, wdtr_able);
13762 } else {
13763 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
13764 }
13765 }
13766 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
13767 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
13768 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13769 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
13770 max_cmd[tid]);
13771 }
13772
13773 /*
13774 * Load the Microcode
13775 *
13776 * Write the microcode image to RISC memory starting at address 0.
13777 */
13778 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
13779 /* Assume the following compressed format of the microcode buffer:
13780 *
13781 * 254 word (508 byte) table indexed by byte code followed
13782 * by the following byte codes:
13783 *
13784 * 1-Byte Code:
13785 * 00: Emit word 0 in table.
13786 * 01: Emit word 1 in table.
13787 * .
13788 * FD: Emit word 253 in table.
13789 *
13790 * Multi-Byte Code:
13791 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
13792 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
13793 */
13794 word = 0;
13795 for (i = 253 * 2; i < _adv_asc3550_size; i++) {
13796 if (_adv_asc3550_buf[i] == 0xff) {
13797 for (j = 0; j < _adv_asc3550_buf[i + 1]; j++) {
13798 AdvWriteWordAutoIncLram(iop_base, (((ushort)
13799 _adv_asc3550_buf
13800 [i +
13801 3] << 8) |
13802 _adv_asc3550_buf
13803 [i + 2]));
13804 word++;
13805 }
13806 i += 3;
13807 } else if (_adv_asc3550_buf[i] == 0xfe) {
13808 AdvWriteWordAutoIncLram(iop_base, (((ushort)
13809 _adv_asc3550_buf[i +
13810 2]
13811 << 8) |
13812 _adv_asc3550_buf[i +
13813 1]));
13814 i += 2;
13815 word++;
13816 } else {
13817 AdvWriteWordAutoIncLram(iop_base, (((ushort)
13818 _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) | _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
13819 word++;
13820 }
13821 }
13822
13823 /*
13824 * Set 'word' for later use to clear the rest of memory and save
13825 * the expanded mcode size.
13826 */
13827 word *= 2;
13828 adv_asc3550_expanded_size = word;
13829
13830 /*
13831 * Clear the rest of ASC-3550 Internal RAM (8KB).
13832 */
13833 for (; word < ADV_3550_MEMSIZE; word += 2) {
13834 AdvWriteWordAutoIncLram(iop_base, 0);
13835 }
13836
13837 /*
13838 * Verify the microcode checksum.
13839 */
13840 sum = 0;
13841 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
13842
13843 for (word = 0; word < adv_asc3550_expanded_size; word += 2) {
13844 sum += AdvReadWordAutoIncLram(iop_base);
13845 }
13846
13847 if (sum != _adv_asc3550_chksum) {
13848 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
13849 return ADV_ERROR;
13850 }
13851
13852 /*
13853 * Restore the RISC memory BIOS region.
13854 */
13855 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
13856 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
13857 bios_mem[i]);
13858 }
13859
13860 /*
13861 * Calculate and write the microcode code checksum to the microcode
13862 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
13863 */
13864 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
13865 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
13866 code_sum = 0;
13867 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
13868 for (word = begin_addr; word < end_addr; word += 2) {
13869 code_sum += AdvReadWordAutoIncLram(iop_base);
13870 }
13871 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
13872
13873 /*
13874 * Read and save microcode version and date.
13875 */
13876 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
13877 asc_dvc->cfg->mcode_date);
13878 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
13879 asc_dvc->cfg->mcode_version);
13880
13881 /*
13882 * Set the chip type to indicate the ASC3550.
13883 */
13884 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
13885
13886 /*
13887 * If the PCI Configuration Command Register "Parity Error Response
13888 * Control" Bit was clear (0), then set the microcode variable
13889 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
13890 * to ignore DMA parity errors.
13891 */
13892 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
13893 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
13894 word |= CONTROL_FLAG_IGNORE_PERR;
13895 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
13896 }
13897
13898 /*
13899 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
13900 * threshold of 128 bytes. This register is only accessible to the host.
13901 */
13902 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
13903 START_CTL_EMFU | READ_CMD_MRM);
13904
13905 /*
13906 * Microcode operating variables for WDTR, SDTR, and command tag
13907 * queuing will be set in slave_configure() based on what a
13908 * device reports it is capable of in Inquiry byte 7.
13909 *
13910 * If SCSI Bus Resets have been disabled, then directly set
13911 * SDTR and WDTR from the EEPROM configuration. This will allow
13912 * the BIOS and warm boot to work without a SCSI bus hang on
13913 * the Inquiry caused by host and target mismatched DTR values.
13914 * Without the SCSI Bus Reset, before an Inquiry a device can't
13915 * be assumed to be in Asynchronous, Narrow mode.
13916 */
13917 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
13918 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
13919 asc_dvc->wdtr_able);
13920 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
13921 asc_dvc->sdtr_able);
13922 }
13923
13924 /*
13925 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
13926 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
13927 * bitmask. These values determine the maximum SDTR speed negotiated
13928 * with a device.
13929 *
13930 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
13931 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
13932 * without determining here whether the device supports SDTR.
13933 *
13934 * 4-bit speed SDTR speed name
13935 * =========== ===============
13936 * 0000b (0x0) SDTR disabled
13937 * 0001b (0x1) 5 Mhz
13938 * 0010b (0x2) 10 Mhz
13939 * 0011b (0x3) 20 Mhz (Ultra)
13940 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
13941 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
13942 * 0110b (0x6) Undefined
13943 * .
13944 * 1111b (0xF) Undefined
13945 */
13946 word = 0;
13947 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13948 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
13949 /* Set Ultra speed for TID 'tid'. */
13950 word |= (0x3 << (4 * (tid % 4)));
13951 } else {
13952 /* Set Fast speed for TID 'tid'. */
13953 word |= (0x2 << (4 * (tid % 4)));
13954 }
13955 if (tid == 3) { /* Check if done with sdtr_speed1. */
13956 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
13957 word = 0;
13958 } else if (tid == 7) { /* Check if done with sdtr_speed2. */
13959 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
13960 word = 0;
13961 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
13962 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
13963 word = 0;
13964 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
13965 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
13966 /* End of loop. */
13967 }
13968 }
13969
13970 /*
13971 * Set microcode operating variable for the disconnect per TID bitmask.
13972 */
13973 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
13974 asc_dvc->cfg->disc_enable);
13975
13976 /*
13977 * Set SCSI_CFG0 Microcode Default Value.
13978 *
13979 * The microcode will set the SCSI_CFG0 register using this value
13980 * after it is started below.
13981 */
13982 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
13983 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
13984 asc_dvc->chip_scsi_id);
13985
13986 /*
13987 * Determine SCSI_CFG1 Microcode Default Value.
13988 *
13989 * The microcode will set the SCSI_CFG1 register using this value
13990 * after it is started below.
13991 */
13992
13993 /* Read current SCSI_CFG1 Register value. */
13994 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
13995
13996 /*
13997 * If all three connectors are in use, return an error.
13998 */
13999 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
14000 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
14001 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
14002 return ADV_ERROR;
14003 }
14004
14005 /*
14006 * If the internal narrow cable is reversed all of the SCSI_CTRL
14007 * register signals will be set. Check for and return an error if
14008 * this condition is found.
14009 */
14010 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
14011 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14012 return ADV_ERROR;
14013 }
14014
14015 /*
14016 * If this is a differential board and a single-ended device
14017 * is attached to one of the connectors, return an error.
14018 */
14019 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
14020 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
14021 return ADV_ERROR;
14022 }
14023
14024 /*
14025 * If automatic termination control is enabled, then set the
14026 * termination value based on a table listed in a_condor.h.
14027 *
14028 * If manual termination was specified with an EEPROM setting
14029 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
14030 * is ready to be 'ored' into SCSI_CFG1.
14031 */
14032 if (asc_dvc->cfg->termination == 0) {
14033 /*
14034 * The software always controls termination by setting TERM_CTL_SEL.
14035 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
14036 */
14037 asc_dvc->cfg->termination |= TERM_CTL_SEL;
14038
14039 switch (scsi_cfg1 & CABLE_DETECT) {
14040 /* TERM_CTL_H: on, TERM_CTL_L: on */
14041 case 0x3:
14042 case 0x7:
14043 case 0xB:
14044 case 0xD:
14045 case 0xE:
14046 case 0xF:
14047 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
14048 break;
14049
14050 /* TERM_CTL_H: on, TERM_CTL_L: off */
14051 case 0x1:
14052 case 0x5:
14053 case 0x9:
14054 case 0xA:
14055 case 0xC:
14056 asc_dvc->cfg->termination |= TERM_CTL_H;
14057 break;
14058
14059 /* TERM_CTL_H: off, TERM_CTL_L: off */
14060 case 0x2:
14061 case 0x6:
14062 break;
14063 }
14064 }
14065
14066 /*
14067 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
14068 */
14069 scsi_cfg1 &= ~TERM_CTL;
14070
14071 /*
14072 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
14073 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
14074 * referenced, because the hardware internally inverts
14075 * the Termination High and Low bits if TERM_POL is set.
14076 */
14077 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
14078
14079 /*
14080 * Set SCSI_CFG1 Microcode Default Value
14081 *
14082 * Set filter value and possibly modified termination control
14083 * bits in the Microcode SCSI_CFG1 Register Value.
14084 *
14085 * The microcode will set the SCSI_CFG1 register using this value
14086 * after it is started below.
14087 */
14088 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
14089 FLTR_DISABLE | scsi_cfg1);
14090
14091 /*
14092 * Set MEM_CFG Microcode Default Value
14093 *
14094 * The microcode will set the MEM_CFG register using this value
14095 * after it is started below.
14096 *
14097 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
14098 * are defined.
14099 *
14100 * ASC-3550 has 8KB internal memory.
14101 */
14102 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
14103 BIOS_EN | RAM_SZ_8KB);
14104
14105 /*
14106 * Set SEL_MASK Microcode Default Value
14107 *
14108 * The microcode will set the SEL_MASK register using this value
14109 * after it is started below.
14110 */
14111 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
14112 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
14113
14114 /*
14115 * Build carrier freelist.
14116 *
14117 * Driver must have already allocated memory and set 'carrier_buf'.
14118 */
14119 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
14120
14121 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
14122 asc_dvc->carr_freelist = NULL;
14123 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
14124 buf_size = ADV_CARRIER_BUFSIZE;
14125 } else {
14126 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
14127 }
14128
14129 do {
14130 /*
14131 * Get physical address of the carrier 'carrp'.
14132 */
14133 contig_len = sizeof(ADV_CARR_T);
14134 carr_paddr =
14135 cpu_to_le32(DvcGetPhyAddr
14136 (asc_dvc, NULL, (uchar *)carrp,
14137 (ADV_SDCNT *)&contig_len,
14138 ADV_IS_CARRIER_FLAG));
14139
14140 buf_size -= sizeof(ADV_CARR_T);
14141
14142 /*
14143 * If the current carrier is not physically contiguous, then
14144 * maybe there was a page crossing. Try the next carrier aligned
14145 * start address.
14146 */
14147 if (contig_len < sizeof(ADV_CARR_T)) {
14148 carrp++;
14149 continue;
14150 }
14151
14152 carrp->carr_pa = carr_paddr;
14153 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
14154
14155 /*
14156 * Insert the carrier at the beginning of the freelist.
14157 */
14158 carrp->next_vpa =
14159 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
14160 asc_dvc->carr_freelist = carrp;
14161
14162 carrp++;
14163 }
14164 while (buf_size > 0);
14165
14166 /*
14167 * Set-up the Host->RISC Initiator Command Queue (ICQ).
14168 */
14169
14170 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
14171 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14172 return ADV_ERROR;
14173 }
14174 asc_dvc->carr_freelist = (ADV_CARR_T *)
14175 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
14176
14177 /*
14178 * The first command issued will be placed in the stopper carrier.
14179 */
14180 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14181
14182 /*
14183 * Set RISC ICQ physical address start value.
14184 */
14185 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
14186
14187 /*
14188 * Set-up the RISC->Host Initiator Response Queue (IRQ).
14189 */
14190 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
14191 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14192 return ADV_ERROR;
14193 }
14194 asc_dvc->carr_freelist = (ADV_CARR_T *)
14195 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
14196
14197 /*
14198 * The first command completed by the RISC will be placed in
14199 * the stopper.
14200 *
14201 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
14202 * completed the RISC will set the ASC_RQ_STOPPER bit.
14203 */
14204 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14205
14206 /*
14207 * Set RISC IRQ physical address start value.
14208 */
14209 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
14210 asc_dvc->carr_pending_cnt = 0;
14211
14212 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
14213 (ADV_INTR_ENABLE_HOST_INTR |
14214 ADV_INTR_ENABLE_GLOBAL_INTR));
14215
14216 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
14217 AdvWriteWordRegister(iop_base, IOPW_PC, word);
14218
14219 /* finally, finally, gentlemen, start your engine */
14220 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
14221
14222 /*
14223 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
14224 * Resets should be performed. The RISC has to be running
14225 * to issue a SCSI Bus Reset.
14226 */
14227 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
14228 /*
14229 * If the BIOS Signature is present in memory, restore the
14230 * BIOS Handshake Configuration Table and do not perform
14231 * a SCSI Bus Reset.
14232 */
14233 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
14234 0x55AA) {
14235 /*
14236 * Restore per TID negotiated values.
14237 */
14238 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14239 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14240 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
14241 tagqng_able);
14242 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14243 AdvWriteByteLram(iop_base,
14244 ASC_MC_NUMBER_OF_MAX_CMD + tid,
14245 max_cmd[tid]);
14246 }
14247 } else {
14248 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
14249 warn_code = ASC_WARN_BUSRESET_ERROR;
14250 }
14251 }
14252 }
14253
14254 return warn_code;
14255 }
14256
14257 /*
14258 * Initialize the ASC-38C0800.
14259 *
14260 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14261 *
14262 * For a non-fatal error return a warning code. If there are no warnings
14263 * then 0 is returned.
14264 *
14265 * Needed after initialization for error recovery.
14266 */
14267 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
14268 {
14269 AdvPortAddr iop_base;
14270 ushort warn_code;
14271 ADV_DCNT sum;
14272 int begin_addr;
14273 int end_addr;
14274 ushort code_sum;
14275 int word;
14276 int j;
14277 int adv_asc38C0800_expanded_size;
14278 ADV_CARR_T *carrp;
14279 ADV_DCNT contig_len;
14280 ADV_SDCNT buf_size;
14281 ADV_PADDR carr_paddr;
14282 int i;
14283 ushort scsi_cfg1;
14284 uchar byte;
14285 uchar tid;
14286 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
14287 ushort wdtr_able, sdtr_able, tagqng_able;
14288 uchar max_cmd[ADV_MAX_TID + 1];
14289
14290 /* If there is already an error, don't continue. */
14291 if (asc_dvc->err_code != 0) {
14292 return ADV_ERROR;
14293 }
14294
14295 /*
14296 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
14297 */
14298 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
14299 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
14300 return ADV_ERROR;
14301 }
14302
14303 warn_code = 0;
14304 iop_base = asc_dvc->iop_base;
14305
14306 /*
14307 * Save the RISC memory BIOS region before writing the microcode.
14308 * The BIOS may already be loaded and using its RISC LRAM region
14309 * so its region must be saved and restored.
14310 *
14311 * Note: This code makes the assumption, which is currently true,
14312 * that a chip reset does not clear RISC LRAM.
14313 */
14314 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14315 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14316 bios_mem[i]);
14317 }
14318
14319 /*
14320 * Save current per TID negotiated values.
14321 */
14322 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14323 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14324 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14325 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14326 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14327 max_cmd[tid]);
14328 }
14329
14330 /*
14331 * RAM BIST (RAM Built-In Self Test)
14332 *
14333 * Address : I/O base + offset 0x38h register (byte).
14334 * Function: Bit 7-6(RW) : RAM mode
14335 * Normal Mode : 0x00
14336 * Pre-test Mode : 0x40
14337 * RAM Test Mode : 0x80
14338 * Bit 5 : unused
14339 * Bit 4(RO) : Done bit
14340 * Bit 3-0(RO) : Status
14341 * Host Error : 0x08
14342 * Int_RAM Error : 0x04
14343 * RISC Error : 0x02
14344 * SCSI Error : 0x01
14345 * No Error : 0x00
14346 *
14347 * Note: RAM BIST code should be put right here, before loading the
14348 * microcode and after saving the RISC memory BIOS region.
14349 */
14350
14351 /*
14352 * LRAM Pre-test
14353 *
14354 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
14355 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
14356 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
14357 * to NORMAL_MODE, return an error too.
14358 */
14359 for (i = 0; i < 2; i++) {
14360 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
14361 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14362 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14363 if ((byte & RAM_TEST_DONE) == 0
14364 || (byte & 0x0F) != PRE_TEST_VALUE) {
14365 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14366 return ADV_ERROR;
14367 }
14368
14369 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14370 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14371 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
14372 != NORMAL_VALUE) {
14373 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14374 return ADV_ERROR;
14375 }
14376 }
14377
14378 /*
14379 * LRAM Test - It takes about 1.5 ms to run through the test.
14380 *
14381 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
14382 * If Done bit not set or Status not 0, save register byte, set the
14383 * err_code, and return an error.
14384 */
14385 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
14386 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
14387
14388 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14389 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
14390 /* Get here if Done bit not set or Status not 0. */
14391 asc_dvc->bist_err_code = byte; /* for BIOS display message */
14392 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
14393 return ADV_ERROR;
14394 }
14395
14396 /* We need to reset back to normal mode after LRAM test passes. */
14397 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14398
14399 /*
14400 * Load the Microcode
14401 *
14402 * Write the microcode image to RISC memory starting at address 0.
14403 *
14404 */
14405 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14406
14407 /* Assume the following compressed format of the microcode buffer:
14408 *
14409 * 254 word (508 byte) table indexed by byte code followed
14410 * by the following byte codes:
14411 *
14412 * 1-Byte Code:
14413 * 00: Emit word 0 in table.
14414 * 01: Emit word 1 in table.
14415 * .
14416 * FD: Emit word 253 in table.
14417 *
14418 * Multi-Byte Code:
14419 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14420 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14421 */
14422 word = 0;
14423 for (i = 253 * 2; i < _adv_asc38C0800_size; i++) {
14424 if (_adv_asc38C0800_buf[i] == 0xff) {
14425 for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++) {
14426 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14427 _adv_asc38C0800_buf
14428 [i +
14429 3] << 8) |
14430 _adv_asc38C0800_buf
14431 [i + 2]));
14432 word++;
14433 }
14434 i += 3;
14435 } else if (_adv_asc38C0800_buf[i] == 0xfe) {
14436 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14437 _adv_asc38C0800_buf
14438 [i +
14439 2] << 8) |
14440 _adv_asc38C0800_buf[i
14441 +
14442 1]));
14443 i += 2;
14444 word++;
14445 } else {
14446 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14447 _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) | _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
14448 word++;
14449 }
14450 }
14451
14452 /*
14453 * Set 'word' for later use to clear the rest of memory and save
14454 * the expanded mcode size.
14455 */
14456 word *= 2;
14457 adv_asc38C0800_expanded_size = word;
14458
14459 /*
14460 * Clear the rest of ASC-38C0800 Internal RAM (16KB).
14461 */
14462 for (; word < ADV_38C0800_MEMSIZE; word += 2) {
14463 AdvWriteWordAutoIncLram(iop_base, 0);
14464 }
14465
14466 /*
14467 * Verify the microcode checksum.
14468 */
14469 sum = 0;
14470 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14471
14472 for (word = 0; word < adv_asc38C0800_expanded_size; word += 2) {
14473 sum += AdvReadWordAutoIncLram(iop_base);
14474 }
14475 ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
14476
14477 ASC_DBG2(1,
14478 "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
14479 (ulong)sum, (ulong)_adv_asc38C0800_chksum);
14480
14481 if (sum != _adv_asc38C0800_chksum) {
14482 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14483 return ADV_ERROR;
14484 }
14485
14486 /*
14487 * Restore the RISC memory BIOS region.
14488 */
14489 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14490 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14491 bios_mem[i]);
14492 }
14493
14494 /*
14495 * Calculate and write the microcode code checksum to the microcode
14496 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14497 */
14498 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14499 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14500 code_sum = 0;
14501 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14502 for (word = begin_addr; word < end_addr; word += 2) {
14503 code_sum += AdvReadWordAutoIncLram(iop_base);
14504 }
14505 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14506
14507 /*
14508 * Read microcode version and date.
14509 */
14510 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
14511 asc_dvc->cfg->mcode_date);
14512 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
14513 asc_dvc->cfg->mcode_version);
14514
14515 /*
14516 * Set the chip type to indicate the ASC38C0800.
14517 */
14518 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
14519
14520 /*
14521 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
14522 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
14523 * cable detection and then we are able to read C_DET[3:0].
14524 *
14525 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
14526 * Microcode Default Value' section below.
14527 */
14528 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14529 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
14530 scsi_cfg1 | DIS_TERM_DRV);
14531
14532 /*
14533 * If the PCI Configuration Command Register "Parity Error Response
14534 * Control" Bit was clear (0), then set the microcode variable
14535 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14536 * to ignore DMA parity errors.
14537 */
14538 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
14539 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14540 word |= CONTROL_FLAG_IGNORE_PERR;
14541 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14542 }
14543
14544 /*
14545 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
14546 * bits for the default FIFO threshold.
14547 *
14548 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
14549 *
14550 * For DMA Errata #4 set the BC_THRESH_ENB bit.
14551 */
14552 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14553 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
14554 READ_CMD_MRM);
14555
14556 /*
14557 * Microcode operating variables for WDTR, SDTR, and command tag
14558 * queuing will be set in slave_configure() based on what a
14559 * device reports it is capable of in Inquiry byte 7.
14560 *
14561 * If SCSI Bus Resets have been disabled, then directly set
14562 * SDTR and WDTR from the EEPROM configuration. This will allow
14563 * the BIOS and warm boot to work without a SCSI bus hang on
14564 * the Inquiry caused by host and target mismatched DTR values.
14565 * Without the SCSI Bus Reset, before an Inquiry a device can't
14566 * be assumed to be in Asynchronous, Narrow mode.
14567 */
14568 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
14569 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
14570 asc_dvc->wdtr_able);
14571 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
14572 asc_dvc->sdtr_able);
14573 }
14574
14575 /*
14576 * Set microcode operating variables for DISC and SDTR_SPEED1,
14577 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
14578 * configuration values.
14579 *
14580 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14581 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14582 * without determining here whether the device supports SDTR.
14583 */
14584 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
14585 asc_dvc->cfg->disc_enable);
14586 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
14587 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
14588 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
14589 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
14590
14591 /*
14592 * Set SCSI_CFG0 Microcode Default Value.
14593 *
14594 * The microcode will set the SCSI_CFG0 register using this value
14595 * after it is started below.
14596 */
14597 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14598 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14599 asc_dvc->chip_scsi_id);
14600
14601 /*
14602 * Determine SCSI_CFG1 Microcode Default Value.
14603 *
14604 * The microcode will set the SCSI_CFG1 register using this value
14605 * after it is started below.
14606 */
14607
14608 /* Read current SCSI_CFG1 Register value. */
14609 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14610
14611 /*
14612 * If the internal narrow cable is reversed all of the SCSI_CTRL
14613 * register signals will be set. Check for and return an error if
14614 * this condition is found.
14615 */
14616 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
14617 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14618 return ADV_ERROR;
14619 }
14620
14621 /*
14622 * All kind of combinations of devices attached to one of four connectors
14623 * are acceptable except HVD device attached. For example, LVD device can
14624 * be attached to SE connector while SE device attached to LVD connector.
14625 * If LVD device attached to SE connector, it only runs up to Ultra speed.
14626 *
14627 * If an HVD device is attached to one of LVD connectors, return an error.
14628 * However, there is no way to detect HVD device attached to SE connectors.
14629 */
14630 if (scsi_cfg1 & HVD) {
14631 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
14632 return ADV_ERROR;
14633 }
14634
14635 /*
14636 * If either SE or LVD automatic termination control is enabled, then
14637 * set the termination value based on a table listed in a_condor.h.
14638 *
14639 * If manual termination was specified with an EEPROM setting then
14640 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
14641 * be 'ored' into SCSI_CFG1.
14642 */
14643 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
14644 /* SE automatic termination control is enabled. */
14645 switch (scsi_cfg1 & C_DET_SE) {
14646 /* TERM_SE_HI: on, TERM_SE_LO: on */
14647 case 0x1:
14648 case 0x2:
14649 case 0x3:
14650 asc_dvc->cfg->termination |= TERM_SE;
14651 break;
14652
14653 /* TERM_SE_HI: on, TERM_SE_LO: off */
14654 case 0x0:
14655 asc_dvc->cfg->termination |= TERM_SE_HI;
14656 break;
14657 }
14658 }
14659
14660 if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
14661 /* LVD automatic termination control is enabled. */
14662 switch (scsi_cfg1 & C_DET_LVD) {
14663 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
14664 case 0x4:
14665 case 0x8:
14666 case 0xC:
14667 asc_dvc->cfg->termination |= TERM_LVD;
14668 break;
14669
14670 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
14671 case 0x0:
14672 break;
14673 }
14674 }
14675
14676 /*
14677 * Clear any set TERM_SE and TERM_LVD bits.
14678 */
14679 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
14680
14681 /*
14682 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
14683 */
14684 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
14685
14686 /*
14687 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
14688 * and set possibly modified termination control bits in the Microcode
14689 * SCSI_CFG1 Register Value.
14690 */
14691 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
14692
14693 /*
14694 * Set SCSI_CFG1 Microcode Default Value
14695 *
14696 * Set possibly modified termination control and reset DIS_TERM_DRV
14697 * bits in the Microcode SCSI_CFG1 Register Value.
14698 *
14699 * The microcode will set the SCSI_CFG1 register using this value
14700 * after it is started below.
14701 */
14702 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
14703
14704 /*
14705 * Set MEM_CFG Microcode Default Value
14706 *
14707 * The microcode will set the MEM_CFG register using this value
14708 * after it is started below.
14709 *
14710 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
14711 * are defined.
14712 *
14713 * ASC-38C0800 has 16KB internal memory.
14714 */
14715 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
14716 BIOS_EN | RAM_SZ_16KB);
14717
14718 /*
14719 * Set SEL_MASK Microcode Default Value
14720 *
14721 * The microcode will set the SEL_MASK register using this value
14722 * after it is started below.
14723 */
14724 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
14725 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
14726
14727 /*
14728 * Build the carrier freelist.
14729 *
14730 * Driver must have already allocated memory and set 'carrier_buf'.
14731 */
14732 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
14733
14734 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
14735 asc_dvc->carr_freelist = NULL;
14736 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
14737 buf_size = ADV_CARRIER_BUFSIZE;
14738 } else {
14739 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
14740 }
14741
14742 do {
14743 /*
14744 * Get physical address for the carrier 'carrp'.
14745 */
14746 contig_len = sizeof(ADV_CARR_T);
14747 carr_paddr =
14748 cpu_to_le32(DvcGetPhyAddr
14749 (asc_dvc, NULL, (uchar *)carrp,
14750 (ADV_SDCNT *)&contig_len,
14751 ADV_IS_CARRIER_FLAG));
14752
14753 buf_size -= sizeof(ADV_CARR_T);
14754
14755 /*
14756 * If the current carrier is not physically contiguous, then
14757 * maybe there was a page crossing. Try the next carrier aligned
14758 * start address.
14759 */
14760 if (contig_len < sizeof(ADV_CARR_T)) {
14761 carrp++;
14762 continue;
14763 }
14764
14765 carrp->carr_pa = carr_paddr;
14766 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
14767
14768 /*
14769 * Insert the carrier at the beginning of the freelist.
14770 */
14771 carrp->next_vpa =
14772 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
14773 asc_dvc->carr_freelist = carrp;
14774
14775 carrp++;
14776 }
14777 while (buf_size > 0);
14778
14779 /*
14780 * Set-up the Host->RISC Initiator Command Queue (ICQ).
14781 */
14782
14783 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
14784 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14785 return ADV_ERROR;
14786 }
14787 asc_dvc->carr_freelist = (ADV_CARR_T *)
14788 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
14789
14790 /*
14791 * The first command issued will be placed in the stopper carrier.
14792 */
14793 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14794
14795 /*
14796 * Set RISC ICQ physical address start value.
14797 * carr_pa is LE, must be native before write
14798 */
14799 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
14800
14801 /*
14802 * Set-up the RISC->Host Initiator Response Queue (IRQ).
14803 */
14804 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
14805 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14806 return ADV_ERROR;
14807 }
14808 asc_dvc->carr_freelist = (ADV_CARR_T *)
14809 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
14810
14811 /*
14812 * The first command completed by the RISC will be placed in
14813 * the stopper.
14814 *
14815 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
14816 * completed the RISC will set the ASC_RQ_STOPPER bit.
14817 */
14818 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14819
14820 /*
14821 * Set RISC IRQ physical address start value.
14822 *
14823 * carr_pa is LE, must be native before write *
14824 */
14825 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
14826 asc_dvc->carr_pending_cnt = 0;
14827
14828 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
14829 (ADV_INTR_ENABLE_HOST_INTR |
14830 ADV_INTR_ENABLE_GLOBAL_INTR));
14831
14832 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
14833 AdvWriteWordRegister(iop_base, IOPW_PC, word);
14834
14835 /* finally, finally, gentlemen, start your engine */
14836 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
14837
14838 /*
14839 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
14840 * Resets should be performed. The RISC has to be running
14841 * to issue a SCSI Bus Reset.
14842 */
14843 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
14844 /*
14845 * If the BIOS Signature is present in memory, restore the
14846 * BIOS Handshake Configuration Table and do not perform
14847 * a SCSI Bus Reset.
14848 */
14849 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
14850 0x55AA) {
14851 /*
14852 * Restore per TID negotiated values.
14853 */
14854 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14855 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14856 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
14857 tagqng_able);
14858 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14859 AdvWriteByteLram(iop_base,
14860 ASC_MC_NUMBER_OF_MAX_CMD + tid,
14861 max_cmd[tid]);
14862 }
14863 } else {
14864 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
14865 warn_code = ASC_WARN_BUSRESET_ERROR;
14866 }
14867 }
14868 }
14869
14870 return warn_code;
14871 }
14872
14873 /*
14874 * Initialize the ASC-38C1600.
14875 *
14876 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
14877 *
14878 * For a non-fatal error return a warning code. If there are no warnings
14879 * then 0 is returned.
14880 *
14881 * Needed after initialization for error recovery.
14882 */
14883 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
14884 {
14885 AdvPortAddr iop_base;
14886 ushort warn_code;
14887 ADV_DCNT sum;
14888 int begin_addr;
14889 int end_addr;
14890 ushort code_sum;
14891 long word;
14892 int j;
14893 int adv_asc38C1600_expanded_size;
14894 ADV_CARR_T *carrp;
14895 ADV_DCNT contig_len;
14896 ADV_SDCNT buf_size;
14897 ADV_PADDR carr_paddr;
14898 int i;
14899 ushort scsi_cfg1;
14900 uchar byte;
14901 uchar tid;
14902 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
14903 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
14904 uchar max_cmd[ASC_MAX_TID + 1];
14905
14906 /* If there is already an error, don't continue. */
14907 if (asc_dvc->err_code != 0) {
14908 return ADV_ERROR;
14909 }
14910
14911 /*
14912 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
14913 */
14914 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
14915 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
14916 return ADV_ERROR;
14917 }
14918
14919 warn_code = 0;
14920 iop_base = asc_dvc->iop_base;
14921
14922 /*
14923 * Save the RISC memory BIOS region before writing the microcode.
14924 * The BIOS may already be loaded and using its RISC LRAM region
14925 * so its region must be saved and restored.
14926 *
14927 * Note: This code makes the assumption, which is currently true,
14928 * that a chip reset does not clear RISC LRAM.
14929 */
14930 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14931 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14932 bios_mem[i]);
14933 }
14934
14935 /*
14936 * Save current per TID negotiated values.
14937 */
14938 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14939 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14940 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
14941 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14942 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
14943 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14944 max_cmd[tid]);
14945 }
14946
14947 /*
14948 * RAM BIST (Built-In Self Test)
14949 *
14950 * Address : I/O base + offset 0x38h register (byte).
14951 * Function: Bit 7-6(RW) : RAM mode
14952 * Normal Mode : 0x00
14953 * Pre-test Mode : 0x40
14954 * RAM Test Mode : 0x80
14955 * Bit 5 : unused
14956 * Bit 4(RO) : Done bit
14957 * Bit 3-0(RO) : Status
14958 * Host Error : 0x08
14959 * Int_RAM Error : 0x04
14960 * RISC Error : 0x02
14961 * SCSI Error : 0x01
14962 * No Error : 0x00
14963 *
14964 * Note: RAM BIST code should be put right here, before loading the
14965 * microcode and after saving the RISC memory BIOS region.
14966 */
14967
14968 /*
14969 * LRAM Pre-test
14970 *
14971 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
14972 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
14973 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
14974 * to NORMAL_MODE, return an error too.
14975 */
14976 for (i = 0; i < 2; i++) {
14977 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
14978 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14979 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14980 if ((byte & RAM_TEST_DONE) == 0
14981 || (byte & 0x0F) != PRE_TEST_VALUE) {
14982 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14983 return ADV_ERROR;
14984 }
14985
14986 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14987 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14988 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
14989 != NORMAL_VALUE) {
14990 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14991 return ADV_ERROR;
14992 }
14993 }
14994
14995 /*
14996 * LRAM Test - It takes about 1.5 ms to run through the test.
14997 *
14998 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
14999 * If Done bit not set or Status not 0, save register byte, set the
15000 * err_code, and return an error.
15001 */
15002 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15003 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
15004
15005 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15006 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
15007 /* Get here if Done bit not set or Status not 0. */
15008 asc_dvc->bist_err_code = byte; /* for BIOS display message */
15009 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15010 return ADV_ERROR;
15011 }
15012
15013 /* We need to reset back to normal mode after LRAM test passes. */
15014 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15015
15016 /*
15017 * Load the Microcode
15018 *
15019 * Write the microcode image to RISC memory starting at address 0.
15020 *
15021 */
15022 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15023
15024 /*
15025 * Assume the following compressed format of the microcode buffer:
15026 *
15027 * 254 word (508 byte) table indexed by byte code followed
15028 * by the following byte codes:
15029 *
15030 * 1-Byte Code:
15031 * 00: Emit word 0 in table.
15032 * 01: Emit word 1 in table.
15033 * .
15034 * FD: Emit word 253 in table.
15035 *
15036 * Multi-Byte Code:
15037 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15038 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15039 */
15040 word = 0;
15041 for (i = 253 * 2; i < _adv_asc38C1600_size; i++) {
15042 if (_adv_asc38C1600_buf[i] == 0xff) {
15043 for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++) {
15044 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15045 _adv_asc38C1600_buf
15046 [i +
15047 3] << 8) |
15048 _adv_asc38C1600_buf
15049 [i + 2]));
15050 word++;
15051 }
15052 i += 3;
15053 } else if (_adv_asc38C1600_buf[i] == 0xfe) {
15054 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15055 _adv_asc38C1600_buf
15056 [i +
15057 2] << 8) |
15058 _adv_asc38C1600_buf[i
15059 +
15060 1]));
15061 i += 2;
15062 word++;
15063 } else {
15064 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15065 _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) | _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
15066 word++;
15067 }
15068 }
15069
15070 /*
15071 * Set 'word' for later use to clear the rest of memory and save
15072 * the expanded mcode size.
15073 */
15074 word *= 2;
15075 adv_asc38C1600_expanded_size = word;
15076
15077 /*
15078 * Clear the rest of ASC-38C1600 Internal RAM (32KB).
15079 */
15080 for (; word < ADV_38C1600_MEMSIZE; word += 2) {
15081 AdvWriteWordAutoIncLram(iop_base, 0);
15082 }
15083
15084 /*
15085 * Verify the microcode checksum.
15086 */
15087 sum = 0;
15088 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15089
15090 for (word = 0; word < adv_asc38C1600_expanded_size; word += 2) {
15091 sum += AdvReadWordAutoIncLram(iop_base);
15092 }
15093
15094 if (sum != _adv_asc38C1600_chksum) {
15095 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15096 return ADV_ERROR;
15097 }
15098
15099 /*
15100 * Restore the RISC memory BIOS region.
15101 */
15102 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15103 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15104 bios_mem[i]);
15105 }
15106
15107 /*
15108 * Calculate and write the microcode code checksum to the microcode
15109 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15110 */
15111 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15112 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15113 code_sum = 0;
15114 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15115 for (word = begin_addr; word < end_addr; word += 2) {
15116 code_sum += AdvReadWordAutoIncLram(iop_base);
15117 }
15118 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15119
15120 /*
15121 * Read microcode version and date.
15122 */
15123 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
15124 asc_dvc->cfg->mcode_date);
15125 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
15126 asc_dvc->cfg->mcode_version);
15127
15128 /*
15129 * Set the chip type to indicate the ASC38C1600.
15130 */
15131 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
15132
15133 /*
15134 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15135 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15136 * cable detection and then we are able to read C_DET[3:0].
15137 *
15138 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15139 * Microcode Default Value' section below.
15140 */
15141 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15142 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
15143 scsi_cfg1 | DIS_TERM_DRV);
15144
15145 /*
15146 * If the PCI Configuration Command Register "Parity Error Response
15147 * Control" Bit was clear (0), then set the microcode variable
15148 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15149 * to ignore DMA parity errors.
15150 */
15151 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
15152 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15153 word |= CONTROL_FLAG_IGNORE_PERR;
15154 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15155 }
15156
15157 /*
15158 * If the BIOS control flag AIPP (Asynchronous Information
15159 * Phase Protection) disable bit is not set, then set the firmware
15160 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
15161 * AIPP checking and encoding.
15162 */
15163 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
15164 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15165 word |= CONTROL_FLAG_ENABLE_AIPP;
15166 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15167 }
15168
15169 /*
15170 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
15171 * and START_CTL_TH [3:2].
15172 */
15173 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15174 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
15175
15176 /*
15177 * Microcode operating variables for WDTR, SDTR, and command tag
15178 * queuing will be set in slave_configure() based on what a
15179 * device reports it is capable of in Inquiry byte 7.
15180 *
15181 * If SCSI Bus Resets have been disabled, then directly set
15182 * SDTR and WDTR from the EEPROM configuration. This will allow
15183 * the BIOS and warm boot to work without a SCSI bus hang on
15184 * the Inquiry caused by host and target mismatched DTR values.
15185 * Without the SCSI Bus Reset, before an Inquiry a device can't
15186 * be assumed to be in Asynchronous, Narrow mode.
15187 */
15188 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
15189 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
15190 asc_dvc->wdtr_able);
15191 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
15192 asc_dvc->sdtr_able);
15193 }
15194
15195 /*
15196 * Set microcode operating variables for DISC and SDTR_SPEED1,
15197 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15198 * configuration values.
15199 *
15200 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15201 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15202 * without determining here whether the device supports SDTR.
15203 */
15204 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
15205 asc_dvc->cfg->disc_enable);
15206 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15207 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15208 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15209 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15210
15211 /*
15212 * Set SCSI_CFG0 Microcode Default Value.
15213 *
15214 * The microcode will set the SCSI_CFG0 register using this value
15215 * after it is started below.
15216 */
15217 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15218 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15219 asc_dvc->chip_scsi_id);
15220
15221 /*
15222 * Calculate SCSI_CFG1 Microcode Default Value.
15223 *
15224 * The microcode will set the SCSI_CFG1 register using this value
15225 * after it is started below.
15226 *
15227 * Each ASC-38C1600 function has only two cable detect bits.
15228 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
15229 */
15230 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15231
15232 /*
15233 * If the cable is reversed all of the SCSI_CTRL register signals
15234 * will be set. Check for and return an error if this condition is
15235 * found.
15236 */
15237 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
15238 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15239 return ADV_ERROR;
15240 }
15241
15242 /*
15243 * Each ASC-38C1600 function has two connectors. Only an HVD device
15244 * can not be connected to either connector. An LVD device or SE device
15245 * may be connected to either connecor. If an SE device is connected,
15246 * then at most Ultra speed (20 Mhz) can be used on both connectors.
15247 *
15248 * If an HVD device is attached, return an error.
15249 */
15250 if (scsi_cfg1 & HVD) {
15251 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15252 return ADV_ERROR;
15253 }
15254
15255 /*
15256 * Each function in the ASC-38C1600 uses only the SE cable detect and
15257 * termination because there are two connectors for each function. Each
15258 * function may use either LVD or SE mode. Corresponding the SE automatic
15259 * termination control EEPROM bits are used for each function. Each
15260 * function has its own EEPROM. If SE automatic control is enabled for
15261 * the function, then set the termination value based on a table listed
15262 * in a_condor.h.
15263 *
15264 * If manual termination is specified in the EEPROM for the function,
15265 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
15266 * ready to be 'ored' into SCSI_CFG1.
15267 */
15268 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
15269 /* SE automatic termination control is enabled. */
15270 switch (scsi_cfg1 & C_DET_SE) {
15271 /* TERM_SE_HI: on, TERM_SE_LO: on */
15272 case 0x1:
15273 case 0x2:
15274 case 0x3:
15275 asc_dvc->cfg->termination |= TERM_SE;
15276 break;
15277
15278 case 0x0:
15279 if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0) {
15280 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
15281 } else {
15282 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
15283 asc_dvc->cfg->termination |= TERM_SE_HI;
15284 }
15285 break;
15286 }
15287 }
15288
15289 /*
15290 * Clear any set TERM_SE bits.
15291 */
15292 scsi_cfg1 &= ~TERM_SE;
15293
15294 /*
15295 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
15296 */
15297 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
15298
15299 /*
15300 * Clear Big Endian and Terminator Polarity bits and set possibly
15301 * modified termination control bits in the Microcode SCSI_CFG1
15302 * Register Value.
15303 *
15304 * Big Endian bit is not used even on big endian machines.
15305 */
15306 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
15307
15308 /*
15309 * Set SCSI_CFG1 Microcode Default Value
15310 *
15311 * Set possibly modified termination control bits in the Microcode
15312 * SCSI_CFG1 Register Value.
15313 *
15314 * The microcode will set the SCSI_CFG1 register using this value
15315 * after it is started below.
15316 */
15317 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15318
15319 /*
15320 * Set MEM_CFG Microcode Default Value
15321 *
15322 * The microcode will set the MEM_CFG register using this value
15323 * after it is started below.
15324 *
15325 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15326 * are defined.
15327 *
15328 * ASC-38C1600 has 32KB internal memory.
15329 *
15330 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
15331 * out a special 16K Adv Library and Microcode version. After the issue
15332 * resolved, we should turn back to the 32K support. Both a_condor.h and
15333 * mcode.sas files also need to be updated.
15334 *
15335 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15336 * BIOS_EN | RAM_SZ_32KB);
15337 */
15338 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15339 BIOS_EN | RAM_SZ_16KB);
15340
15341 /*
15342 * Set SEL_MASK Microcode Default Value
15343 *
15344 * The microcode will set the SEL_MASK register using this value
15345 * after it is started below.
15346 */
15347 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15348 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15349
15350 /*
15351 * Build the carrier freelist.
15352 *
15353 * Driver must have already allocated memory and set 'carrier_buf'.
15354 */
15355
15356 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15357
15358 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15359 asc_dvc->carr_freelist = NULL;
15360 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
15361 buf_size = ADV_CARRIER_BUFSIZE;
15362 } else {
15363 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15364 }
15365
15366 do {
15367 /*
15368 * Get physical address for the carrier 'carrp'.
15369 */
15370 contig_len = sizeof(ADV_CARR_T);
15371 carr_paddr =
15372 cpu_to_le32(DvcGetPhyAddr
15373 (asc_dvc, NULL, (uchar *)carrp,
15374 (ADV_SDCNT *)&contig_len,
15375 ADV_IS_CARRIER_FLAG));
15376
15377 buf_size -= sizeof(ADV_CARR_T);
15378
15379 /*
15380 * If the current carrier is not physically contiguous, then
15381 * maybe there was a page crossing. Try the next carrier aligned
15382 * start address.
15383 */
15384 if (contig_len < sizeof(ADV_CARR_T)) {
15385 carrp++;
15386 continue;
15387 }
15388
15389 carrp->carr_pa = carr_paddr;
15390 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15391
15392 /*
15393 * Insert the carrier at the beginning of the freelist.
15394 */
15395 carrp->next_vpa =
15396 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15397 asc_dvc->carr_freelist = carrp;
15398
15399 carrp++;
15400 }
15401 while (buf_size > 0);
15402
15403 /*
15404 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15405 */
15406 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
15407 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15408 return ADV_ERROR;
15409 }
15410 asc_dvc->carr_freelist = (ADV_CARR_T *)
15411 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15412
15413 /*
15414 * The first command issued will be placed in the stopper carrier.
15415 */
15416 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15417
15418 /*
15419 * Set RISC ICQ physical address start value. Initialize the
15420 * COMMA register to the same value otherwise the RISC will
15421 * prematurely detect a command is available.
15422 */
15423 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15424 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
15425 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
15426
15427 /*
15428 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15429 */
15430 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
15431 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15432 return ADV_ERROR;
15433 }
15434 asc_dvc->carr_freelist = (ADV_CARR_T *)
15435 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15436
15437 /*
15438 * The first command completed by the RISC will be placed in
15439 * the stopper.
15440 *
15441 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15442 * completed the RISC will set the ASC_RQ_STOPPER bit.
15443 */
15444 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15445
15446 /*
15447 * Set RISC IRQ physical address start value.
15448 */
15449 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15450 asc_dvc->carr_pending_cnt = 0;
15451
15452 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15453 (ADV_INTR_ENABLE_HOST_INTR |
15454 ADV_INTR_ENABLE_GLOBAL_INTR));
15455 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15456 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15457
15458 /* finally, finally, gentlemen, start your engine */
15459 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15460
15461 /*
15462 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15463 * Resets should be performed. The RISC has to be running
15464 * to issue a SCSI Bus Reset.
15465 */
15466 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
15467 /*
15468 * If the BIOS Signature is present in memory, restore the
15469 * per TID microcode operating variables.
15470 */
15471 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
15472 0x55AA) {
15473 /*
15474 * Restore per TID negotiated values.
15475 */
15476 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15477 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15478 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15479 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
15480 tagqng_able);
15481 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15482 AdvWriteByteLram(iop_base,
15483 ASC_MC_NUMBER_OF_MAX_CMD + tid,
15484 max_cmd[tid]);
15485 }
15486 } else {
15487 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
15488 warn_code = ASC_WARN_BUSRESET_ERROR;
15489 }
15490 }
15491 }
15492
15493 return warn_code;
15494 }
15495
15496 /*
15497 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
15498 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
15499 * all of this is done.
15500 *
15501 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15502 *
15503 * For a non-fatal error return a warning code. If there are no warnings
15504 * then 0 is returned.
15505 *
15506 * Note: Chip is stopped on entry.
15507 */
15508 static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
15509 {
15510 AdvPortAddr iop_base;
15511 ushort warn_code;
15512 ADVEEP_3550_CONFIG eep_config;
15513 int i;
15514
15515 iop_base = asc_dvc->iop_base;
15516
15517 warn_code = 0;
15518
15519 /*
15520 * Read the board's EEPROM configuration.
15521 *
15522 * Set default values if a bad checksum is found.
15523 */
15524 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
15525 warn_code |= ASC_WARN_EEPROM_CHKSUM;
15526
15527 /*
15528 * Set EEPROM default values.
15529 */
15530 for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++) {
15531 *((uchar *)&eep_config + i) =
15532 *((uchar *)&Default_3550_EEPROM_Config + i);
15533 }
15534
15535 /*
15536 * Assume the 6 byte board serial number that was read
15537 * from EEPROM is correct even if the EEPROM checksum
15538 * failed.
15539 */
15540 eep_config.serial_number_word3 =
15541 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
15542
15543 eep_config.serial_number_word2 =
15544 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
15545
15546 eep_config.serial_number_word1 =
15547 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
15548
15549 AdvSet3550EEPConfig(iop_base, &eep_config);
15550 }
15551 /*
15552 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
15553 * EEPROM configuration that was read.
15554 *
15555 * This is the mapping of EEPROM fields to Adv Library fields.
15556 */
15557 asc_dvc->wdtr_able = eep_config.wdtr_able;
15558 asc_dvc->sdtr_able = eep_config.sdtr_able;
15559 asc_dvc->ultra_able = eep_config.ultra_able;
15560 asc_dvc->tagqng_able = eep_config.tagqng_able;
15561 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
15562 asc_dvc->max_host_qng = eep_config.max_host_qng;
15563 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15564 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
15565 asc_dvc->start_motor = eep_config.start_motor;
15566 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
15567 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
15568 asc_dvc->no_scam = eep_config.scam_tolerant;
15569 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
15570 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
15571 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
15572
15573 /*
15574 * Set the host maximum queuing (max. 253, min. 16) and the per device
15575 * maximum queuing (max. 63, min. 4).
15576 */
15577 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
15578 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15579 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
15580 /* If the value is zero, assume it is uninitialized. */
15581 if (eep_config.max_host_qng == 0) {
15582 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15583 } else {
15584 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
15585 }
15586 }
15587
15588 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
15589 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15590 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
15591 /* If the value is zero, assume it is uninitialized. */
15592 if (eep_config.max_dvc_qng == 0) {
15593 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15594 } else {
15595 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
15596 }
15597 }
15598
15599 /*
15600 * If 'max_dvc_qng' is greater than 'max_host_qng', then
15601 * set 'max_dvc_qng' to 'max_host_qng'.
15602 */
15603 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
15604 eep_config.max_dvc_qng = eep_config.max_host_qng;
15605 }
15606
15607 /*
15608 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
15609 * values based on possibly adjusted EEPROM values.
15610 */
15611 asc_dvc->max_host_qng = eep_config.max_host_qng;
15612 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15613
15614 /*
15615 * If the EEPROM 'termination' field is set to automatic (0), then set
15616 * the ADV_DVC_CFG 'termination' field to automatic also.
15617 *
15618 * If the termination is specified with a non-zero 'termination'
15619 * value check that a legal value is set and set the ADV_DVC_CFG
15620 * 'termination' field appropriately.
15621 */
15622 if (eep_config.termination == 0) {
15623 asc_dvc->cfg->termination = 0; /* auto termination */
15624 } else {
15625 /* Enable manual control with low off / high off. */
15626 if (eep_config.termination == 1) {
15627 asc_dvc->cfg->termination = TERM_CTL_SEL;
15628
15629 /* Enable manual control with low off / high on. */
15630 } else if (eep_config.termination == 2) {
15631 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
15632
15633 /* Enable manual control with low on / high on. */
15634 } else if (eep_config.termination == 3) {
15635 asc_dvc->cfg->termination =
15636 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
15637 } else {
15638 /*
15639 * The EEPROM 'termination' field contains a bad value. Use
15640 * automatic termination instead.
15641 */
15642 asc_dvc->cfg->termination = 0;
15643 warn_code |= ASC_WARN_EEPROM_TERMINATION;
15644 }
15645 }
15646
15647 return warn_code;
15648 }
15649
15650 /*
15651 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
15652 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
15653 * all of this is done.
15654 *
15655 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15656 *
15657 * For a non-fatal error return a warning code. If there are no warnings
15658 * then 0 is returned.
15659 *
15660 * Note: Chip is stopped on entry.
15661 */
15662 static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
15663 {
15664 AdvPortAddr iop_base;
15665 ushort warn_code;
15666 ADVEEP_38C0800_CONFIG eep_config;
15667 int i;
15668 uchar tid, termination;
15669 ushort sdtr_speed = 0;
15670
15671 iop_base = asc_dvc->iop_base;
15672
15673 warn_code = 0;
15674
15675 /*
15676 * Read the board's EEPROM configuration.
15677 *
15678 * Set default values if a bad checksum is found.
15679 */
15680 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
15681 eep_config.check_sum) {
15682 warn_code |= ASC_WARN_EEPROM_CHKSUM;
15683
15684 /*
15685 * Set EEPROM default values.
15686 */
15687 for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++) {
15688 *((uchar *)&eep_config + i) =
15689 *((uchar *)&Default_38C0800_EEPROM_Config + i);
15690 }
15691
15692 /*
15693 * Assume the 6 byte board serial number that was read
15694 * from EEPROM is correct even if the EEPROM checksum
15695 * failed.
15696 */
15697 eep_config.serial_number_word3 =
15698 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
15699
15700 eep_config.serial_number_word2 =
15701 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
15702
15703 eep_config.serial_number_word1 =
15704 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
15705
15706 AdvSet38C0800EEPConfig(iop_base, &eep_config);
15707 }
15708 /*
15709 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
15710 * EEPROM configuration that was read.
15711 *
15712 * This is the mapping of EEPROM fields to Adv Library fields.
15713 */
15714 asc_dvc->wdtr_able = eep_config.wdtr_able;
15715 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
15716 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
15717 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
15718 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
15719 asc_dvc->tagqng_able = eep_config.tagqng_able;
15720 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
15721 asc_dvc->max_host_qng = eep_config.max_host_qng;
15722 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15723 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
15724 asc_dvc->start_motor = eep_config.start_motor;
15725 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
15726 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
15727 asc_dvc->no_scam = eep_config.scam_tolerant;
15728 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
15729 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
15730 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
15731
15732 /*
15733 * For every Target ID if any of its 'sdtr_speed[1234]' bits
15734 * are set, then set an 'sdtr_able' bit for it.
15735 */
15736 asc_dvc->sdtr_able = 0;
15737 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
15738 if (tid == 0) {
15739 sdtr_speed = asc_dvc->sdtr_speed1;
15740 } else if (tid == 4) {
15741 sdtr_speed = asc_dvc->sdtr_speed2;
15742 } else if (tid == 8) {
15743 sdtr_speed = asc_dvc->sdtr_speed3;
15744 } else if (tid == 12) {
15745 sdtr_speed = asc_dvc->sdtr_speed4;
15746 }
15747 if (sdtr_speed & ADV_MAX_TID) {
15748 asc_dvc->sdtr_able |= (1 << tid);
15749 }
15750 sdtr_speed >>= 4;
15751 }
15752
15753 /*
15754 * Set the host maximum queuing (max. 253, min. 16) and the per device
15755 * maximum queuing (max. 63, min. 4).
15756 */
15757 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
15758 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15759 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
15760 /* If the value is zero, assume it is uninitialized. */
15761 if (eep_config.max_host_qng == 0) {
15762 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15763 } else {
15764 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
15765 }
15766 }
15767
15768 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
15769 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15770 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
15771 /* If the value is zero, assume it is uninitialized. */
15772 if (eep_config.max_dvc_qng == 0) {
15773 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15774 } else {
15775 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
15776 }
15777 }
15778
15779 /*
15780 * If 'max_dvc_qng' is greater than 'max_host_qng', then
15781 * set 'max_dvc_qng' to 'max_host_qng'.
15782 */
15783 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
15784 eep_config.max_dvc_qng = eep_config.max_host_qng;
15785 }
15786
15787 /*
15788 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
15789 * values based on possibly adjusted EEPROM values.
15790 */
15791 asc_dvc->max_host_qng = eep_config.max_host_qng;
15792 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15793
15794 /*
15795 * If the EEPROM 'termination' field is set to automatic (0), then set
15796 * the ADV_DVC_CFG 'termination' field to automatic also.
15797 *
15798 * If the termination is specified with a non-zero 'termination'
15799 * value check that a legal value is set and set the ADV_DVC_CFG
15800 * 'termination' field appropriately.
15801 */
15802 if (eep_config.termination_se == 0) {
15803 termination = 0; /* auto termination for SE */
15804 } else {
15805 /* Enable manual control with low off / high off. */
15806 if (eep_config.termination_se == 1) {
15807 termination = 0;
15808
15809 /* Enable manual control with low off / high on. */
15810 } else if (eep_config.termination_se == 2) {
15811 termination = TERM_SE_HI;
15812
15813 /* Enable manual control with low on / high on. */
15814 } else if (eep_config.termination_se == 3) {
15815 termination = TERM_SE;
15816 } else {
15817 /*
15818 * The EEPROM 'termination_se' field contains a bad value.
15819 * Use automatic termination instead.
15820 */
15821 termination = 0;
15822 warn_code |= ASC_WARN_EEPROM_TERMINATION;
15823 }
15824 }
15825
15826 if (eep_config.termination_lvd == 0) {
15827 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
15828 } else {
15829 /* Enable manual control with low off / high off. */
15830 if (eep_config.termination_lvd == 1) {
15831 asc_dvc->cfg->termination = termination;
15832
15833 /* Enable manual control with low off / high on. */
15834 } else if (eep_config.termination_lvd == 2) {
15835 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
15836
15837 /* Enable manual control with low on / high on. */
15838 } else if (eep_config.termination_lvd == 3) {
15839 asc_dvc->cfg->termination = termination | TERM_LVD;
15840 } else {
15841 /*
15842 * The EEPROM 'termination_lvd' field contains a bad value.
15843 * Use automatic termination instead.
15844 */
15845 asc_dvc->cfg->termination = termination;
15846 warn_code |= ASC_WARN_EEPROM_TERMINATION;
15847 }
15848 }
15849
15850 return warn_code;
15851 }
15852
15853 /*
15854 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
15855 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
15856 * all of this is done.
15857 *
15858 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
15859 *
15860 * For a non-fatal error return a warning code. If there are no warnings
15861 * then 0 is returned.
15862 *
15863 * Note: Chip is stopped on entry.
15864 */
15865 static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
15866 {
15867 AdvPortAddr iop_base;
15868 ushort warn_code;
15869 ADVEEP_38C1600_CONFIG eep_config;
15870 int i;
15871 uchar tid, termination;
15872 ushort sdtr_speed = 0;
15873
15874 iop_base = asc_dvc->iop_base;
15875
15876 warn_code = 0;
15877
15878 /*
15879 * Read the board's EEPROM configuration.
15880 *
15881 * Set default values if a bad checksum is found.
15882 */
15883 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
15884 eep_config.check_sum) {
15885 warn_code |= ASC_WARN_EEPROM_CHKSUM;
15886
15887 /*
15888 * Set EEPROM default values.
15889 */
15890 for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++) {
15891 if (i == 1
15892 && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) !=
15893 0) {
15894 /*
15895 * Set Function 1 EEPROM Word 0 MSB
15896 *
15897 * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11)
15898 * EEPROM bits.
15899 *
15900 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and
15901 * old Mac system booting problem. The Expansion ROM must
15902 * be disabled in Function 1 for these systems.
15903 *
15904 */
15905 *((uchar *)&eep_config + i) =
15906 ((*
15907 ((uchar *)&Default_38C1600_EEPROM_Config
15908 +
15909 i)) &
15910 (~
15911 (((ADV_EEPROM_BIOS_ENABLE |
15912 ADV_EEPROM_INTAB) >> 8) & 0xFF)));
15913
15914 /*
15915 * Set the INTAB (bit 11) if the GPIO 0 input indicates
15916 * the Function 1 interrupt line is wired to INTA.
15917 *
15918 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
15919 * 1 - Function 1 interrupt line wired to INT A.
15920 * 0 - Function 1 interrupt line wired to INT B.
15921 *
15922 * Note: Adapter boards always have Function 0 wired to INTA.
15923 * Put all 5 GPIO bits in input mode and then read
15924 * their input values.
15925 */
15926 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL,
15927 0);
15928 if (AdvReadByteRegister
15929 (iop_base, IOPB_GPIO_DATA) & 0x01) {
15930 /* Function 1 interrupt wired to INTA; Set EEPROM bit. */
15931 *((uchar *)&eep_config + i) |=
15932 ((ADV_EEPROM_INTAB >> 8) & 0xFF);
15933 }
15934 } else {
15935 *((uchar *)&eep_config + i) =
15936 *((uchar *)&Default_38C1600_EEPROM_Config
15937 + i);
15938 }
15939 }
15940
15941 /*
15942 * Assume the 6 byte board serial number that was read
15943 * from EEPROM is correct even if the EEPROM checksum
15944 * failed.
15945 */
15946 eep_config.serial_number_word3 =
15947 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
15948
15949 eep_config.serial_number_word2 =
15950 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
15951
15952 eep_config.serial_number_word1 =
15953 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
15954
15955 AdvSet38C1600EEPConfig(iop_base, &eep_config);
15956 }
15957
15958 /*
15959 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
15960 * EEPROM configuration that was read.
15961 *
15962 * This is the mapping of EEPROM fields to Adv Library fields.
15963 */
15964 asc_dvc->wdtr_able = eep_config.wdtr_able;
15965 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
15966 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
15967 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
15968 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
15969 asc_dvc->ppr_able = 0;
15970 asc_dvc->tagqng_able = eep_config.tagqng_able;
15971 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
15972 asc_dvc->max_host_qng = eep_config.max_host_qng;
15973 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15974 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
15975 asc_dvc->start_motor = eep_config.start_motor;
15976 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
15977 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
15978 asc_dvc->no_scam = eep_config.scam_tolerant;
15979
15980 /*
15981 * For every Target ID if any of its 'sdtr_speed[1234]' bits
15982 * are set, then set an 'sdtr_able' bit for it.
15983 */
15984 asc_dvc->sdtr_able = 0;
15985 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15986 if (tid == 0) {
15987 sdtr_speed = asc_dvc->sdtr_speed1;
15988 } else if (tid == 4) {
15989 sdtr_speed = asc_dvc->sdtr_speed2;
15990 } else if (tid == 8) {
15991 sdtr_speed = asc_dvc->sdtr_speed3;
15992 } else if (tid == 12) {
15993 sdtr_speed = asc_dvc->sdtr_speed4;
15994 }
15995 if (sdtr_speed & ASC_MAX_TID) {
15996 asc_dvc->sdtr_able |= (1 << tid);
15997 }
15998 sdtr_speed >>= 4;
15999 }
16000
16001 /*
16002 * Set the host maximum queuing (max. 253, min. 16) and the per device
16003 * maximum queuing (max. 63, min. 4).
16004 */
16005 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
16006 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16007 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
16008 /* If the value is zero, assume it is uninitialized. */
16009 if (eep_config.max_host_qng == 0) {
16010 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16011 } else {
16012 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16013 }
16014 }
16015
16016 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
16017 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16018 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
16019 /* If the value is zero, assume it is uninitialized. */
16020 if (eep_config.max_dvc_qng == 0) {
16021 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16022 } else {
16023 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16024 }
16025 }
16026
16027 /*
16028 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16029 * set 'max_dvc_qng' to 'max_host_qng'.
16030 */
16031 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
16032 eep_config.max_dvc_qng = eep_config.max_host_qng;
16033 }
16034
16035 /*
16036 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
16037 * values based on possibly adjusted EEPROM values.
16038 */
16039 asc_dvc->max_host_qng = eep_config.max_host_qng;
16040 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16041
16042 /*
16043 * If the EEPROM 'termination' field is set to automatic (0), then set
16044 * the ASC_DVC_CFG 'termination' field to automatic also.
16045 *
16046 * If the termination is specified with a non-zero 'termination'
16047 * value check that a legal value is set and set the ASC_DVC_CFG
16048 * 'termination' field appropriately.
16049 */
16050 if (eep_config.termination_se == 0) {
16051 termination = 0; /* auto termination for SE */
16052 } else {
16053 /* Enable manual control with low off / high off. */
16054 if (eep_config.termination_se == 1) {
16055 termination = 0;
16056
16057 /* Enable manual control with low off / high on. */
16058 } else if (eep_config.termination_se == 2) {
16059 termination = TERM_SE_HI;
16060
16061 /* Enable manual control with low on / high on. */
16062 } else if (eep_config.termination_se == 3) {
16063 termination = TERM_SE;
16064 } else {
16065 /*
16066 * The EEPROM 'termination_se' field contains a bad value.
16067 * Use automatic termination instead.
16068 */
16069 termination = 0;
16070 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16071 }
16072 }
16073
16074 if (eep_config.termination_lvd == 0) {
16075 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
16076 } else {
16077 /* Enable manual control with low off / high off. */
16078 if (eep_config.termination_lvd == 1) {
16079 asc_dvc->cfg->termination = termination;
16080
16081 /* Enable manual control with low off / high on. */
16082 } else if (eep_config.termination_lvd == 2) {
16083 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16084
16085 /* Enable manual control with low on / high on. */
16086 } else if (eep_config.termination_lvd == 3) {
16087 asc_dvc->cfg->termination = termination | TERM_LVD;
16088 } else {
16089 /*
16090 * The EEPROM 'termination_lvd' field contains a bad value.
16091 * Use automatic termination instead.
16092 */
16093 asc_dvc->cfg->termination = termination;
16094 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16095 }
16096 }
16097
16098 return warn_code;
16099 }
16100
16101 /*
16102 * Read EEPROM configuration into the specified buffer.
16103 *
16104 * Return a checksum based on the EEPROM configuration read.
16105 */
16106 static ushort __devinit
16107 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16108 {
16109 ushort wval, chksum;
16110 ushort *wbuf;
16111 int eep_addr;
16112 ushort *charfields;
16113
16114 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16115 wbuf = (ushort *)cfg_buf;
16116 chksum = 0;
16117
16118 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16119 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16120 wval = AdvReadEEPWord(iop_base, eep_addr);
16121 chksum += wval; /* Checksum is calculated from word values. */
16122 if (*charfields++) {
16123 *wbuf = le16_to_cpu(wval);
16124 } else {
16125 *wbuf = wval;
16126 }
16127 }
16128 /* Read checksum word. */
16129 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16130 wbuf++;
16131 charfields++;
16132
16133 /* Read rest of EEPROM not covered by the checksum. */
16134 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16135 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16136 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16137 if (*charfields++) {
16138 *wbuf = le16_to_cpu(*wbuf);
16139 }
16140 }
16141 return chksum;
16142 }
16143
16144 /*
16145 * Read EEPROM configuration into the specified buffer.
16146 *
16147 * Return a checksum based on the EEPROM configuration read.
16148 */
16149 static ushort __devinit
16150 AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
16151 {
16152 ushort wval, chksum;
16153 ushort *wbuf;
16154 int eep_addr;
16155 ushort *charfields;
16156
16157 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16158 wbuf = (ushort *)cfg_buf;
16159 chksum = 0;
16160
16161 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16162 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16163 wval = AdvReadEEPWord(iop_base, eep_addr);
16164 chksum += wval; /* Checksum is calculated from word values. */
16165 if (*charfields++) {
16166 *wbuf = le16_to_cpu(wval);
16167 } else {
16168 *wbuf = wval;
16169 }
16170 }
16171 /* Read checksum word. */
16172 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16173 wbuf++;
16174 charfields++;
16175
16176 /* Read rest of EEPROM not covered by the checksum. */
16177 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16178 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16179 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16180 if (*charfields++) {
16181 *wbuf = le16_to_cpu(*wbuf);
16182 }
16183 }
16184 return chksum;
16185 }
16186
16187 /*
16188 * Read EEPROM configuration into the specified buffer.
16189 *
16190 * Return a checksum based on the EEPROM configuration read.
16191 */
16192 static ushort __devinit
16193 AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
16194 {
16195 ushort wval, chksum;
16196 ushort *wbuf;
16197 int eep_addr;
16198 ushort *charfields;
16199
16200 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16201 wbuf = (ushort *)cfg_buf;
16202 chksum = 0;
16203
16204 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16205 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16206 wval = AdvReadEEPWord(iop_base, eep_addr);
16207 chksum += wval; /* Checksum is calculated from word values. */
16208 if (*charfields++) {
16209 *wbuf = le16_to_cpu(wval);
16210 } else {
16211 *wbuf = wval;
16212 }
16213 }
16214 /* Read checksum word. */
16215 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16216 wbuf++;
16217 charfields++;
16218
16219 /* Read rest of EEPROM not covered by the checksum. */
16220 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16221 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16222 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16223 if (*charfields++) {
16224 *wbuf = le16_to_cpu(*wbuf);
16225 }
16226 }
16227 return chksum;
16228 }
16229
16230 /*
16231 * Read the EEPROM from specified location
16232 */
16233 static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
16234 {
16235 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16236 ASC_EEP_CMD_READ | eep_word_addr);
16237 AdvWaitEEPCmd(iop_base);
16238 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
16239 }
16240
16241 /*
16242 * Wait for EEPROM command to complete
16243 */
16244 static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
16245 {
16246 int eep_delay_ms;
16247
16248 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
16249 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
16250 ASC_EEP_CMD_DONE) {
16251 break;
16252 }
16253 DvcSleepMilliSecond(1);
16254 }
16255 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
16256 0) {
16257 ASC_ASSERT(0);
16258 }
16259 return;
16260 }
16261
16262 /*
16263 * Write the EEPROM from 'cfg_buf'.
16264 */
16265 void __devinit
16266 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16267 {
16268 ushort *wbuf;
16269 ushort addr, chksum;
16270 ushort *charfields;
16271
16272 wbuf = (ushort *)cfg_buf;
16273 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16274 chksum = 0;
16275
16276 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16277 AdvWaitEEPCmd(iop_base);
16278
16279 /*
16280 * Write EEPROM from word 0 to word 20.
16281 */
16282 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16283 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16284 ushort word;
16285
16286 if (*charfields++) {
16287 word = cpu_to_le16(*wbuf);
16288 } else {
16289 word = *wbuf;
16290 }
16291 chksum += *wbuf; /* Checksum is calculated from word values. */
16292 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16293 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16294 ASC_EEP_CMD_WRITE | addr);
16295 AdvWaitEEPCmd(iop_base);
16296 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16297 }
16298
16299 /*
16300 * Write EEPROM checksum at word 21.
16301 */
16302 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16303 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16304 AdvWaitEEPCmd(iop_base);
16305 wbuf++;
16306 charfields++;
16307
16308 /*
16309 * Write EEPROM OEM name at words 22 to 29.
16310 */
16311 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16312 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16313 ushort word;
16314
16315 if (*charfields++) {
16316 word = cpu_to_le16(*wbuf);
16317 } else {
16318 word = *wbuf;
16319 }
16320 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16321 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16322 ASC_EEP_CMD_WRITE | addr);
16323 AdvWaitEEPCmd(iop_base);
16324 }
16325 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16326 AdvWaitEEPCmd(iop_base);
16327 return;
16328 }
16329
16330 /*
16331 * Write the EEPROM from 'cfg_buf'.
16332 */
16333 void __devinit
16334 AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
16335 {
16336 ushort *wbuf;
16337 ushort *charfields;
16338 ushort addr, chksum;
16339
16340 wbuf = (ushort *)cfg_buf;
16341 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16342 chksum = 0;
16343
16344 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16345 AdvWaitEEPCmd(iop_base);
16346
16347 /*
16348 * Write EEPROM from word 0 to word 20.
16349 */
16350 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16351 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16352 ushort word;
16353
16354 if (*charfields++) {
16355 word = cpu_to_le16(*wbuf);
16356 } else {
16357 word = *wbuf;
16358 }
16359 chksum += *wbuf; /* Checksum is calculated from word values. */
16360 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16361 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16362 ASC_EEP_CMD_WRITE | addr);
16363 AdvWaitEEPCmd(iop_base);
16364 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16365 }
16366
16367 /*
16368 * Write EEPROM checksum at word 21.
16369 */
16370 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16371 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16372 AdvWaitEEPCmd(iop_base);
16373 wbuf++;
16374 charfields++;
16375
16376 /*
16377 * Write EEPROM OEM name at words 22 to 29.
16378 */
16379 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16380 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16381 ushort word;
16382
16383 if (*charfields++) {
16384 word = cpu_to_le16(*wbuf);
16385 } else {
16386 word = *wbuf;
16387 }
16388 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16389 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16390 ASC_EEP_CMD_WRITE | addr);
16391 AdvWaitEEPCmd(iop_base);
16392 }
16393 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16394 AdvWaitEEPCmd(iop_base);
16395 return;
16396 }
16397
16398 /*
16399 * Write the EEPROM from 'cfg_buf'.
16400 */
16401 void __devinit
16402 AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
16403 {
16404 ushort *wbuf;
16405 ushort *charfields;
16406 ushort addr, chksum;
16407
16408 wbuf = (ushort *)cfg_buf;
16409 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16410 chksum = 0;
16411
16412 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16413 AdvWaitEEPCmd(iop_base);
16414
16415 /*
16416 * Write EEPROM from word 0 to word 20.
16417 */
16418 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16419 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16420 ushort word;
16421
16422 if (*charfields++) {
16423 word = cpu_to_le16(*wbuf);
16424 } else {
16425 word = *wbuf;
16426 }
16427 chksum += *wbuf; /* Checksum is calculated from word values. */
16428 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16429 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16430 ASC_EEP_CMD_WRITE | addr);
16431 AdvWaitEEPCmd(iop_base);
16432 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16433 }
16434
16435 /*
16436 * Write EEPROM checksum at word 21.
16437 */
16438 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16439 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16440 AdvWaitEEPCmd(iop_base);
16441 wbuf++;
16442 charfields++;
16443
16444 /*
16445 * Write EEPROM OEM name at words 22 to 29.
16446 */
16447 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16448 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16449 ushort word;
16450
16451 if (*charfields++) {
16452 word = cpu_to_le16(*wbuf);
16453 } else {
16454 word = *wbuf;
16455 }
16456 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16457 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16458 ASC_EEP_CMD_WRITE | addr);
16459 AdvWaitEEPCmd(iop_base);
16460 }
16461 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16462 AdvWaitEEPCmd(iop_base);
16463 return;
16464 }
16465
16466 /* a_advlib.c */
16467 /*
16468 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
16469 *
16470 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
16471 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
16472 * RISC to notify it a new command is ready to be executed.
16473 *
16474 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
16475 * set to SCSI_MAX_RETRY.
16476 *
16477 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
16478 * for DMA addresses or math operations are byte swapped to little-endian
16479 * order.
16480 *
16481 * Return:
16482 * ADV_SUCCESS(1) - The request was successfully queued.
16483 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
16484 * request completes.
16485 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
16486 * host IC error.
16487 */
16488 static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
16489 {
16490 ulong last_int_level;
16491 AdvPortAddr iop_base;
16492 ADV_DCNT req_size;
16493 ADV_PADDR req_paddr;
16494 ADV_CARR_T *new_carrp;
16495
16496 ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
16497
16498 /*
16499 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
16500 */
16501 if (scsiq->target_id > ADV_MAX_TID) {
16502 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
16503 scsiq->done_status = QD_WITH_ERROR;
16504 return ADV_ERROR;
16505 }
16506
16507 iop_base = asc_dvc->iop_base;
16508
16509 last_int_level = DvcEnterCritical();
16510
16511 /*
16512 * Allocate a carrier ensuring at least one carrier always
16513 * remains on the freelist and initialize fields.
16514 */
16515 if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
16516 DvcLeaveCritical(last_int_level);
16517 return ADV_BUSY;
16518 }
16519 asc_dvc->carr_freelist = (ADV_CARR_T *)
16520 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
16521 asc_dvc->carr_pending_cnt++;
16522
16523 /*
16524 * Set the carrier to be a stopper by setting 'next_vpa'
16525 * to the stopper value. The current stopper will be changed
16526 * below to point to the new stopper.
16527 */
16528 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16529
16530 /*
16531 * Clear the ADV_SCSI_REQ_Q done flag.
16532 */
16533 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
16534
16535 req_size = sizeof(ADV_SCSI_REQ_Q);
16536 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
16537 (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
16538
16539 ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
16540 ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
16541
16542 /* Wait for assertion before making little-endian */
16543 req_paddr = cpu_to_le32(req_paddr);
16544
16545 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
16546 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
16547 scsiq->scsiq_rptr = req_paddr;
16548
16549 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
16550 /*
16551 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
16552 * order during initialization.
16553 */
16554 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
16555
16556 /*
16557 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
16558 * the microcode. The newly allocated stopper will become the new
16559 * stopper.
16560 */
16561 asc_dvc->icq_sp->areq_vpa = req_paddr;
16562
16563 /*
16564 * Set the 'next_vpa' pointer for the old stopper to be the
16565 * physical address of the new stopper. The RISC can only
16566 * follow physical addresses.
16567 */
16568 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
16569
16570 /*
16571 * Set the host adapter stopper pointer to point to the new carrier.
16572 */
16573 asc_dvc->icq_sp = new_carrp;
16574
16575 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
16576 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
16577 /*
16578 * Tickle the RISC to tell it to read its Command Queue Head pointer.
16579 */
16580 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
16581 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
16582 /*
16583 * Clear the tickle value. In the ASC-3550 the RISC flag
16584 * command 'clr_tickle_a' does not work unless the host
16585 * value is cleared.
16586 */
16587 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
16588 ADV_TICKLE_NOP);
16589 }
16590 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16591 /*
16592 * Notify the RISC a carrier is ready by writing the physical
16593 * address of the new carrier stopper to the COMMA register.
16594 */
16595 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
16596 le32_to_cpu(new_carrp->carr_pa));
16597 }
16598
16599 DvcLeaveCritical(last_int_level);
16600
16601 return ADV_SUCCESS;
16602 }
16603
16604 /*
16605 * Reset SCSI Bus and purge all outstanding requests.
16606 *
16607 * Return Value:
16608 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
16609 * ADV_FALSE(0) - Microcode command failed.
16610 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
16611 * may be hung which requires driver recovery.
16612 */
16613 static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
16614 {
16615 int status;
16616
16617 /*
16618 * Send the SCSI Bus Reset idle start idle command which asserts
16619 * the SCSI Bus Reset signal.
16620 */
16621 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
16622 if (status != ADV_TRUE) {
16623 return status;
16624 }
16625
16626 /*
16627 * Delay for the specified SCSI Bus Reset hold time.
16628 *
16629 * The hold time delay is done on the host because the RISC has no
16630 * microsecond accurate timer.
16631 */
16632 DvcDelayMicroSecond(asc_dvc, (ushort)ASC_SCSI_RESET_HOLD_TIME_US);
16633
16634 /*
16635 * Send the SCSI Bus Reset end idle command which de-asserts
16636 * the SCSI Bus Reset signal and purges any pending requests.
16637 */
16638 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
16639 if (status != ADV_TRUE) {
16640 return status;
16641 }
16642
16643 DvcSleepMilliSecond((ADV_DCNT)asc_dvc->scsi_reset_wait * 1000);
16644
16645 return status;
16646 }
16647
16648 /*
16649 * Reset chip and SCSI Bus.
16650 *
16651 * Return Value:
16652 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
16653 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
16654 */
16655 static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
16656 {
16657 int status;
16658 ushort wdtr_able, sdtr_able, tagqng_able;
16659 ushort ppr_able = 0;
16660 uchar tid, max_cmd[ADV_MAX_TID + 1];
16661 AdvPortAddr iop_base;
16662 ushort bios_sig;
16663
16664 iop_base = asc_dvc->iop_base;
16665
16666 /*
16667 * Save current per TID negotiated values.
16668 */
16669 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16670 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16671 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16672 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16673 }
16674 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16675 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
16676 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16677 max_cmd[tid]);
16678 }
16679
16680 /*
16681 * Force the AdvInitAsc3550/38C0800Driver() function to
16682 * perform a SCSI Bus Reset by clearing the BIOS signature word.
16683 * The initialization functions assumes a SCSI Bus Reset is not
16684 * needed if the BIOS signature word is present.
16685 */
16686 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
16687 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
16688
16689 /*
16690 * Stop chip and reset it.
16691 */
16692 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
16693 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
16694 DvcSleepMilliSecond(100);
16695 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
16696 ADV_CTRL_REG_CMD_WR_IO_REG);
16697
16698 /*
16699 * Reset Adv Library error code, if any, and try
16700 * re-initializing the chip.
16701 */
16702 asc_dvc->err_code = 0;
16703 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16704 status = AdvInitAsc38C1600Driver(asc_dvc);
16705 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
16706 status = AdvInitAsc38C0800Driver(asc_dvc);
16707 } else {
16708 status = AdvInitAsc3550Driver(asc_dvc);
16709 }
16710
16711 /* Translate initialization return value to status value. */
16712 if (status == 0) {
16713 status = ADV_TRUE;
16714 } else {
16715 status = ADV_FALSE;
16716 }
16717
16718 /*
16719 * Restore the BIOS signature word.
16720 */
16721 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
16722
16723 /*
16724 * Restore per TID negotiated values.
16725 */
16726 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16727 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16728 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16729 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16730 }
16731 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16732 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
16733 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16734 max_cmd[tid]);
16735 }
16736
16737 return status;
16738 }
16739
16740 /*
16741 * Adv Library Interrupt Service Routine
16742 *
16743 * This function is called by a driver's interrupt service routine.
16744 * The function disables and re-enables interrupts.
16745 *
16746 * When a microcode idle command is completed, the ADV_DVC_VAR
16747 * 'idle_cmd_done' field is set to ADV_TRUE.
16748 *
16749 * Note: AdvISR() can be called when interrupts are disabled or even
16750 * when there is no hardware interrupt condition present. It will
16751 * always check for completed idle commands and microcode requests.
16752 * This is an important feature that shouldn't be changed because it
16753 * allows commands to be completed from polling mode loops.
16754 *
16755 * Return:
16756 * ADV_TRUE(1) - interrupt was pending
16757 * ADV_FALSE(0) - no interrupt was pending
16758 */
16759 static int AdvISR(ADV_DVC_VAR *asc_dvc)
16760 {
16761 AdvPortAddr iop_base;
16762 uchar int_stat;
16763 ushort target_bit;
16764 ADV_CARR_T *free_carrp;
16765 ADV_VADDR irq_next_vpa;
16766 int flags;
16767 ADV_SCSI_REQ_Q *scsiq;
16768
16769 flags = DvcEnterCritical();
16770
16771 iop_base = asc_dvc->iop_base;
16772
16773 /* Reading the register clears the interrupt. */
16774 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
16775
16776 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
16777 ADV_INTR_STATUS_INTRC)) == 0) {
16778 DvcLeaveCritical(flags);
16779 return ADV_FALSE;
16780 }
16781
16782 /*
16783 * Notify the driver of an asynchronous microcode condition by
16784 * calling the ADV_DVC_VAR.async_callback function. The function
16785 * is passed the microcode ASC_MC_INTRB_CODE byte value.
16786 */
16787 if (int_stat & ADV_INTR_STATUS_INTRB) {
16788 uchar intrb_code;
16789
16790 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
16791
16792 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
16793 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
16794 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
16795 asc_dvc->carr_pending_cnt != 0) {
16796 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
16797 ADV_TICKLE_A);
16798 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
16799 AdvWriteByteRegister(iop_base,
16800 IOPB_TICKLE,
16801 ADV_TICKLE_NOP);
16802 }
16803 }
16804 }
16805
16806 if (asc_dvc->async_callback != 0) {
16807 (*asc_dvc->async_callback) (asc_dvc, intrb_code);
16808 }
16809 }
16810
16811 /*
16812 * Check if the IRQ stopper carrier contains a completed request.
16813 */
16814 while (((irq_next_vpa =
16815 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
16816 /*
16817 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
16818 * The RISC will have set 'areq_vpa' to a virtual address.
16819 *
16820 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
16821 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
16822 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
16823 * in AdvExeScsiQueue().
16824 */
16825 scsiq = (ADV_SCSI_REQ_Q *)
16826 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
16827
16828 /*
16829 * Request finished with good status and the queue was not
16830 * DMAed to host memory by the firmware. Set all status fields
16831 * to indicate good status.
16832 */
16833 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
16834 scsiq->done_status = QD_NO_ERROR;
16835 scsiq->host_status = scsiq->scsi_status = 0;
16836 scsiq->data_cnt = 0L;
16837 }
16838
16839 /*
16840 * Advance the stopper pointer to the next carrier
16841 * ignoring the lower four bits. Free the previous
16842 * stopper carrier.
16843 */
16844 free_carrp = asc_dvc->irq_sp;
16845 asc_dvc->irq_sp = (ADV_CARR_T *)
16846 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
16847
16848 free_carrp->next_vpa =
16849 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
16850 asc_dvc->carr_freelist = free_carrp;
16851 asc_dvc->carr_pending_cnt--;
16852
16853 ASC_ASSERT(scsiq != NULL);
16854 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
16855
16856 /*
16857 * Clear request microcode control flag.
16858 */
16859 scsiq->cntl = 0;
16860
16861 /*
16862 * Notify the driver of the completed request by passing
16863 * the ADV_SCSI_REQ_Q pointer to its callback function.
16864 */
16865 scsiq->a_flag |= ADV_SCSIQ_DONE;
16866 (*asc_dvc->isr_callback) (asc_dvc, scsiq);
16867 /*
16868 * Note: After the driver callback function is called, 'scsiq'
16869 * can no longer be referenced.
16870 *
16871 * Fall through and continue processing other completed
16872 * requests...
16873 */
16874
16875 /*
16876 * Disable interrupts again in case the driver inadvertently
16877 * enabled interrupts in its callback function.
16878 *
16879 * The DvcEnterCritical() return value is ignored, because
16880 * the 'flags' saved when AdvISR() was first entered will be
16881 * used to restore the interrupt flag on exit.
16882 */
16883 (void)DvcEnterCritical();
16884 }
16885 DvcLeaveCritical(flags);
16886 return ADV_TRUE;
16887 }
16888
16889 /*
16890 * Send an idle command to the chip and wait for completion.
16891 *
16892 * Command completion is polled for once per microsecond.
16893 *
16894 * The function can be called from anywhere including an interrupt handler.
16895 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
16896 * functions to prevent reentrancy.
16897 *
16898 * Return Values:
16899 * ADV_TRUE - command completed successfully
16900 * ADV_FALSE - command failed
16901 * ADV_ERROR - command timed out
16902 */
16903 static int
16904 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
16905 ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
16906 {
16907 ulong last_int_level;
16908 int result;
16909 ADV_DCNT i, j;
16910 AdvPortAddr iop_base;
16911
16912 last_int_level = DvcEnterCritical();
16913
16914 iop_base = asc_dvc->iop_base;
16915
16916 /*
16917 * Clear the idle command status which is set by the microcode
16918 * to a non-zero value to indicate when the command is completed.
16919 * The non-zero result is one of the IDLE_CMD_STATUS_* values
16920 * defined in a_advlib.h.
16921 */
16922 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
16923
16924 /*
16925 * Write the idle command value after the idle command parameter
16926 * has been written to avoid a race condition. If the order is not
16927 * followed, the microcode may process the idle command before the
16928 * parameters have been written to LRAM.
16929 */
16930 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
16931 cpu_to_le32(idle_cmd_parameter));
16932 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
16933
16934 /*
16935 * Tickle the RISC to tell it to process the idle command.
16936 */
16937 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
16938 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
16939 /*
16940 * Clear the tickle value. In the ASC-3550 the RISC flag
16941 * command 'clr_tickle_b' does not work unless the host
16942 * value is cleared.
16943 */
16944 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
16945 }
16946
16947 /* Wait for up to 100 millisecond for the idle command to timeout. */
16948 for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
16949 /* Poll once each microsecond for command completion. */
16950 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
16951 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
16952 result);
16953 if (result != 0) {
16954 DvcLeaveCritical(last_int_level);
16955 return result;
16956 }
16957 DvcDelayMicroSecond(asc_dvc, (ushort)1);
16958 }
16959 }
16960
16961 ASC_ASSERT(0); /* The idle command should never timeout. */
16962 DvcLeaveCritical(last_int_level);
16963 return ADV_ERROR;
16964 }
16965
16966 static int __devinit
16967 advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
16968 {
16969 int req_cnt = 0;
16970 adv_req_t *reqp = NULL;
16971 int sg_cnt = 0;
16972 adv_sgblk_t *sgp;
16973 int warn_code, err_code;
16974
16975 /*
16976 * Allocate buffer carrier structures. The total size
16977 * is about 4 KB, so allocate all at once.
16978 */
16979 boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
16980 ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp);
16981
16982 if (!boardp->carrp)
16983 goto kmalloc_failed;
16984
16985 /*
16986 * Allocate up to 'max_host_qng' request structures for the Wide
16987 * board. The total size is about 16 KB, so allocate all at once.
16988 * If the allocation fails decrement and try again.
16989 */
16990 for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
16991 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
16992
16993 ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, "
16994 "bytes %lu\n", reqp, req_cnt,
16995 (ulong)sizeof(adv_req_t) * req_cnt);
16996
16997 if (reqp)
16998 break;
16999 }
17000
17001 if (!reqp)
17002 goto kmalloc_failed;
17003
17004 boardp->orig_reqp = reqp;
17005
17006 /*
17007 * Allocate up to ADV_TOT_SG_BLOCK request structures for
17008 * the Wide board. Each structure is about 136 bytes.
17009 */
17010 boardp->adv_sgblkp = NULL;
17011 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
17012 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
17013
17014 if (!sgp)
17015 break;
17016
17017 sgp->next_sgblkp = boardp->adv_sgblkp;
17018 boardp->adv_sgblkp = sgp;
17019
17020 }
17021
17022 ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n",
17023 sg_cnt, sizeof(adv_sgblk_t),
17024 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
17025
17026 if (!boardp->adv_sgblkp)
17027 goto kmalloc_failed;
17028
17029 adv_dvc_varp->carrier_buf = boardp->carrp;
17030
17031 /*
17032 * Point 'adv_reqp' to the request structures and
17033 * link them together.
17034 */
17035 req_cnt--;
17036 reqp[req_cnt].next_reqp = NULL;
17037 for (; req_cnt > 0; req_cnt--) {
17038 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
17039 }
17040 boardp->adv_reqp = &reqp[0];
17041
17042 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17043 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n");
17044 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
17045 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17046 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()"
17047 "\n");
17048 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
17049 } else {
17050 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()"
17051 "\n");
17052 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
17053 }
17054 err_code = adv_dvc_varp->err_code;
17055
17056 if (warn_code || err_code) {
17057 ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
17058 " error 0x%x\n", boardp->id, warn_code, err_code);
17059 }
17060
17061 goto exit;
17062
17063 kmalloc_failed:
17064 ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
17065 "failed\n", boardp->id);
17066 err_code = ADV_ERROR;
17067 exit:
17068 return err_code;
17069 }
17070
17071 static void advansys_wide_free_mem(asc_board_t *boardp)
17072 {
17073 kfree(boardp->carrp);
17074 boardp->carrp = NULL;
17075 kfree(boardp->orig_reqp);
17076 boardp->orig_reqp = boardp->adv_reqp = NULL;
17077 while (boardp->adv_sgblkp) {
17078 adv_sgblk_t *sgp = boardp->adv_sgblkp;
17079 boardp->adv_sgblkp = sgp->next_sgblkp;
17080 kfree(sgp);
17081 }
17082 }
17083
17084 static struct Scsi_Host *__devinit
17085 advansys_board_found(int iop, struct device *dev, int bus_type)
17086 {
17087 struct Scsi_Host *shost;
17088 struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL;
17089 asc_board_t *boardp;
17090 ASC_DVC_VAR *asc_dvc_varp = NULL;
17091 ADV_DVC_VAR *adv_dvc_varp = NULL;
17092 int share_irq;
17093 int iolen = 0;
17094 ADV_PADDR pci_memory_address;
17095 int warn_code, err_code;
17096 int ret;
17097
17098 /*
17099 * Register the adapter, get its configuration, and
17100 * initialize it.
17101 */
17102 ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n");
17103 shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t));
17104 if (!shost)
17105 return NULL;
17106
17107 /* Initialize private per board data */
17108 boardp = ASC_BOARDP(shost);
17109 memset(boardp, 0, sizeof(asc_board_t));
17110 boardp->id = asc_board_count++;
17111 spin_lock_init(&boardp->lock);
17112
17113 /*
17114 * Handle both narrow and wide boards.
17115 *
17116 * If a Wide board was detected, set the board structure
17117 * wide board flag. Set-up the board structure based on
17118 * the board type.
17119 */
17120 #ifdef CONFIG_PCI
17121 if (bus_type == ASC_IS_PCI &&
17122 (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
17123 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
17124 pdev->device == PCI_DEVICE_ID_38C1600_REV1)) {
17125 boardp->flags |= ASC_IS_WIDE_BOARD;
17126 }
17127 #endif /* CONFIG_PCI */
17128
17129 if (ASC_NARROW_BOARD(boardp)) {
17130 ASC_DBG(1, "advansys_board_found: narrow board\n");
17131 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
17132 asc_dvc_varp->bus_type = bus_type;
17133 asc_dvc_varp->drv_ptr = boardp;
17134 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
17135 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
17136 asc_dvc_varp->iop_base = iop;
17137 asc_dvc_varp->isr_callback = asc_isr_callback;
17138 } else {
17139 ASC_DBG(1, "advansys_board_found: wide board\n");
17140 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
17141 adv_dvc_varp->drv_ptr = boardp;
17142 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
17143 adv_dvc_varp->isr_callback = adv_isr_callback;
17144 adv_dvc_varp->async_callback = adv_async_callback;
17145 #ifdef CONFIG_PCI
17146 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
17147 ASC_DBG(1, "advansys_board_found: ASC-3550\n");
17148 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
17149 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
17150 ASC_DBG(1, "advansys_board_found: ASC-38C0800\n");
17151 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
17152 } else {
17153 ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
17154 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
17155 }
17156 #endif /* CONFIG_PCI */
17157
17158 /*
17159 * Map the board's registers into virtual memory for
17160 * PCI slave access. Only memory accesses are used to
17161 * access the board's registers.
17162 *
17163 * Note: The PCI register base address is not always
17164 * page aligned, but the address passed to ioremap()
17165 * must be page aligned. It is guaranteed that the
17166 * PCI register base address will not cross a page
17167 * boundary.
17168 */
17169 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17170 iolen = ADV_3550_IOLEN;
17171 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17172 iolen = ADV_38C0800_IOLEN;
17173 } else {
17174 iolen = ADV_38C1600_IOLEN;
17175 }
17176 #ifdef CONFIG_PCI
17177 pci_memory_address = pci_resource_start(pdev, 1);
17178 ASC_DBG1(1,
17179 "advansys_board_found: pci_memory_address: 0x%lx\n",
17180 (ulong)pci_memory_address);
17181 if ((boardp->ioremap_addr =
17182 ioremap(pci_memory_address & PAGE_MASK, PAGE_SIZE)) == 0) {
17183 ASC_PRINT3
17184 ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
17185 boardp->id, pci_memory_address, iolen);
17186 goto err_shost;
17187 }
17188 ASC_DBG1(1, "advansys_board_found: ioremap_addr: 0x%lx\n",
17189 (ulong)boardp->ioremap_addr);
17190 adv_dvc_varp->iop_base = (AdvPortAddr)
17191 (boardp->ioremap_addr +
17192 (pci_memory_address - (pci_memory_address & PAGE_MASK)));
17193 ASC_DBG1(1, "advansys_board_found: iop_base: 0x%lx\n",
17194 adv_dvc_varp->iop_base);
17195 #endif /* CONFIG_PCI */
17196
17197 /*
17198 * Even though it isn't used to access wide boards, other
17199 * than for the debug line below, save I/O Port address so
17200 * that it can be reported.
17201 */
17202 boardp->ioport = iop;
17203
17204 ASC_DBG2(1,
17205 "advansys_board_found: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
17206 (ushort)inp(iop + 1), (ushort)inpw(iop));
17207 }
17208
17209 #ifdef CONFIG_PROC_FS
17210 /*
17211 * Allocate buffer for printing information from
17212 * /proc/scsi/advansys/[0...].
17213 */
17214 boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
17215 if (!boardp->prtbuf) {
17216 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
17217 "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
17218 goto err_unmap;
17219 }
17220 #endif /* CONFIG_PROC_FS */
17221
17222 if (ASC_NARROW_BOARD(boardp)) {
17223 asc_dvc_varp->cfg->dev = dev;
17224 /*
17225 * Set the board bus type and PCI IRQ before
17226 * calling AscInitGetConfig().
17227 */
17228 switch (asc_dvc_varp->bus_type) {
17229 #ifdef CONFIG_ISA
17230 case ASC_IS_ISA:
17231 shost->unchecked_isa_dma = TRUE;
17232 share_irq = 0;
17233 break;
17234 case ASC_IS_VL:
17235 shost->unchecked_isa_dma = FALSE;
17236 share_irq = 0;
17237 break;
17238 case ASC_IS_EISA:
17239 shost->unchecked_isa_dma = FALSE;
17240 share_irq = IRQF_SHARED;
17241 break;
17242 #endif /* CONFIG_ISA */
17243 #ifdef CONFIG_PCI
17244 case ASC_IS_PCI:
17245 shost->irq = asc_dvc_varp->irq_no = pdev->irq;
17246 asc_dvc_varp->cfg->pci_slot_info =
17247 ASC_PCI_MKID(pdev->bus->number,
17248 PCI_SLOT(pdev->devfn),
17249 PCI_FUNC(pdev->devfn));
17250 shost->unchecked_isa_dma = FALSE;
17251 share_irq = IRQF_SHARED;
17252 break;
17253 #endif /* CONFIG_PCI */
17254 default:
17255 ASC_PRINT2
17256 ("advansys_board_found: board %d: unknown adapter type: %d\n",
17257 boardp->id, asc_dvc_varp->bus_type);
17258 shost->unchecked_isa_dma = TRUE;
17259 share_irq = 0;
17260 break;
17261 }
17262 } else {
17263 adv_dvc_varp->cfg->dev = dev;
17264 /*
17265 * For Wide boards set PCI information before calling
17266 * AdvInitGetConfig().
17267 */
17268 #ifdef CONFIG_PCI
17269 shost->irq = adv_dvc_varp->irq_no = pdev->irq;
17270 adv_dvc_varp->cfg->pci_slot_info =
17271 ASC_PCI_MKID(pdev->bus->number,
17272 PCI_SLOT(pdev->devfn),
17273 PCI_FUNC(pdev->devfn));
17274 shost->unchecked_isa_dma = FALSE;
17275 share_irq = IRQF_SHARED;
17276 #endif /* CONFIG_PCI */
17277 }
17278
17279 /*
17280 * Read the board configuration.
17281 */
17282 if (ASC_NARROW_BOARD(boardp)) {
17283 /*
17284 * NOTE: AscInitGetConfig() may change the board's
17285 * bus_type value. The bus_type value should no
17286 * longer be used. If the bus_type field must be
17287 * referenced only use the bit-wise AND operator "&".
17288 */
17289 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
17290 switch (ret = AscInitGetConfig(asc_dvc_varp)) {
17291 case 0: /* No error */
17292 break;
17293 case ASC_WARN_IO_PORT_ROTATE:
17294 ASC_PRINT1
17295 ("AscInitGetConfig: board %d: I/O port address modified\n",
17296 boardp->id);
17297 break;
17298 case ASC_WARN_AUTO_CONFIG:
17299 ASC_PRINT1
17300 ("AscInitGetConfig: board %d: I/O port increment switch enabled\n",
17301 boardp->id);
17302 break;
17303 case ASC_WARN_EEPROM_CHKSUM:
17304 ASC_PRINT1
17305 ("AscInitGetConfig: board %d: EEPROM checksum error\n",
17306 boardp->id);
17307 break;
17308 case ASC_WARN_IRQ_MODIFIED:
17309 ASC_PRINT1
17310 ("AscInitGetConfig: board %d: IRQ modified\n",
17311 boardp->id);
17312 break;
17313 case ASC_WARN_CMD_QNG_CONFLICT:
17314 ASC_PRINT1
17315 ("AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
17316 boardp->id);
17317 break;
17318 default:
17319 ASC_PRINT2
17320 ("AscInitGetConfig: board %d: unknown warning: 0x%x\n",
17321 boardp->id, ret);
17322 break;
17323 }
17324 if ((err_code = asc_dvc_varp->err_code) != 0) {
17325 ASC_PRINT3
17326 ("AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
17327 boardp->id,
17328 asc_dvc_varp->init_state, asc_dvc_varp->err_code);
17329 }
17330 } else {
17331 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
17332 if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
17333 ASC_PRINT2
17334 ("AdvInitGetConfig: board %d: warning: 0x%x\n",
17335 boardp->id, ret);
17336 }
17337 if ((err_code = adv_dvc_varp->err_code) != 0) {
17338 ASC_PRINT2
17339 ("AdvInitGetConfig: board %d error: err_code 0x%x\n",
17340 boardp->id, adv_dvc_varp->err_code);
17341 }
17342 }
17343
17344 if (err_code != 0)
17345 goto err_free_proc;
17346
17347 /*
17348 * Save the EEPROM configuration so that it can be displayed
17349 * from /proc/scsi/advansys/[0...].
17350 */
17351 if (ASC_NARROW_BOARD(boardp)) {
17352
17353 ASCEEP_CONFIG *ep;
17354
17355 /*
17356 * Set the adapter's target id bit in the 'init_tidmask' field.
17357 */
17358 boardp->init_tidmask |=
17359 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
17360
17361 /*
17362 * Save EEPROM settings for the board.
17363 */
17364 ep = &boardp->eep_config.asc_eep;
17365
17366 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
17367 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
17368 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
17369 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
17370 ep->start_motor = asc_dvc_varp->start_motor;
17371 ep->cntl = asc_dvc_varp->dvc_cntl;
17372 ep->no_scam = asc_dvc_varp->no_scam;
17373 ep->max_total_qng = asc_dvc_varp->max_total_qng;
17374 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
17375 /* 'max_tag_qng' is set to the same value for every device. */
17376 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
17377 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
17378 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
17379 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
17380 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
17381 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
17382 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
17383
17384 /*
17385 * Modify board configuration.
17386 */
17387 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
17388 switch (ret = AscInitSetConfig(asc_dvc_varp)) {
17389 case 0: /* No error. */
17390 break;
17391 case ASC_WARN_IO_PORT_ROTATE:
17392 ASC_PRINT1
17393 ("AscInitSetConfig: board %d: I/O port address modified\n",
17394 boardp->id);
17395 break;
17396 case ASC_WARN_AUTO_CONFIG:
17397 ASC_PRINT1
17398 ("AscInitSetConfig: board %d: I/O port increment switch enabled\n",
17399 boardp->id);
17400 break;
17401 case ASC_WARN_EEPROM_CHKSUM:
17402 ASC_PRINT1
17403 ("AscInitSetConfig: board %d: EEPROM checksum error\n",
17404 boardp->id);
17405 break;
17406 case ASC_WARN_IRQ_MODIFIED:
17407 ASC_PRINT1
17408 ("AscInitSetConfig: board %d: IRQ modified\n",
17409 boardp->id);
17410 break;
17411 case ASC_WARN_CMD_QNG_CONFLICT:
17412 ASC_PRINT1
17413 ("AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
17414 boardp->id);
17415 break;
17416 default:
17417 ASC_PRINT2
17418 ("AscInitSetConfig: board %d: unknown warning: 0x%x\n",
17419 boardp->id, ret);
17420 break;
17421 }
17422 if (asc_dvc_varp->err_code != 0) {
17423 ASC_PRINT3
17424 ("AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
17425 boardp->id,
17426 asc_dvc_varp->init_state, asc_dvc_varp->err_code);
17427 goto err_free_proc;
17428 }
17429
17430 /*
17431 * Finish initializing the 'Scsi_Host' structure.
17432 */
17433 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
17434 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
17435 shost->irq = asc_dvc_varp->irq_no;
17436 }
17437 } else {
17438 ADVEEP_3550_CONFIG *ep_3550;
17439 ADVEEP_38C0800_CONFIG *ep_38C0800;
17440 ADVEEP_38C1600_CONFIG *ep_38C1600;
17441
17442 /*
17443 * Save Wide EEP Configuration Information.
17444 */
17445 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17446 ep_3550 = &boardp->eep_config.adv_3550_eep;
17447
17448 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
17449 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
17450 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17451 ep_3550->termination = adv_dvc_varp->cfg->termination;
17452 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
17453 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
17454 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
17455 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
17456 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
17457 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
17458 ep_3550->start_motor = adv_dvc_varp->start_motor;
17459 ep_3550->scsi_reset_delay =
17460 adv_dvc_varp->scsi_reset_wait;
17461 ep_3550->serial_number_word1 =
17462 adv_dvc_varp->cfg->serial1;
17463 ep_3550->serial_number_word2 =
17464 adv_dvc_varp->cfg->serial2;
17465 ep_3550->serial_number_word3 =
17466 adv_dvc_varp->cfg->serial3;
17467 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17468 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
17469
17470 ep_38C0800->adapter_scsi_id =
17471 adv_dvc_varp->chip_scsi_id;
17472 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
17473 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17474 ep_38C0800->termination_lvd =
17475 adv_dvc_varp->cfg->termination;
17476 ep_38C0800->disc_enable =
17477 adv_dvc_varp->cfg->disc_enable;
17478 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
17479 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
17480 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
17481 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
17482 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
17483 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
17484 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
17485 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
17486 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
17487 ep_38C0800->scsi_reset_delay =
17488 adv_dvc_varp->scsi_reset_wait;
17489 ep_38C0800->serial_number_word1 =
17490 adv_dvc_varp->cfg->serial1;
17491 ep_38C0800->serial_number_word2 =
17492 adv_dvc_varp->cfg->serial2;
17493 ep_38C0800->serial_number_word3 =
17494 adv_dvc_varp->cfg->serial3;
17495 } else {
17496 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
17497
17498 ep_38C1600->adapter_scsi_id =
17499 adv_dvc_varp->chip_scsi_id;
17500 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
17501 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17502 ep_38C1600->termination_lvd =
17503 adv_dvc_varp->cfg->termination;
17504 ep_38C1600->disc_enable =
17505 adv_dvc_varp->cfg->disc_enable;
17506 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
17507 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
17508 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
17509 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
17510 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
17511 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
17512 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
17513 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
17514 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
17515 ep_38C1600->scsi_reset_delay =
17516 adv_dvc_varp->scsi_reset_wait;
17517 ep_38C1600->serial_number_word1 =
17518 adv_dvc_varp->cfg->serial1;
17519 ep_38C1600->serial_number_word2 =
17520 adv_dvc_varp->cfg->serial2;
17521 ep_38C1600->serial_number_word3 =
17522 adv_dvc_varp->cfg->serial3;
17523 }
17524
17525 /*
17526 * Set the adapter's target id bit in the 'init_tidmask' field.
17527 */
17528 boardp->init_tidmask |=
17529 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
17530 }
17531
17532 /*
17533 * Channels are numbered beginning with 0. For AdvanSys one host
17534 * structure supports one channel. Multi-channel boards have a
17535 * separate host structure for each channel.
17536 */
17537 shost->max_channel = 0;
17538 if (ASC_NARROW_BOARD(boardp)) {
17539 shost->max_id = ASC_MAX_TID + 1;
17540 shost->max_lun = ASC_MAX_LUN + 1;
17541
17542 shost->io_port = asc_dvc_varp->iop_base;
17543 boardp->asc_n_io_port = ASC_IOADR_GAP;
17544 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
17545
17546 /* Set maximum number of queues the adapter can handle. */
17547 shost->can_queue = asc_dvc_varp->max_total_qng;
17548 } else {
17549 shost->max_id = ADV_MAX_TID + 1;
17550 shost->max_lun = ADV_MAX_LUN + 1;
17551
17552 /*
17553 * Save the I/O Port address and length even though
17554 * I/O ports are not used to access Wide boards.
17555 * Instead the Wide boards are accessed with
17556 * PCI Memory Mapped I/O.
17557 */
17558 shost->io_port = iop;
17559 boardp->asc_n_io_port = iolen;
17560
17561 shost->this_id = adv_dvc_varp->chip_scsi_id;
17562
17563 /* Set maximum number of queues the adapter can handle. */
17564 shost->can_queue = adv_dvc_varp->max_host_qng;
17565 }
17566
17567 /*
17568 * 'n_io_port' currently is one byte.
17569 *
17570 * Set a value to 'n_io_port', but never referenced it because
17571 * it may be truncated.
17572 */
17573 shost->n_io_port = boardp->asc_n_io_port <= 255 ?
17574 boardp->asc_n_io_port : 255;
17575
17576 /*
17577 * Following v1.3.89, 'cmd_per_lun' is no longer needed
17578 * and should be set to zero.
17579 *
17580 * But because of a bug introduced in v1.3.89 if the driver is
17581 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
17582 * SCSI function 'allocate_device' will panic. To allow the driver
17583 * to work as a module in these kernels set 'cmd_per_lun' to 1.
17584 *
17585 * Note: This is wrong. cmd_per_lun should be set to the depth
17586 * you want on untagged devices always.
17587 #ifdef MODULE
17588 */
17589 shost->cmd_per_lun = 1;
17590 /* #else
17591 shost->cmd_per_lun = 0;
17592 #endif */
17593
17594 /*
17595 * Set the maximum number of scatter-gather elements the
17596 * adapter can handle.
17597 */
17598 if (ASC_NARROW_BOARD(boardp)) {
17599 /*
17600 * Allow two commands with 'sg_tablesize' scatter-gather
17601 * elements to be executed simultaneously. This value is
17602 * the theoretical hardware limit. It may be decreased
17603 * below.
17604 */
17605 shost->sg_tablesize =
17606 (((asc_dvc_varp->max_total_qng - 2) / 2) *
17607 ASC_SG_LIST_PER_Q) + 1;
17608 } else {
17609 shost->sg_tablesize = ADV_MAX_SG_LIST;
17610 }
17611
17612 /*
17613 * The value of 'sg_tablesize' can not exceed the SCSI
17614 * mid-level driver definition of SG_ALL. SG_ALL also
17615 * must not be exceeded, because it is used to define the
17616 * size of the scatter-gather table in 'struct asc_sg_head'.
17617 */
17618 if (shost->sg_tablesize > SG_ALL) {
17619 shost->sg_tablesize = SG_ALL;
17620 }
17621
17622 ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize);
17623
17624 /* BIOS start address. */
17625 if (ASC_NARROW_BOARD(boardp)) {
17626 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
17627 asc_dvc_varp->bus_type);
17628 } else {
17629 /*
17630 * Fill-in BIOS board variables. The Wide BIOS saves
17631 * information in LRAM that is used by the driver.
17632 */
17633 AdvReadWordLram(adv_dvc_varp->iop_base,
17634 BIOS_SIGNATURE, boardp->bios_signature);
17635 AdvReadWordLram(adv_dvc_varp->iop_base,
17636 BIOS_VERSION, boardp->bios_version);
17637 AdvReadWordLram(adv_dvc_varp->iop_base,
17638 BIOS_CODESEG, boardp->bios_codeseg);
17639 AdvReadWordLram(adv_dvc_varp->iop_base,
17640 BIOS_CODELEN, boardp->bios_codelen);
17641
17642 ASC_DBG2(1,
17643 "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n",
17644 boardp->bios_signature, boardp->bios_version);
17645
17646 ASC_DBG2(1,
17647 "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n",
17648 boardp->bios_codeseg, boardp->bios_codelen);
17649
17650 /*
17651 * If the BIOS saved a valid signature, then fill in
17652 * the BIOS code segment base address.
17653 */
17654 if (boardp->bios_signature == 0x55AA) {
17655 /*
17656 * Convert x86 realmode code segment to a linear
17657 * address by shifting left 4.
17658 */
17659 shost->base = ((ulong)boardp->bios_codeseg << 4);
17660 } else {
17661 shost->base = 0;
17662 }
17663 }
17664
17665 /*
17666 * Register Board Resources - I/O Port, DMA, IRQ
17667 */
17668
17669 /* Register DMA Channel for Narrow boards. */
17670 shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
17671 #ifdef CONFIG_ISA
17672 if (ASC_NARROW_BOARD(boardp)) {
17673 /* Register DMA channel for ISA bus. */
17674 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
17675 shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
17676 ret = request_dma(shost->dma_channel, "advansys");
17677 if (ret) {
17678 ASC_PRINT3
17679 ("advansys_board_found: board %d: request_dma() %d failed %d\n",
17680 boardp->id, shost->dma_channel, ret);
17681 goto err_free_proc;
17682 }
17683 AscEnableIsaDma(shost->dma_channel);
17684 }
17685 }
17686 #endif /* CONFIG_ISA */
17687
17688 /* Register IRQ Number. */
17689 ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq);
17690
17691 ret = request_irq(shost->irq, advansys_interrupt, share_irq,
17692 "advansys", shost);
17693
17694 if (ret) {
17695 if (ret == -EBUSY) {
17696 ASC_PRINT2
17697 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
17698 boardp->id, shost->irq);
17699 } else if (ret == -EINVAL) {
17700 ASC_PRINT2
17701 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
17702 boardp->id, shost->irq);
17703 } else {
17704 ASC_PRINT3
17705 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
17706 boardp->id, shost->irq, ret);
17707 }
17708 goto err_free_dma;
17709 }
17710
17711 /*
17712 * Initialize board RISC chip and enable interrupts.
17713 */
17714 if (ASC_NARROW_BOARD(boardp)) {
17715 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
17716 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
17717 err_code = asc_dvc_varp->err_code;
17718
17719 if (warn_code || err_code) {
17720 ASC_PRINT4
17721 ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
17722 boardp->id,
17723 asc_dvc_varp->init_state, warn_code, err_code);
17724 }
17725 } else {
17726 err_code = advansys_wide_init_chip(boardp, adv_dvc_varp);
17727 }
17728
17729 if (err_code != 0)
17730 goto err_free_wide_mem;
17731
17732 ASC_DBG_PRT_SCSI_HOST(2, shost);
17733
17734 ret = scsi_add_host(shost, dev);
17735 if (ret)
17736 goto err_free_wide_mem;
17737
17738 scsi_scan_host(shost);
17739 return shost;
17740
17741 err_free_wide_mem:
17742 advansys_wide_free_mem(boardp);
17743 free_irq(shost->irq, shost);
17744 err_free_dma:
17745 if (shost->dma_channel != NO_ISA_DMA)
17746 free_dma(shost->dma_channel);
17747 err_free_proc:
17748 kfree(boardp->prtbuf);
17749 err_unmap:
17750 if (boardp->ioremap_addr)
17751 iounmap(boardp->ioremap_addr);
17752 err_shost:
17753 scsi_host_put(shost);
17754 return NULL;
17755 }
17756
17757 /*
17758 * advansys_release()
17759 *
17760 * Release resources allocated for a single AdvanSys adapter.
17761 */
17762 static int advansys_release(struct Scsi_Host *shost)
17763 {
17764 asc_board_t *boardp;
17765
17766 ASC_DBG(1, "advansys_release: begin\n");
17767 scsi_remove_host(shost);
17768 boardp = ASC_BOARDP(shost);
17769 free_irq(shost->irq, shost);
17770 if (shost->dma_channel != NO_ISA_DMA) {
17771 ASC_DBG(1, "advansys_release: free_dma()\n");
17772 free_dma(shost->dma_channel);
17773 }
17774 if (ASC_WIDE_BOARD(boardp)) {
17775 iounmap(boardp->ioremap_addr);
17776 advansys_wide_free_mem(boardp);
17777 }
17778 kfree(boardp->prtbuf);
17779 scsi_host_put(shost);
17780 ASC_DBG(1, "advansys_release: end\n");
17781 return 0;
17782 }
17783
17784 static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
17785 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
17786 0x0210, 0x0230, 0x0250, 0x0330
17787 };
17788
17789 static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
17790 {
17791 PortAddr iop_base = _asc_def_iop_base[id];
17792 struct Scsi_Host *shost;
17793
17794 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
17795 ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n",
17796 iop_base);
17797 return -ENODEV;
17798 }
17799 ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base);
17800 if (!AscFindSignature(iop_base))
17801 goto nodev;
17802 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
17803 goto nodev;
17804
17805 shost = advansys_board_found(iop_base, dev, ASC_IS_ISA);
17806 if (!shost)
17807 goto nodev;
17808
17809 dev_set_drvdata(dev, shost);
17810 return 0;
17811
17812 nodev:
17813 release_region(iop_base, ASC_IOADR_GAP);
17814 return -ENODEV;
17815 }
17816
17817 static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
17818 {
17819 int ioport = _asc_def_iop_base[id];
17820 advansys_release(dev_get_drvdata(dev));
17821 release_region(ioport, ASC_IOADR_GAP);
17822 return 0;
17823 }
17824
17825 static struct isa_driver advansys_isa_driver = {
17826 .probe = advansys_isa_probe,
17827 .remove = __devexit_p(advansys_isa_remove),
17828 .driver = {
17829 .owner = THIS_MODULE,
17830 .name = "advansys",
17831 },
17832 };
17833
17834 static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
17835 {
17836 PortAddr iop_base = _asc_def_iop_base[id];
17837 struct Scsi_Host *shost;
17838
17839 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
17840 ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n",
17841 iop_base);
17842 return -ENODEV;
17843 }
17844 ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base);
17845 if (!AscFindSignature(iop_base))
17846 goto nodev;
17847 /*
17848 * I don't think this condition can actually happen, but the old
17849 * driver did it, and the chances of finding a VLB setup in 2007
17850 * to do testing with is slight to none.
17851 */
17852 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
17853 goto nodev;
17854
17855 shost = advansys_board_found(iop_base, dev, ASC_IS_VL);
17856 if (!shost)
17857 goto nodev;
17858
17859 dev_set_drvdata(dev, shost);
17860 return 0;
17861
17862 nodev:
17863 release_region(iop_base, ASC_IOADR_GAP);
17864 return -ENODEV;
17865 }
17866
17867 static struct isa_driver advansys_vlb_driver = {
17868 .probe = advansys_vlb_probe,
17869 .remove = __devexit_p(advansys_isa_remove),
17870 .driver = {
17871 .owner = THIS_MODULE,
17872 .name = "advansys",
17873 },
17874 };
17875
17876 static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
17877 { "ABP7401" },
17878 { "ABP7501" },
17879 { "" }
17880 };
17881
17882 MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
17883
17884 /*
17885 * EISA is a little more tricky than PCI; each EISA device may have two
17886 * channels, and this driver is written to make each channel its own Scsi_Host
17887 */
17888 struct eisa_scsi_data {
17889 struct Scsi_Host *host[2];
17890 };
17891
17892 static int __devinit advansys_eisa_probe(struct device *dev)
17893 {
17894 int i, ioport;
17895 int err;
17896 struct eisa_device *edev = to_eisa_device(dev);
17897 struct eisa_scsi_data *data;
17898
17899 err = -ENOMEM;
17900 data = kzalloc(sizeof(*data), GFP_KERNEL);
17901 if (!data)
17902 goto fail;
17903 ioport = edev->base_addr + 0xc30;
17904
17905 err = -ENODEV;
17906 for (i = 0; i < 2; i++, ioport += 0x20) {
17907 if (!request_region(ioport, ASC_IOADR_GAP, "advansys")) {
17908 printk(KERN_WARNING "Region %x-%x busy\n", ioport,
17909 ioport + ASC_IOADR_GAP - 1);
17910 continue;
17911 }
17912 if (!AscFindSignature(ioport)) {
17913 release_region(ioport, ASC_IOADR_GAP);
17914 continue;
17915 }
17916
17917 /*
17918 * I don't know why we need to do this for EISA chips, but
17919 * not for any others. It looks to be equivalent to
17920 * AscGetChipCfgMsw, but I may have overlooked something,
17921 * so I'm not converting it until I get an EISA board to
17922 * test with.
17923 */
17924 inw(ioport + 4);
17925 data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA);
17926 if (data->host[i]) {
17927 err = 0;
17928 } else {
17929 release_region(ioport, ASC_IOADR_GAP);
17930 }
17931 }
17932
17933 if (err) {
17934 kfree(data);
17935 } else {
17936 dev_set_drvdata(dev, data);
17937 }
17938
17939 fail:
17940 return err;
17941 }
17942
17943 static __devexit int advansys_eisa_remove(struct device *dev)
17944 {
17945 int i;
17946 struct eisa_scsi_data *data = dev_get_drvdata(dev);
17947
17948 for (i = 0; i < 2; i++) {
17949 int ioport;
17950 struct Scsi_Host *shost = data->host[i];
17951 if (!shost)
17952 continue;
17953 ioport = shost->io_port;
17954 advansys_release(shost);
17955 release_region(ioport, ASC_IOADR_GAP);
17956 }
17957
17958 kfree(data);
17959 return 0;
17960 }
17961
17962 static struct eisa_driver advansys_eisa_driver = {
17963 .id_table = advansys_eisa_table,
17964 .driver = {
17965 .name = "advansys",
17966 .probe = advansys_eisa_probe,
17967 .remove = __devexit_p(advansys_eisa_remove),
17968 }
17969 };
17970
17971 /* PCI Devices supported by this driver */
17972 static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
17973 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
17974 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17975 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
17976 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17977 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
17978 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17979 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
17980 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17981 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
17982 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17983 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
17984 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17985 {}
17986 };
17987
17988 MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
17989
17990 static void __devinit advansys_set_latency(struct pci_dev *pdev)
17991 {
17992 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
17993 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
17994 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
17995 } else {
17996 u8 latency;
17997 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
17998 if (latency < 0x20)
17999 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
18000 }
18001 }
18002
18003 static int __devinit
18004 advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
18005 {
18006 int err, ioport;
18007 struct Scsi_Host *shost;
18008
18009 err = pci_enable_device(pdev);
18010 if (err)
18011 goto fail;
18012 err = pci_request_regions(pdev, "advansys");
18013 if (err)
18014 goto disable_device;
18015 pci_set_master(pdev);
18016 advansys_set_latency(pdev);
18017
18018 if (pci_resource_len(pdev, 0) == 0)
18019 goto nodev;
18020
18021 ioport = pci_resource_start(pdev, 0);
18022 shost = advansys_board_found(ioport, &pdev->dev, ASC_IS_PCI);
18023
18024 if (!shost)
18025 goto nodev;
18026
18027 pci_set_drvdata(pdev, shost);
18028 return 0;
18029
18030 nodev:
18031 err = -ENODEV;
18032 pci_release_regions(pdev);
18033 disable_device:
18034 pci_disable_device(pdev);
18035 fail:
18036 return err;
18037 }
18038
18039 static void __devexit advansys_pci_remove(struct pci_dev *pdev)
18040 {
18041 advansys_release(pci_get_drvdata(pdev));
18042 pci_release_regions(pdev);
18043 pci_disable_device(pdev);
18044 }
18045
18046 static struct pci_driver advansys_pci_driver = {
18047 .name = "advansys",
18048 .id_table = advansys_pci_tbl,
18049 .probe = advansys_pci_probe,
18050 .remove = __devexit_p(advansys_pci_remove),
18051 };
18052
18053 static int __init advansys_init(void)
18054 {
18055 int error;
18056
18057 error = isa_register_driver(&advansys_isa_driver,
18058 ASC_IOADR_TABLE_MAX_IX);
18059 if (error)
18060 goto fail;
18061
18062 error = isa_register_driver(&advansys_vlb_driver,
18063 ASC_IOADR_TABLE_MAX_IX);
18064 if (error)
18065 goto unregister_isa;
18066
18067 error = eisa_driver_register(&advansys_eisa_driver);
18068 if (error)
18069 goto unregister_vlb;
18070
18071 error = pci_register_driver(&advansys_pci_driver);
18072 if (error)
18073 goto unregister_eisa;
18074
18075 return 0;
18076
18077 unregister_eisa:
18078 eisa_driver_unregister(&advansys_eisa_driver);
18079 unregister_vlb:
18080 isa_unregister_driver(&advansys_vlb_driver);
18081 unregister_isa:
18082 isa_unregister_driver(&advansys_isa_driver);
18083 fail:
18084 return error;
18085 }
18086
18087 static void __exit advansys_exit(void)
18088 {
18089 pci_unregister_driver(&advansys_pci_driver);
18090 eisa_driver_unregister(&advansys_eisa_driver);
18091 isa_unregister_driver(&advansys_vlb_driver);
18092 isa_unregister_driver(&advansys_isa_driver);
18093 }
18094
18095 module_init(advansys_init);
18096 module_exit(advansys_exit);
18097
18098 MODULE_LICENSE("GPL");