]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - drivers/scsi/advansys.c
[SCSI] advansys: Move struct device out of the cfg structures
[mirror_ubuntu-zesty-kernel.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 } ASC_DVC_CFG;
1384
1385 #define ASC_DEF_DVC_CNTL 0xFFFF
1386 #define ASC_DEF_CHIP_SCSI_ID 7
1387 #define ASC_DEF_ISA_DMA_SPEED 4
1388 #define ASC_INIT_STATE_NULL 0x0000
1389 #define ASC_INIT_STATE_BEG_GET_CFG 0x0001
1390 #define ASC_INIT_STATE_END_GET_CFG 0x0002
1391 #define ASC_INIT_STATE_BEG_SET_CFG 0x0004
1392 #define ASC_INIT_STATE_END_SET_CFG 0x0008
1393 #define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
1394 #define ASC_INIT_STATE_END_LOAD_MC 0x0020
1395 #define ASC_INIT_STATE_BEG_INQUIRY 0x0040
1396 #define ASC_INIT_STATE_END_INQUIRY 0x0080
1397 #define ASC_INIT_RESET_SCSI_DONE 0x0100
1398 #define ASC_INIT_STATE_WITHOUT_EEP 0x8000
1399 #define ASC_BUG_FIX_IF_NOT_DWB 0x0001
1400 #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
1401 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1402 #define ASC_MIN_TAGGED_CMD 7
1403 #define ASC_MAX_SCSI_RESET_WAIT 30
1404
1405 struct asc_dvc_var; /* Forward Declaration. */
1406
1407 typedef void (*ASC_ISR_CALLBACK) (struct asc_dvc_var *, ASC_QDONE_INFO *);
1408 typedef int (*ASC_EXE_CALLBACK) (struct asc_dvc_var *, ASC_SCSI_Q *);
1409
1410 typedef struct asc_dvc_var {
1411 PortAddr iop_base;
1412 ushort err_code;
1413 ushort dvc_cntl;
1414 ushort bug_fix_cntl;
1415 ushort bus_type;
1416 ASC_ISR_CALLBACK isr_callback;
1417 ASC_EXE_CALLBACK exe_callback;
1418 ASC_SCSI_BIT_ID_TYPE init_sdtr;
1419 ASC_SCSI_BIT_ID_TYPE sdtr_done;
1420 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1421 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1422 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1423 ASC_SCSI_BIT_ID_TYPE start_motor;
1424 uchar scsi_reset_wait;
1425 uchar chip_no;
1426 char is_in_int;
1427 uchar max_total_qng;
1428 uchar cur_total_qng;
1429 uchar in_critical_cnt;
1430 uchar irq_no;
1431 uchar last_q_shortage;
1432 ushort init_state;
1433 uchar cur_dvc_qng[ASC_MAX_TID + 1];
1434 uchar max_dvc_qng[ASC_MAX_TID + 1];
1435 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
1436 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
1437 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1438 ASC_DVC_CFG *cfg;
1439 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1440 char redo_scam;
1441 ushort res2;
1442 uchar dos_int13_table[ASC_MAX_TID + 1];
1443 ASC_DCNT max_dma_count;
1444 ASC_SCSI_BIT_ID_TYPE no_scam;
1445 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1446 uchar max_sdtr_index;
1447 uchar host_init_sdtr_index;
1448 struct asc_board *drv_ptr;
1449 ASC_DCNT uc_break;
1450 } ASC_DVC_VAR;
1451
1452 typedef struct asc_dvc_inq_info {
1453 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1454 } ASC_DVC_INQ_INFO;
1455
1456 typedef struct asc_cap_info {
1457 ASC_DCNT lba;
1458 ASC_DCNT blk_size;
1459 } ASC_CAP_INFO;
1460
1461 typedef struct asc_cap_info_array {
1462 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1463 } ASC_CAP_INFO_ARRAY;
1464
1465 #define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
1466 #define ASC_MCNTL_NULL_TARGET (ushort)0x0002
1467 #define ASC_CNTL_INITIATOR (ushort)0x0001
1468 #define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
1469 #define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
1470 #define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
1471 #define ASC_CNTL_NO_SCAM (ushort)0x0010
1472 #define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
1473 #define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
1474 #define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
1475 #define ASC_CNTL_RESET_SCSI (ushort)0x0200
1476 #define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
1477 #define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
1478 #define ASC_CNTL_SCSI_PARITY (ushort)0x1000
1479 #define ASC_CNTL_BURST_MODE (ushort)0x2000
1480 #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1481 #define ASC_EEP_DVC_CFG_BEG_VL 2
1482 #define ASC_EEP_MAX_DVC_ADDR_VL 15
1483 #define ASC_EEP_DVC_CFG_BEG 32
1484 #define ASC_EEP_MAX_DVC_ADDR 45
1485 #define ASC_EEP_DEFINED_WORDS 10
1486 #define ASC_EEP_MAX_ADDR 63
1487 #define ASC_EEP_RES_WORDS 0
1488 #define ASC_EEP_MAX_RETRY 20
1489 #define ASC_MAX_INIT_BUSY_RETRY 8
1490 #define ASC_EEP_ISA_PNP_WSIZE 16
1491
1492 /*
1493 * These macros keep the chip SCSI id and ISA DMA speed
1494 * bitfields in board order. C bitfields aren't portable
1495 * between big and little-endian platforms so they are
1496 * not used.
1497 */
1498
1499 #define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
1500 #define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
1501 #define ASC_EEP_SET_CHIP_ID(cfg, sid) \
1502 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
1503 #define ASC_EEP_SET_DMA_SPD(cfg, spd) \
1504 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
1505
1506 typedef struct asceep_config {
1507 ushort cfg_lsw;
1508 ushort cfg_msw;
1509 uchar init_sdtr;
1510 uchar disc_enable;
1511 uchar use_cmd_qng;
1512 uchar start_motor;
1513 uchar max_total_qng;
1514 uchar max_tag_qng;
1515 uchar bios_scan;
1516 uchar power_up_wait;
1517 uchar no_scam;
1518 uchar id_speed; /* low order 4 bits is chip scsi id */
1519 /* high order 4 bits is isa dma speed */
1520 uchar dos_int13_table[ASC_MAX_TID + 1];
1521 uchar adapter_info[6];
1522 ushort cntl;
1523 ushort chksum;
1524 } ASCEEP_CONFIG;
1525
1526 #define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800
1527 #define ASC_PCI_CFG_LSW_BURST_MODE 0x0080
1528 #define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020
1529
1530 #define ASC_EEP_CMD_READ 0x80
1531 #define ASC_EEP_CMD_WRITE 0x40
1532 #define ASC_EEP_CMD_WRITE_ABLE 0x30
1533 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
1534 #define ASC_OVERRUN_BSIZE 0x00000048UL
1535 #define ASC_CTRL_BREAK_ONCE 0x0001
1536 #define ASC_CTRL_BREAK_STAY_IDLE 0x0002
1537 #define ASCV_MSGOUT_BEG 0x0000
1538 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1539 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1540 #define ASCV_BREAK_SAVED_CODE (ushort)0x0006
1541 #define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
1542 #define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
1543 #define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
1544 #define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
1545 #define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
1546 #define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
1547 #define ASCV_BREAK_ADDR (ushort)0x0028
1548 #define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
1549 #define ASCV_BREAK_CONTROL (ushort)0x002C
1550 #define ASCV_BREAK_HIT_COUNT (ushort)0x002E
1551
1552 #define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
1553 #define ASCV_MCODE_CHKSUM_W (ushort)0x0032
1554 #define ASCV_MCODE_SIZE_W (ushort)0x0034
1555 #define ASCV_STOP_CODE_B (ushort)0x0036
1556 #define ASCV_DVC_ERR_CODE_B (ushort)0x0037
1557 #define ASCV_OVERRUN_PADDR_D (ushort)0x0038
1558 #define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
1559 #define ASCV_HALTCODE_W (ushort)0x0040
1560 #define ASCV_CHKSUM_W (ushort)0x0042
1561 #define ASCV_MC_DATE_W (ushort)0x0044
1562 #define ASCV_MC_VER_W (ushort)0x0046
1563 #define ASCV_NEXTRDY_B (ushort)0x0048
1564 #define ASCV_DONENEXT_B (ushort)0x0049
1565 #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1566 #define ASCV_SCSIBUSY_B (ushort)0x004B
1567 #define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
1568 #define ASCV_CURCDB_B (ushort)0x004D
1569 #define ASCV_RCLUN_B (ushort)0x004E
1570 #define ASCV_BUSY_QHEAD_B (ushort)0x004F
1571 #define ASCV_DISC1_QHEAD_B (ushort)0x0050
1572 #define ASCV_DISC_ENABLE_B (ushort)0x0052
1573 #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1574 #define ASCV_HOSTSCSI_ID_B (ushort)0x0055
1575 #define ASCV_MCODE_CNTL_B (ushort)0x0056
1576 #define ASCV_NULL_TARGET_B (ushort)0x0057
1577 #define ASCV_FREE_Q_HEAD_W (ushort)0x0058
1578 #define ASCV_DONE_Q_TAIL_W (ushort)0x005A
1579 #define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
1580 #define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
1581 #define ASCV_HOST_FLAG_B (ushort)0x005D
1582 #define ASCV_TOTAL_READY_Q_B (ushort)0x0064
1583 #define ASCV_VER_SERIAL_B (ushort)0x0065
1584 #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1585 #define ASCV_WTM_FLAG_B (ushort)0x0068
1586 #define ASCV_RISC_FLAG_B (ushort)0x006A
1587 #define ASCV_REQ_SG_LIST_QP (ushort)0x006B
1588 #define ASC_HOST_FLAG_IN_ISR 0x01
1589 #define ASC_HOST_FLAG_ACK_INT 0x02
1590 #define ASC_RISC_FLAG_GEN_INT 0x01
1591 #define ASC_RISC_FLAG_REQ_SG_LIST 0x02
1592 #define IOP_CTRL (0x0F)
1593 #define IOP_STATUS (0x0E)
1594 #define IOP_INT_ACK IOP_STATUS
1595 #define IOP_REG_IFC (0x0D)
1596 #define IOP_SYN_OFFSET (0x0B)
1597 #define IOP_EXTRA_CONTROL (0x0D)
1598 #define IOP_REG_PC (0x0C)
1599 #define IOP_RAM_ADDR (0x0A)
1600 #define IOP_RAM_DATA (0x08)
1601 #define IOP_EEP_DATA (0x06)
1602 #define IOP_EEP_CMD (0x07)
1603 #define IOP_VERSION (0x03)
1604 #define IOP_CONFIG_HIGH (0x04)
1605 #define IOP_CONFIG_LOW (0x02)
1606 #define IOP_SIG_BYTE (0x01)
1607 #define IOP_SIG_WORD (0x00)
1608 #define IOP_REG_DC1 (0x0E)
1609 #define IOP_REG_DC0 (0x0C)
1610 #define IOP_REG_SB (0x0B)
1611 #define IOP_REG_DA1 (0x0A)
1612 #define IOP_REG_DA0 (0x08)
1613 #define IOP_REG_SC (0x09)
1614 #define IOP_DMA_SPEED (0x07)
1615 #define IOP_REG_FLAG (0x07)
1616 #define IOP_FIFO_H (0x06)
1617 #define IOP_FIFO_L (0x04)
1618 #define IOP_REG_ID (0x05)
1619 #define IOP_REG_QP (0x03)
1620 #define IOP_REG_IH (0x02)
1621 #define IOP_REG_IX (0x01)
1622 #define IOP_REG_AX (0x00)
1623 #define IFC_REG_LOCK (0x00)
1624 #define IFC_REG_UNLOCK (0x09)
1625 #define IFC_WR_EN_FILTER (0x10)
1626 #define IFC_RD_NO_EEPROM (0x10)
1627 #define IFC_SLEW_RATE (0x20)
1628 #define IFC_ACT_NEG (0x40)
1629 #define IFC_INP_FILTER (0x80)
1630 #define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
1631 #define SC_SEL (uchar)(0x80)
1632 #define SC_BSY (uchar)(0x40)
1633 #define SC_ACK (uchar)(0x20)
1634 #define SC_REQ (uchar)(0x10)
1635 #define SC_ATN (uchar)(0x08)
1636 #define SC_IO (uchar)(0x04)
1637 #define SC_CD (uchar)(0x02)
1638 #define SC_MSG (uchar)(0x01)
1639 #define SEC_SCSI_CTL (uchar)(0x80)
1640 #define SEC_ACTIVE_NEGATE (uchar)(0x40)
1641 #define SEC_SLEW_RATE (uchar)(0x20)
1642 #define SEC_ENABLE_FILTER (uchar)(0x10)
1643 #define ASC_HALT_EXTMSG_IN (ushort)0x8000
1644 #define ASC_HALT_CHK_CONDITION (ushort)0x8100
1645 #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1646 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
1647 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
1648 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1649 #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1650 #define ASC_MAX_QNO 0xF8
1651 #define ASC_DATA_SEC_BEG (ushort)0x0080
1652 #define ASC_DATA_SEC_END (ushort)0x0080
1653 #define ASC_CODE_SEC_BEG (ushort)0x0080
1654 #define ASC_CODE_SEC_END (ushort)0x0080
1655 #define ASC_QADR_BEG (0x4000)
1656 #define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
1657 #define ASC_QADR_END (ushort)0x7FFF
1658 #define ASC_QLAST_ADR (ushort)0x7FC0
1659 #define ASC_QBLK_SIZE 0x40
1660 #define ASC_BIOS_DATA_QBEG 0xF8
1661 #define ASC_MIN_ACTIVE_QNO 0x01
1662 #define ASC_QLINK_END 0xFF
1663 #define ASC_EEPROM_WORDS 0x10
1664 #define ASC_MAX_MGS_LEN 0x10
1665 #define ASC_BIOS_ADDR_DEF 0xDC00
1666 #define ASC_BIOS_SIZE 0x3800
1667 #define ASC_BIOS_RAM_OFF 0x3800
1668 #define ASC_BIOS_RAM_SIZE 0x800
1669 #define ASC_BIOS_MIN_ADDR 0xC000
1670 #define ASC_BIOS_MAX_ADDR 0xEC00
1671 #define ASC_BIOS_BANK_SIZE 0x0400
1672 #define ASC_MCODE_START_ADDR 0x0080
1673 #define ASC_CFG0_HOST_INT_ON 0x0020
1674 #define ASC_CFG0_BIOS_ON 0x0040
1675 #define ASC_CFG0_VERA_BURST_ON 0x0080
1676 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
1677 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
1678 #define ASC_CFG1_LRAM_8BITS_ON 0x0800
1679 #define ASC_CFG_MSW_CLR_MASK 0x3080
1680 #define CSW_TEST1 (ASC_CS_TYPE)0x8000
1681 #define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
1682 #define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
1683 #define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
1684 #define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
1685 #define CSW_TEST2 (ASC_CS_TYPE)0x0400
1686 #define CSW_TEST3 (ASC_CS_TYPE)0x0200
1687 #define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
1688 #define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
1689 #define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
1690 #define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
1691 #define CSW_HALTED (ASC_CS_TYPE)0x0010
1692 #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1693 #define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
1694 #define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
1695 #define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
1696 #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1697 #define CIW_INT_ACK (ASC_CS_TYPE)0x0100
1698 #define CIW_TEST1 (ASC_CS_TYPE)0x0200
1699 #define CIW_TEST2 (ASC_CS_TYPE)0x0400
1700 #define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
1701 #define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
1702 #define CC_CHIP_RESET (uchar)0x80
1703 #define CC_SCSI_RESET (uchar)0x40
1704 #define CC_HALT (uchar)0x20
1705 #define CC_SINGLE_STEP (uchar)0x10
1706 #define CC_DMA_ABLE (uchar)0x08
1707 #define CC_TEST (uchar)0x04
1708 #define CC_BANK_ONE (uchar)0x02
1709 #define CC_DIAG (uchar)0x01
1710 #define ASC_1000_ID0W 0x04C1
1711 #define ASC_1000_ID0W_FIX 0x00C1
1712 #define ASC_1000_ID1B 0x25
1713 #define ASC_EISA_REV_IOP_MASK (0x0C83)
1714 #define ASC_EISA_PID_IOP_MASK (0x0C80)
1715 #define ASC_EISA_CFG_IOP_MASK (0x0C86)
1716 #define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
1717 #define INS_HALTINT (ushort)0x6281
1718 #define INS_HALT (ushort)0x6280
1719 #define INS_SINT (ushort)0x6200
1720 #define INS_RFLAG_WTM (ushort)0x7380
1721 #define ASC_MC_SAVE_CODE_WSIZE 0x500
1722 #define ASC_MC_SAVE_DATA_WSIZE 0x40
1723
1724 typedef struct asc_mc_saved {
1725 ushort data[ASC_MC_SAVE_DATA_WSIZE];
1726 ushort code[ASC_MC_SAVE_CODE_WSIZE];
1727 } ASC_MC_SAVED;
1728
1729 #define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1730 #define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1731 #define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1732 #define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1733 #define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1734 #define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1735 #define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
1736 #define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
1737 #define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1738 #define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1739 #define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1740 #define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1741 #define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1742 #define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1743 #define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1744 #define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
1745 #define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
1746 #define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
1747 #define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
1748 #define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
1749 #define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
1750 #define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
1751 #define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
1752 #define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
1753 #define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
1754 #define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
1755 #define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1756 #define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1757 #define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
1758 #define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
1759 #define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
1760 #define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
1761 #define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1762 #define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
1763 #define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
1764 #define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
1765 #define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
1766 #define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
1767 #define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
1768 #define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
1769 #define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1770 #define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1771 #define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
1772 #define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
1773 #define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
1774 #define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
1775 #define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
1776 #define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
1777 #define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
1778 #define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
1779 #define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
1780 #define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
1781 #define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
1782 #define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
1783 #define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
1784 #define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
1785 #define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
1786 #define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
1787 #define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
1788 #define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
1789 #define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
1790 #define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
1791 #define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
1792 #define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
1793 #define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
1794 #define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
1795 #define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
1796 #define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
1797
1798 static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1799 static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1800 static void AscWaitEEPRead(void);
1801 static void AscWaitEEPWrite(void);
1802 static ushort AscReadEEPWord(PortAddr, uchar);
1803 static ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1804 static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1805 static int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1806 static int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1807 static int AscStartChip(PortAddr);
1808 static int AscStopChip(PortAddr);
1809 static void AscSetChipIH(PortAddr, ushort);
1810 static int AscIsChipHalted(PortAddr);
1811 static void AscAckInterrupt(PortAddr);
1812 static void AscDisableInterrupt(PortAddr);
1813 static void AscEnableInterrupt(PortAddr);
1814 static void AscSetBank(PortAddr, uchar);
1815 static int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1816 #ifdef CONFIG_ISA
1817 static uchar AscGetIsaDmaSpeed(PortAddr);
1818 #endif /* CONFIG_ISA */
1819 static uchar AscReadLramByte(PortAddr, ushort);
1820 static ushort AscReadLramWord(PortAddr, ushort);
1821 #if CC_VERY_LONG_SG_LIST
1822 static ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1823 #endif /* CC_VERY_LONG_SG_LIST */
1824 static void AscWriteLramWord(PortAddr, ushort, ushort);
1825 static void AscWriteLramByte(PortAddr, ushort, uchar);
1826 static ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
1827 static void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1828 static void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1829 static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1830 static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
1831 static ushort AscInitAscDvcVar(ASC_DVC_VAR *);
1832 static ushort AscInitFromEEP(ASC_DVC_VAR *);
1833 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1834 static int AscTestExternalLram(ASC_DVC_VAR *);
1835 static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1836 static uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1837 static void AscSetChipSDTR(PortAddr, uchar, uchar);
1838 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1839 static uchar AscAllocFreeQueue(PortAddr, uchar);
1840 static uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1841 static int AscHostReqRiscHalt(PortAddr);
1842 static int AscStopQueueExe(PortAddr);
1843 static int AscSendScsiQueue(ASC_DVC_VAR *,
1844 ASC_SCSI_Q *scsiq, uchar n_q_required);
1845 static int AscPutReadyQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1846 static int AscPutReadySgListQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1847 static int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1848 static int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1849 static ushort AscInitLram(ASC_DVC_VAR *);
1850 static ushort AscInitQLinkVar(ASC_DVC_VAR *);
1851 static int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1852 static int AscIsrChipHalted(ASC_DVC_VAR *);
1853 static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1854 ASC_QDONE_INFO *, ASC_DCNT);
1855 static int AscIsrQDone(ASC_DVC_VAR *);
1856 #ifdef CONFIG_ISA
1857 static ushort AscGetEisaChipCfg(PortAddr);
1858 #endif /* CONFIG_ISA */
1859 static uchar AscGetChipScsiCtrl(PortAddr);
1860 static uchar AscGetChipVersion(PortAddr, ushort);
1861 static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
1862 static void AscToggleIRQAct(PortAddr);
1863 static inline ulong DvcEnterCritical(void);
1864 static inline void DvcLeaveCritical(ulong);
1865 static void DvcSleepMilliSecond(ASC_DCNT);
1866 static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
1867 static void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1868 static void DvcGetQinfo(PortAddr, ushort, uchar *, int);
1869 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
1870 static void AscAsyncFix(ASC_DVC_VAR *, struct scsi_device *);
1871 static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
1872 static int AscISR(ASC_DVC_VAR *);
1873 static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar);
1874 static int AscSgListToQueue(int);
1875 #ifdef CONFIG_ISA
1876 static void AscEnableIsaDma(uchar);
1877 #endif /* CONFIG_ISA */
1878 static const char *advansys_info(struct Scsi_Host *shost);
1879
1880 /*
1881 * --- Adv Library Constants and Macros
1882 */
1883
1884 #define ADV_LIB_VERSION_MAJOR 5
1885 #define ADV_LIB_VERSION_MINOR 14
1886
1887 /*
1888 * Define Adv Library required special types.
1889 */
1890
1891 /*
1892 * Portable Data Types
1893 *
1894 * Any instance where a 32-bit long or pointer type is assumed
1895 * for precision or HW defined structures, the following define
1896 * types must be used. In Linux the char, short, and int types
1897 * are all consistent at 8, 16, and 32 bits respectively. Pointers
1898 * and long types are 64 bits on Alpha and UltraSPARC.
1899 */
1900 #define ADV_PADDR __u32 /* Physical address data type. */
1901 #define ADV_VADDR __u32 /* Virtual address data type. */
1902 #define ADV_DCNT __u32 /* Unsigned Data count type. */
1903 #define ADV_SDCNT __s32 /* Signed Data count type. */
1904
1905 /*
1906 * These macros are used to convert a virtual address to a
1907 * 32-bit value. This currently can be used on Linux Alpha
1908 * which uses 64-bit virtual address but a 32-bit bus address.
1909 * This is likely to break in the future, but doing this now
1910 * will give us time to change the HW and FW to handle 64-bit
1911 * addresses.
1912 */
1913 #define ADV_VADDR_TO_U32 virt_to_bus
1914 #define ADV_U32_TO_VADDR bus_to_virt
1915
1916 #define AdvPortAddr void __iomem * /* Virtual memory address size */
1917
1918 /*
1919 * Define Adv Library required memory access macros.
1920 */
1921 #define ADV_MEM_READB(addr) readb(addr)
1922 #define ADV_MEM_READW(addr) readw(addr)
1923 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
1924 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
1925 #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
1926
1927 #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
1928
1929 /*
1930 * For wide boards a CDB length maximum of 16 bytes
1931 * is supported.
1932 */
1933 #define ADV_MAX_CDB_LEN 16
1934
1935 /*
1936 * Define total number of simultaneous maximum element scatter-gather
1937 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
1938 * maximum number of outstanding commands per wide host adapter. Each
1939 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
1940 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
1941 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
1942 * structures or 255 scatter-gather elements.
1943 *
1944 */
1945 #define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
1946
1947 /*
1948 * Define Adv Library required maximum number of scatter-gather
1949 * elements per request.
1950 */
1951 #define ADV_MAX_SG_LIST 255
1952
1953 /* Number of SG blocks needed. */
1954 #define ADV_NUM_SG_BLOCK \
1955 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
1956
1957 /* Total contiguous memory needed for SG blocks. */
1958 #define ADV_SG_TOTAL_MEM_SIZE \
1959 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
1960
1961 #define ADV_PAGE_SIZE PAGE_SIZE
1962
1963 #define ADV_NUM_PAGE_CROSSING \
1964 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1965
1966 #define ADV_EEP_DVC_CFG_BEGIN (0x00)
1967 #define ADV_EEP_DVC_CFG_END (0x15)
1968 #define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
1969 #define ADV_EEP_MAX_WORD_ADDR (0x1E)
1970
1971 #define ADV_EEP_DELAY_MS 100
1972
1973 #define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
1974 #define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
1975 /*
1976 * For the ASC3550 Bit 13 is Termination Polarity control bit.
1977 * For later ICs Bit 13 controls whether the CIS (Card Information
1978 * Service Section) is loaded from EEPROM.
1979 */
1980 #define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
1981 #define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
1982 /*
1983 * ASC38C1600 Bit 11
1984 *
1985 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
1986 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
1987 * Function 0 will specify INT B.
1988 *
1989 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
1990 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
1991 * Function 1 will specify INT A.
1992 */
1993 #define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
1994
1995 typedef struct adveep_3550_config {
1996 /* Word Offset, Description */
1997
1998 ushort cfg_lsw; /* 00 power up initialization */
1999 /* bit 13 set - Term Polarity Control */
2000 /* bit 14 set - BIOS Enable */
2001 /* bit 15 set - Big Endian Mode */
2002 ushort cfg_msw; /* 01 unused */
2003 ushort disc_enable; /* 02 disconnect enable */
2004 ushort wdtr_able; /* 03 Wide DTR able */
2005 ushort sdtr_able; /* 04 Synchronous DTR able */
2006 ushort start_motor; /* 05 send start up motor */
2007 ushort tagqng_able; /* 06 tag queuing able */
2008 ushort bios_scan; /* 07 BIOS device control */
2009 ushort scam_tolerant; /* 08 no scam */
2010
2011 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2012 uchar bios_boot_delay; /* power up wait */
2013
2014 uchar scsi_reset_delay; /* 10 reset delay */
2015 uchar bios_id_lun; /* first boot device scsi id & lun */
2016 /* high nibble is lun */
2017 /* low nibble is scsi id */
2018
2019 uchar termination; /* 11 0 - automatic */
2020 /* 1 - low off / high off */
2021 /* 2 - low off / high on */
2022 /* 3 - low on / high on */
2023 /* There is no low on / high off */
2024
2025 uchar reserved1; /* reserved byte (not used) */
2026
2027 ushort bios_ctrl; /* 12 BIOS control bits */
2028 /* bit 0 BIOS don't act as initiator. */
2029 /* bit 1 BIOS > 1 GB support */
2030 /* bit 2 BIOS > 2 Disk Support */
2031 /* bit 3 BIOS don't support removables */
2032 /* bit 4 BIOS support bootable CD */
2033 /* bit 5 BIOS scan enabled */
2034 /* bit 6 BIOS support multiple LUNs */
2035 /* bit 7 BIOS display of message */
2036 /* bit 8 SCAM disabled */
2037 /* bit 9 Reset SCSI bus during init. */
2038 /* bit 10 */
2039 /* bit 11 No verbose initialization. */
2040 /* bit 12 SCSI parity enabled */
2041 /* bit 13 */
2042 /* bit 14 */
2043 /* bit 15 */
2044 ushort ultra_able; /* 13 ULTRA speed able */
2045 ushort reserved2; /* 14 reserved */
2046 uchar max_host_qng; /* 15 maximum host queuing */
2047 uchar max_dvc_qng; /* maximum per device queuing */
2048 ushort dvc_cntl; /* 16 control bit for driver */
2049 ushort bug_fix; /* 17 control bit for bug fix */
2050 ushort serial_number_word1; /* 18 Board serial number word 1 */
2051 ushort serial_number_word2; /* 19 Board serial number word 2 */
2052 ushort serial_number_word3; /* 20 Board serial number word 3 */
2053 ushort check_sum; /* 21 EEP check sum */
2054 uchar oem_name[16]; /* 22 OEM name */
2055 ushort dvc_err_code; /* 30 last device driver error code */
2056 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2057 ushort adv_err_addr; /* 32 last uc error address */
2058 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2059 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2060 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2061 ushort num_of_err; /* 36 number of error */
2062 } ADVEEP_3550_CONFIG;
2063
2064 typedef struct adveep_38C0800_config {
2065 /* Word Offset, Description */
2066
2067 ushort cfg_lsw; /* 00 power up initialization */
2068 /* bit 13 set - Load CIS */
2069 /* bit 14 set - BIOS Enable */
2070 /* bit 15 set - Big Endian Mode */
2071 ushort cfg_msw; /* 01 unused */
2072 ushort disc_enable; /* 02 disconnect enable */
2073 ushort wdtr_able; /* 03 Wide DTR able */
2074 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2075 ushort start_motor; /* 05 send start up motor */
2076 ushort tagqng_able; /* 06 tag queuing able */
2077 ushort bios_scan; /* 07 BIOS device control */
2078 ushort scam_tolerant; /* 08 no scam */
2079
2080 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2081 uchar bios_boot_delay; /* power up wait */
2082
2083 uchar scsi_reset_delay; /* 10 reset delay */
2084 uchar bios_id_lun; /* first boot device scsi id & lun */
2085 /* high nibble is lun */
2086 /* low nibble is scsi id */
2087
2088 uchar termination_se; /* 11 0 - automatic */
2089 /* 1 - low off / high off */
2090 /* 2 - low off / high on */
2091 /* 3 - low on / high on */
2092 /* There is no low on / high off */
2093
2094 uchar termination_lvd; /* 11 0 - automatic */
2095 /* 1 - low off / high off */
2096 /* 2 - low off / high on */
2097 /* 3 - low on / high on */
2098 /* There is no low on / high off */
2099
2100 ushort bios_ctrl; /* 12 BIOS control bits */
2101 /* bit 0 BIOS don't act as initiator. */
2102 /* bit 1 BIOS > 1 GB support */
2103 /* bit 2 BIOS > 2 Disk Support */
2104 /* bit 3 BIOS don't support removables */
2105 /* bit 4 BIOS support bootable CD */
2106 /* bit 5 BIOS scan enabled */
2107 /* bit 6 BIOS support multiple LUNs */
2108 /* bit 7 BIOS display of message */
2109 /* bit 8 SCAM disabled */
2110 /* bit 9 Reset SCSI bus during init. */
2111 /* bit 10 */
2112 /* bit 11 No verbose initialization. */
2113 /* bit 12 SCSI parity enabled */
2114 /* bit 13 */
2115 /* bit 14 */
2116 /* bit 15 */
2117 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2118 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2119 uchar max_host_qng; /* 15 maximum host queueing */
2120 uchar max_dvc_qng; /* maximum per device queuing */
2121 ushort dvc_cntl; /* 16 control bit for driver */
2122 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2123 ushort serial_number_word1; /* 18 Board serial number word 1 */
2124 ushort serial_number_word2; /* 19 Board serial number word 2 */
2125 ushort serial_number_word3; /* 20 Board serial number word 3 */
2126 ushort check_sum; /* 21 EEP check sum */
2127 uchar oem_name[16]; /* 22 OEM name */
2128 ushort dvc_err_code; /* 30 last device driver error code */
2129 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2130 ushort adv_err_addr; /* 32 last uc error address */
2131 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2132 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2133 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2134 ushort reserved36; /* 36 reserved */
2135 ushort reserved37; /* 37 reserved */
2136 ushort reserved38; /* 38 reserved */
2137 ushort reserved39; /* 39 reserved */
2138 ushort reserved40; /* 40 reserved */
2139 ushort reserved41; /* 41 reserved */
2140 ushort reserved42; /* 42 reserved */
2141 ushort reserved43; /* 43 reserved */
2142 ushort reserved44; /* 44 reserved */
2143 ushort reserved45; /* 45 reserved */
2144 ushort reserved46; /* 46 reserved */
2145 ushort reserved47; /* 47 reserved */
2146 ushort reserved48; /* 48 reserved */
2147 ushort reserved49; /* 49 reserved */
2148 ushort reserved50; /* 50 reserved */
2149 ushort reserved51; /* 51 reserved */
2150 ushort reserved52; /* 52 reserved */
2151 ushort reserved53; /* 53 reserved */
2152 ushort reserved54; /* 54 reserved */
2153 ushort reserved55; /* 55 reserved */
2154 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2155 ushort cisprt_msw; /* 57 CIS PTR MSW */
2156 ushort subsysvid; /* 58 SubSystem Vendor ID */
2157 ushort subsysid; /* 59 SubSystem ID */
2158 ushort reserved60; /* 60 reserved */
2159 ushort reserved61; /* 61 reserved */
2160 ushort reserved62; /* 62 reserved */
2161 ushort reserved63; /* 63 reserved */
2162 } ADVEEP_38C0800_CONFIG;
2163
2164 typedef struct adveep_38C1600_config {
2165 /* Word Offset, Description */
2166
2167 ushort cfg_lsw; /* 00 power up initialization */
2168 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
2169 /* clear - Func. 0 INTA, Func. 1 INTB */
2170 /* bit 13 set - Load CIS */
2171 /* bit 14 set - BIOS Enable */
2172 /* bit 15 set - Big Endian Mode */
2173 ushort cfg_msw; /* 01 unused */
2174 ushort disc_enable; /* 02 disconnect enable */
2175 ushort wdtr_able; /* 03 Wide DTR able */
2176 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2177 ushort start_motor; /* 05 send start up motor */
2178 ushort tagqng_able; /* 06 tag queuing able */
2179 ushort bios_scan; /* 07 BIOS device control */
2180 ushort scam_tolerant; /* 08 no scam */
2181
2182 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2183 uchar bios_boot_delay; /* power up wait */
2184
2185 uchar scsi_reset_delay; /* 10 reset delay */
2186 uchar bios_id_lun; /* first boot device scsi id & lun */
2187 /* high nibble is lun */
2188 /* low nibble is scsi id */
2189
2190 uchar termination_se; /* 11 0 - automatic */
2191 /* 1 - low off / high off */
2192 /* 2 - low off / high on */
2193 /* 3 - low on / high on */
2194 /* There is no low on / high off */
2195
2196 uchar termination_lvd; /* 11 0 - automatic */
2197 /* 1 - low off / high off */
2198 /* 2 - low off / high on */
2199 /* 3 - low on / high on */
2200 /* There is no low on / high off */
2201
2202 ushort bios_ctrl; /* 12 BIOS control bits */
2203 /* bit 0 BIOS don't act as initiator. */
2204 /* bit 1 BIOS > 1 GB support */
2205 /* bit 2 BIOS > 2 Disk Support */
2206 /* bit 3 BIOS don't support removables */
2207 /* bit 4 BIOS support bootable CD */
2208 /* bit 5 BIOS scan enabled */
2209 /* bit 6 BIOS support multiple LUNs */
2210 /* bit 7 BIOS display of message */
2211 /* bit 8 SCAM disabled */
2212 /* bit 9 Reset SCSI bus during init. */
2213 /* bit 10 Basic Integrity Checking disabled */
2214 /* bit 11 No verbose initialization. */
2215 /* bit 12 SCSI parity enabled */
2216 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
2217 /* bit 14 */
2218 /* bit 15 */
2219 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2220 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2221 uchar max_host_qng; /* 15 maximum host queueing */
2222 uchar max_dvc_qng; /* maximum per device queuing */
2223 ushort dvc_cntl; /* 16 control bit for driver */
2224 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2225 ushort serial_number_word1; /* 18 Board serial number word 1 */
2226 ushort serial_number_word2; /* 19 Board serial number word 2 */
2227 ushort serial_number_word3; /* 20 Board serial number word 3 */
2228 ushort check_sum; /* 21 EEP check sum */
2229 uchar oem_name[16]; /* 22 OEM name */
2230 ushort dvc_err_code; /* 30 last device driver error code */
2231 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2232 ushort adv_err_addr; /* 32 last uc error address */
2233 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2234 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2235 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2236 ushort reserved36; /* 36 reserved */
2237 ushort reserved37; /* 37 reserved */
2238 ushort reserved38; /* 38 reserved */
2239 ushort reserved39; /* 39 reserved */
2240 ushort reserved40; /* 40 reserved */
2241 ushort reserved41; /* 41 reserved */
2242 ushort reserved42; /* 42 reserved */
2243 ushort reserved43; /* 43 reserved */
2244 ushort reserved44; /* 44 reserved */
2245 ushort reserved45; /* 45 reserved */
2246 ushort reserved46; /* 46 reserved */
2247 ushort reserved47; /* 47 reserved */
2248 ushort reserved48; /* 48 reserved */
2249 ushort reserved49; /* 49 reserved */
2250 ushort reserved50; /* 50 reserved */
2251 ushort reserved51; /* 51 reserved */
2252 ushort reserved52; /* 52 reserved */
2253 ushort reserved53; /* 53 reserved */
2254 ushort reserved54; /* 54 reserved */
2255 ushort reserved55; /* 55 reserved */
2256 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2257 ushort cisprt_msw; /* 57 CIS PTR MSW */
2258 ushort subsysvid; /* 58 SubSystem Vendor ID */
2259 ushort subsysid; /* 59 SubSystem ID */
2260 ushort reserved60; /* 60 reserved */
2261 ushort reserved61; /* 61 reserved */
2262 ushort reserved62; /* 62 reserved */
2263 ushort reserved63; /* 63 reserved */
2264 } ADVEEP_38C1600_CONFIG;
2265
2266 /*
2267 * EEPROM Commands
2268 */
2269 #define ASC_EEP_CMD_DONE 0x0200
2270 #define ASC_EEP_CMD_DONE_ERR 0x0001
2271
2272 /* cfg_word */
2273 #define EEP_CFG_WORD_BIG_ENDIAN 0x8000
2274
2275 /* bios_ctrl */
2276 #define BIOS_CTRL_BIOS 0x0001
2277 #define BIOS_CTRL_EXTENDED_XLAT 0x0002
2278 #define BIOS_CTRL_GT_2_DISK 0x0004
2279 #define BIOS_CTRL_BIOS_REMOVABLE 0x0008
2280 #define BIOS_CTRL_BOOTABLE_CD 0x0010
2281 #define BIOS_CTRL_MULTIPLE_LUN 0x0040
2282 #define BIOS_CTRL_DISPLAY_MSG 0x0080
2283 #define BIOS_CTRL_NO_SCAM 0x0100
2284 #define BIOS_CTRL_RESET_SCSI_BUS 0x0200
2285 #define BIOS_CTRL_INIT_VERBOSE 0x0800
2286 #define BIOS_CTRL_SCSI_PARITY 0x1000
2287 #define BIOS_CTRL_AIPP_DIS 0x2000
2288
2289 #define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
2290
2291 #define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2292
2293 /*
2294 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
2295 * a special 16K Adv Library and Microcode version. After the issue is
2296 * resolved, should restore 32K support.
2297 *
2298 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
2299 */
2300 #define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2301
2302 /*
2303 * Byte I/O register address from base of 'iop_base'.
2304 */
2305 #define IOPB_INTR_STATUS_REG 0x00
2306 #define IOPB_CHIP_ID_1 0x01
2307 #define IOPB_INTR_ENABLES 0x02
2308 #define IOPB_CHIP_TYPE_REV 0x03
2309 #define IOPB_RES_ADDR_4 0x04
2310 #define IOPB_RES_ADDR_5 0x05
2311 #define IOPB_RAM_DATA 0x06
2312 #define IOPB_RES_ADDR_7 0x07
2313 #define IOPB_FLAG_REG 0x08
2314 #define IOPB_RES_ADDR_9 0x09
2315 #define IOPB_RISC_CSR 0x0A
2316 #define IOPB_RES_ADDR_B 0x0B
2317 #define IOPB_RES_ADDR_C 0x0C
2318 #define IOPB_RES_ADDR_D 0x0D
2319 #define IOPB_SOFT_OVER_WR 0x0E
2320 #define IOPB_RES_ADDR_F 0x0F
2321 #define IOPB_MEM_CFG 0x10
2322 #define IOPB_RES_ADDR_11 0x11
2323 #define IOPB_GPIO_DATA 0x12
2324 #define IOPB_RES_ADDR_13 0x13
2325 #define IOPB_FLASH_PAGE 0x14
2326 #define IOPB_RES_ADDR_15 0x15
2327 #define IOPB_GPIO_CNTL 0x16
2328 #define IOPB_RES_ADDR_17 0x17
2329 #define IOPB_FLASH_DATA 0x18
2330 #define IOPB_RES_ADDR_19 0x19
2331 #define IOPB_RES_ADDR_1A 0x1A
2332 #define IOPB_RES_ADDR_1B 0x1B
2333 #define IOPB_RES_ADDR_1C 0x1C
2334 #define IOPB_RES_ADDR_1D 0x1D
2335 #define IOPB_RES_ADDR_1E 0x1E
2336 #define IOPB_RES_ADDR_1F 0x1F
2337 #define IOPB_DMA_CFG0 0x20
2338 #define IOPB_DMA_CFG1 0x21
2339 #define IOPB_TICKLE 0x22
2340 #define IOPB_DMA_REG_WR 0x23
2341 #define IOPB_SDMA_STATUS 0x24
2342 #define IOPB_SCSI_BYTE_CNT 0x25
2343 #define IOPB_HOST_BYTE_CNT 0x26
2344 #define IOPB_BYTE_LEFT_TO_XFER 0x27
2345 #define IOPB_BYTE_TO_XFER_0 0x28
2346 #define IOPB_BYTE_TO_XFER_1 0x29
2347 #define IOPB_BYTE_TO_XFER_2 0x2A
2348 #define IOPB_BYTE_TO_XFER_3 0x2B
2349 #define IOPB_ACC_GRP 0x2C
2350 #define IOPB_RES_ADDR_2D 0x2D
2351 #define IOPB_DEV_ID 0x2E
2352 #define IOPB_RES_ADDR_2F 0x2F
2353 #define IOPB_SCSI_DATA 0x30
2354 #define IOPB_RES_ADDR_31 0x31
2355 #define IOPB_RES_ADDR_32 0x32
2356 #define IOPB_SCSI_DATA_HSHK 0x33
2357 #define IOPB_SCSI_CTRL 0x34
2358 #define IOPB_RES_ADDR_35 0x35
2359 #define IOPB_RES_ADDR_36 0x36
2360 #define IOPB_RES_ADDR_37 0x37
2361 #define IOPB_RAM_BIST 0x38
2362 #define IOPB_PLL_TEST 0x39
2363 #define IOPB_PCI_INT_CFG 0x3A
2364 #define IOPB_RES_ADDR_3B 0x3B
2365 #define IOPB_RFIFO_CNT 0x3C
2366 #define IOPB_RES_ADDR_3D 0x3D
2367 #define IOPB_RES_ADDR_3E 0x3E
2368 #define IOPB_RES_ADDR_3F 0x3F
2369
2370 /*
2371 * Word I/O register address from base of 'iop_base'.
2372 */
2373 #define IOPW_CHIP_ID_0 0x00 /* CID0 */
2374 #define IOPW_CTRL_REG 0x02 /* CC */
2375 #define IOPW_RAM_ADDR 0x04 /* LA */
2376 #define IOPW_RAM_DATA 0x06 /* LD */
2377 #define IOPW_RES_ADDR_08 0x08
2378 #define IOPW_RISC_CSR 0x0A /* CSR */
2379 #define IOPW_SCSI_CFG0 0x0C /* CFG0 */
2380 #define IOPW_SCSI_CFG1 0x0E /* CFG1 */
2381 #define IOPW_RES_ADDR_10 0x10
2382 #define IOPW_SEL_MASK 0x12 /* SM */
2383 #define IOPW_RES_ADDR_14 0x14
2384 #define IOPW_FLASH_ADDR 0x16 /* FA */
2385 #define IOPW_RES_ADDR_18 0x18
2386 #define IOPW_EE_CMD 0x1A /* EC */
2387 #define IOPW_EE_DATA 0x1C /* ED */
2388 #define IOPW_SFIFO_CNT 0x1E /* SFC */
2389 #define IOPW_RES_ADDR_20 0x20
2390 #define IOPW_Q_BASE 0x22 /* QB */
2391 #define IOPW_QP 0x24 /* QP */
2392 #define IOPW_IX 0x26 /* IX */
2393 #define IOPW_SP 0x28 /* SP */
2394 #define IOPW_PC 0x2A /* PC */
2395 #define IOPW_RES_ADDR_2C 0x2C
2396 #define IOPW_RES_ADDR_2E 0x2E
2397 #define IOPW_SCSI_DATA 0x30 /* SD */
2398 #define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
2399 #define IOPW_SCSI_CTRL 0x34 /* SC */
2400 #define IOPW_HSHK_CFG 0x36 /* HCFG */
2401 #define IOPW_SXFR_STATUS 0x36 /* SXS */
2402 #define IOPW_SXFR_CNTL 0x38 /* SXL */
2403 #define IOPW_SXFR_CNTH 0x3A /* SXH */
2404 #define IOPW_RES_ADDR_3C 0x3C
2405 #define IOPW_RFIFO_DATA 0x3E /* RFD */
2406
2407 /*
2408 * Doubleword I/O register address from base of 'iop_base'.
2409 */
2410 #define IOPDW_RES_ADDR_0 0x00
2411 #define IOPDW_RAM_DATA 0x04
2412 #define IOPDW_RES_ADDR_8 0x08
2413 #define IOPDW_RES_ADDR_C 0x0C
2414 #define IOPDW_RES_ADDR_10 0x10
2415 #define IOPDW_COMMA 0x14
2416 #define IOPDW_COMMB 0x18
2417 #define IOPDW_RES_ADDR_1C 0x1C
2418 #define IOPDW_SDMA_ADDR0 0x20
2419 #define IOPDW_SDMA_ADDR1 0x24
2420 #define IOPDW_SDMA_COUNT 0x28
2421 #define IOPDW_SDMA_ERROR 0x2C
2422 #define IOPDW_RDMA_ADDR0 0x30
2423 #define IOPDW_RDMA_ADDR1 0x34
2424 #define IOPDW_RDMA_COUNT 0x38
2425 #define IOPDW_RDMA_ERROR 0x3C
2426
2427 #define ADV_CHIP_ID_BYTE 0x25
2428 #define ADV_CHIP_ID_WORD 0x04C1
2429
2430 #define ADV_SC_SCSI_BUS_RESET 0x2000
2431
2432 #define ADV_INTR_ENABLE_HOST_INTR 0x01
2433 #define ADV_INTR_ENABLE_SEL_INTR 0x02
2434 #define ADV_INTR_ENABLE_DPR_INTR 0x04
2435 #define ADV_INTR_ENABLE_RTA_INTR 0x08
2436 #define ADV_INTR_ENABLE_RMA_INTR 0x10
2437 #define ADV_INTR_ENABLE_RST_INTR 0x20
2438 #define ADV_INTR_ENABLE_DPE_INTR 0x40
2439 #define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
2440
2441 #define ADV_INTR_STATUS_INTRA 0x01
2442 #define ADV_INTR_STATUS_INTRB 0x02
2443 #define ADV_INTR_STATUS_INTRC 0x04
2444
2445 #define ADV_RISC_CSR_STOP (0x0000)
2446 #define ADV_RISC_TEST_COND (0x2000)
2447 #define ADV_RISC_CSR_RUN (0x4000)
2448 #define ADV_RISC_CSR_SINGLE_STEP (0x8000)
2449
2450 #define ADV_CTRL_REG_HOST_INTR 0x0100
2451 #define ADV_CTRL_REG_SEL_INTR 0x0200
2452 #define ADV_CTRL_REG_DPR_INTR 0x0400
2453 #define ADV_CTRL_REG_RTA_INTR 0x0800
2454 #define ADV_CTRL_REG_RMA_INTR 0x1000
2455 #define ADV_CTRL_REG_RES_BIT14 0x2000
2456 #define ADV_CTRL_REG_DPE_INTR 0x4000
2457 #define ADV_CTRL_REG_POWER_DONE 0x8000
2458 #define ADV_CTRL_REG_ANY_INTR 0xFF00
2459
2460 #define ADV_CTRL_REG_CMD_RESET 0x00C6
2461 #define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
2462 #define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
2463 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
2464 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
2465
2466 #define ADV_TICKLE_NOP 0x00
2467 #define ADV_TICKLE_A 0x01
2468 #define ADV_TICKLE_B 0x02
2469 #define ADV_TICKLE_C 0x03
2470
2471 #define ADV_SCSI_CTRL_RSTOUT 0x2000
2472
2473 #define AdvIsIntPending(port) \
2474 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2475
2476 /*
2477 * SCSI_CFG0 Register bit definitions
2478 */
2479 #define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
2480 #define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
2481 #define EVEN_PARITY 0x1000 /* Select Even Parity */
2482 #define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2483 #define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
2484 #define PRIM_MODE 0x0100 /* Primitive SCSI mode */
2485 #define SCAM_EN 0x0080 /* Enable SCAM selection */
2486 #define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2487 #define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2488 #define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
2489 #define OUR_ID 0x000F /* SCSI ID */
2490
2491 /*
2492 * SCSI_CFG1 Register bit definitions
2493 */
2494 #define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
2495 #define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2496 #define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
2497 #define FILTER_SEL 0x0C00 /* Filter Period Selection */
2498 #define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
2499 #define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
2500 #define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
2501 #define ACTIVE_DBL 0x0200 /* Disable Active Negation */
2502 #define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
2503 #define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
2504 #define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
2505 #define TERM_CTL 0x0030 /* External SCSI Termination Bits */
2506 #define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
2507 #define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
2508 #define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
2509
2510 /*
2511 * Addendum for ASC-38C0800 Chip
2512 *
2513 * The ASC-38C1600 Chip uses the same definitions except that the
2514 * bus mode override bits [12:10] have been moved to byte register
2515 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
2516 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
2517 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
2518 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
2519 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
2520 */
2521 #define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
2522 #define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
2523 #define HVD 0x1000 /* HVD Device Detect */
2524 #define LVD 0x0800 /* LVD Device Detect */
2525 #define SE 0x0400 /* SE Device Detect */
2526 #define TERM_LVD 0x00C0 /* LVD Termination Bits */
2527 #define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
2528 #define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
2529 #define TERM_SE 0x0030 /* SE Termination Bits */
2530 #define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
2531 #define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
2532 #define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
2533 #define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
2534 #define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
2535 #define C_DET_SE 0x0003 /* SE Cable Detect Bits */
2536 #define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
2537 #define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
2538
2539 #define CABLE_ILLEGAL_A 0x7
2540 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
2541
2542 #define CABLE_ILLEGAL_B 0xB
2543 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
2544
2545 /*
2546 * MEM_CFG Register bit definitions
2547 */
2548 #define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
2549 #define FAST_EE_CLK 0x20 /* Diagnostic Bit */
2550 #define RAM_SZ 0x1C /* Specify size of RAM to RISC */
2551 #define RAM_SZ_2KB 0x00 /* 2 KB */
2552 #define RAM_SZ_4KB 0x04 /* 4 KB */
2553 #define RAM_SZ_8KB 0x08 /* 8 KB */
2554 #define RAM_SZ_16KB 0x0C /* 16 KB */
2555 #define RAM_SZ_32KB 0x10 /* 32 KB */
2556 #define RAM_SZ_64KB 0x14 /* 64 KB */
2557
2558 /*
2559 * DMA_CFG0 Register bit definitions
2560 *
2561 * This register is only accessible to the host.
2562 */
2563 #define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
2564 #define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
2565 #define FIFO_THRESH_16B 0x00 /* 16 bytes */
2566 #define FIFO_THRESH_32B 0x20 /* 32 bytes */
2567 #define FIFO_THRESH_48B 0x30 /* 48 bytes */
2568 #define FIFO_THRESH_64B 0x40 /* 64 bytes */
2569 #define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
2570 #define FIFO_THRESH_96B 0x60 /* 96 bytes */
2571 #define FIFO_THRESH_112B 0x70 /* 112 bytes */
2572 #define START_CTL 0x0C /* DMA start conditions */
2573 #define START_CTL_TH 0x00 /* Wait threshold level (default) */
2574 #define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
2575 #define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
2576 #define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
2577 #define READ_CMD 0x03 /* Memory Read Method */
2578 #define READ_CMD_MR 0x00 /* Memory Read */
2579 #define READ_CMD_MRL 0x02 /* Memory Read Long */
2580 #define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
2581
2582 /*
2583 * ASC-38C0800 RAM BIST Register bit definitions
2584 */
2585 #define RAM_TEST_MODE 0x80
2586 #define PRE_TEST_MODE 0x40
2587 #define NORMAL_MODE 0x00
2588 #define RAM_TEST_DONE 0x10
2589 #define RAM_TEST_STATUS 0x0F
2590 #define RAM_TEST_HOST_ERROR 0x08
2591 #define RAM_TEST_INTRAM_ERROR 0x04
2592 #define RAM_TEST_RISC_ERROR 0x02
2593 #define RAM_TEST_SCSI_ERROR 0x01
2594 #define RAM_TEST_SUCCESS 0x00
2595 #define PRE_TEST_VALUE 0x05
2596 #define NORMAL_VALUE 0x00
2597
2598 /*
2599 * ASC38C1600 Definitions
2600 *
2601 * IOPB_PCI_INT_CFG Bit Field Definitions
2602 */
2603
2604 #define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
2605
2606 /*
2607 * Bit 1 can be set to change the interrupt for the Function to operate in
2608 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
2609 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
2610 * mode, otherwise the operating mode is undefined.
2611 */
2612 #define TOTEMPOLE 0x02
2613
2614 /*
2615 * Bit 0 can be used to change the Int Pin for the Function. The value is
2616 * 0 by default for both Functions with Function 0 using INT A and Function
2617 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
2618 * INT A is used.
2619 *
2620 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
2621 * value specified in the PCI Configuration Space.
2622 */
2623 #define INTAB 0x01
2624
2625 /* a_advlib.h */
2626
2627 /*
2628 * Adv Library Status Definitions
2629 */
2630 #define ADV_TRUE 1
2631 #define ADV_FALSE 0
2632 #define ADV_NOERROR 1
2633 #define ADV_SUCCESS 1
2634 #define ADV_BUSY 0
2635 #define ADV_ERROR (-1)
2636
2637 /*
2638 * ADV_DVC_VAR 'warn_code' values
2639 */
2640 #define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
2641 #define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
2642 #define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
2643 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */
2644 #define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
2645
2646 #define ADV_MAX_TID 15 /* max. target identifier */
2647 #define ADV_MAX_LUN 7 /* max. logical unit number */
2648
2649 /*
2650 * Error code values are set in ADV_DVC_VAR 'err_code'.
2651 */
2652 #define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */
2653 #define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
2654 #define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */
2655 #define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
2656 #define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */
2657 #define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
2658 #define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */
2659 #define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
2660 #define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
2661 #define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */
2662 #define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */
2663 #define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */
2664 #define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */
2665 #define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */
2666
2667 /*
2668 * Fixed locations of microcode operating variables.
2669 */
2670 #define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
2671 #define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
2672 #define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
2673 #define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
2674 #define ASC_MC_VERSION_NUM 0x003A /* microcode number */
2675 #define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
2676 #define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
2677 #define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
2678 #define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
2679 #define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
2680 #define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
2681 #define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
2682 #define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
2683 #define ASC_MC_CHIP_TYPE 0x009A
2684 #define ASC_MC_INTRB_CODE 0x009B
2685 #define ASC_MC_WDTR_ABLE 0x009C
2686 #define ASC_MC_SDTR_ABLE 0x009E
2687 #define ASC_MC_TAGQNG_ABLE 0x00A0
2688 #define ASC_MC_DISC_ENABLE 0x00A2
2689 #define ASC_MC_IDLE_CMD_STATUS 0x00A4
2690 #define ASC_MC_IDLE_CMD 0x00A6
2691 #define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
2692 #define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
2693 #define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
2694 #define ASC_MC_DEFAULT_MEM_CFG 0x00B0
2695 #define ASC_MC_DEFAULT_SEL_MASK 0x00B2
2696 #define ASC_MC_SDTR_DONE 0x00B6
2697 #define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
2698 #define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
2699 #define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
2700 #define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
2701 #define ASC_MC_WDTR_DONE 0x0124
2702 #define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
2703 #define ASC_MC_ICQ 0x0160
2704 #define ASC_MC_IRQ 0x0164
2705 #define ASC_MC_PPR_ABLE 0x017A
2706
2707 /*
2708 * BIOS LRAM variable absolute offsets.
2709 */
2710 #define BIOS_CODESEG 0x54
2711 #define BIOS_CODELEN 0x56
2712 #define BIOS_SIGNATURE 0x58
2713 #define BIOS_VERSION 0x5A
2714
2715 /*
2716 * Microcode Control Flags
2717 *
2718 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2719 * and handled by the microcode.
2720 */
2721 #define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
2722 #define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
2723
2724 /*
2725 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2726 */
2727 #define HSHK_CFG_WIDE_XFR 0x8000
2728 #define HSHK_CFG_RATE 0x0F00
2729 #define HSHK_CFG_OFFSET 0x001F
2730
2731 #define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
2732 #define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
2733 #define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
2734 #define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
2735
2736 #define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2737 #define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
2738 #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2739 #define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
2740 #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2741
2742 #define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
2743 #define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
2744 #define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
2745 #define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
2746 #define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
2747 /*
2748 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
2749 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
2750 */
2751 #define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
2752 #define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
2753
2754 /*
2755 * All fields here are accessed by the board microcode and need to be
2756 * little-endian.
2757 */
2758 typedef struct adv_carr_t {
2759 ADV_VADDR carr_va; /* Carrier Virtual Address */
2760 ADV_PADDR carr_pa; /* Carrier Physical Address */
2761 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
2762 /*
2763 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
2764 *
2765 * next_vpa [3:1] Reserved Bits
2766 * next_vpa [0] Done Flag set in Response Queue.
2767 */
2768 ADV_VADDR next_vpa;
2769 } ADV_CARR_T;
2770
2771 /*
2772 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2773 */
2774 #define ASC_NEXT_VPA_MASK 0xFFFFFFF0
2775
2776 #define ASC_RQ_DONE 0x00000001
2777 #define ASC_RQ_GOOD 0x00000002
2778 #define ASC_CQ_STOPPER 0x00000000
2779
2780 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2781
2782 #define ADV_CARRIER_NUM_PAGE_CROSSING \
2783 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2784 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2785
2786 #define ADV_CARRIER_BUFSIZE \
2787 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2788
2789 /*
2790 * ASC_SCSI_REQ_Q 'a_flag' definitions
2791 *
2792 * The Adv Library should limit use to the lower nibble (4 bits) of
2793 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2794 */
2795 #define ADV_POLL_REQUEST 0x01 /* poll for request completion */
2796 #define ADV_SCSIQ_DONE 0x02 /* request done */
2797 #define ADV_DONT_RETRY 0x08 /* don't do retry */
2798
2799 #define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
2800 #define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
2801 #define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
2802
2803 /*
2804 * Adapter temporary configuration structure
2805 *
2806 * This structure can be discarded after initialization. Don't add
2807 * fields here needed after initialization.
2808 *
2809 * Field naming convention:
2810 *
2811 * *_enable indicates the field enables or disables a feature. The
2812 * value of the field is never reset.
2813 */
2814 typedef struct adv_dvc_cfg {
2815 ushort disc_enable; /* enable disconnection */
2816 uchar chip_version; /* chip version */
2817 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2818 ushort lib_version; /* Adv Library version number */
2819 ushort control_flag; /* Microcode Control Flag */
2820 ushort mcode_date; /* Microcode date */
2821 ushort mcode_version; /* Microcode version */
2822 ushort pci_slot_info; /* high byte device/function number */
2823 /* bits 7-3 device num., bits 2-0 function num. */
2824 /* low byte bus num. */
2825 ushort serial1; /* EEPROM serial number word 1 */
2826 ushort serial2; /* EEPROM serial number word 2 */
2827 ushort serial3; /* EEPROM serial number word 3 */
2828 } ADV_DVC_CFG;
2829
2830 struct adv_dvc_var;
2831 struct adv_scsi_req_q;
2832
2833 typedef void (*ADV_ISR_CALLBACK)
2834 (struct adv_dvc_var *, struct adv_scsi_req_q *);
2835
2836 typedef void (*ADV_ASYNC_CALLBACK)
2837 (struct adv_dvc_var *, uchar);
2838
2839 /*
2840 * Adapter operation variable structure.
2841 *
2842 * One structure is required per host adapter.
2843 *
2844 * Field naming convention:
2845 *
2846 * *_able indicates both whether a feature should be enabled or disabled
2847 * and whether a device isi capable of the feature. At initialization
2848 * this field may be set, but later if a device is found to be incapable
2849 * of the feature, the field is cleared.
2850 */
2851 typedef struct adv_dvc_var {
2852 AdvPortAddr iop_base; /* I/O port address */
2853 ushort err_code; /* fatal error code */
2854 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
2855 ADV_ISR_CALLBACK isr_callback;
2856 ADV_ASYNC_CALLBACK async_callback;
2857 ushort wdtr_able; /* try WDTR for a device */
2858 ushort sdtr_able; /* try SDTR for a device */
2859 ushort ultra_able; /* try SDTR Ultra speed for a device */
2860 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
2861 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
2862 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
2863 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
2864 ushort tagqng_able; /* try tagged queuing with a device */
2865 ushort ppr_able; /* PPR message capable per TID bitmask. */
2866 uchar max_dvc_qng; /* maximum number of tagged commands per device */
2867 ushort start_motor; /* start motor command allowed */
2868 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
2869 uchar chip_no; /* should be assigned by caller */
2870 uchar max_host_qng; /* maximum number of Q'ed command allowed */
2871 uchar irq_no; /* IRQ number */
2872 ushort no_scam; /* scam_tolerant of EEPROM */
2873 struct asc_board *drv_ptr; /* driver pointer to private structure */
2874 uchar chip_scsi_id; /* chip SCSI target ID */
2875 uchar chip_type;
2876 uchar bist_err_code;
2877 ADV_CARR_T *carrier_buf;
2878 ADV_CARR_T *carr_freelist; /* Carrier free list. */
2879 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
2880 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
2881 ushort carr_pending_cnt; /* Count of pending carriers. */
2882 /*
2883 * Note: The following fields will not be used after initialization. The
2884 * driver may discard the buffer after initialization is done.
2885 */
2886 ADV_DVC_CFG *cfg; /* temporary configuration structure */
2887 } ADV_DVC_VAR;
2888
2889 #define NO_OF_SG_PER_BLOCK 15
2890
2891 typedef struct asc_sg_block {
2892 uchar reserved1;
2893 uchar reserved2;
2894 uchar reserved3;
2895 uchar sg_cnt; /* Valid entries in block. */
2896 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
2897 struct {
2898 ADV_PADDR sg_addr; /* SG element address. */
2899 ADV_DCNT sg_count; /* SG element count. */
2900 } sg_list[NO_OF_SG_PER_BLOCK];
2901 } ADV_SG_BLOCK;
2902
2903 /*
2904 * ADV_SCSI_REQ_Q - microcode request structure
2905 *
2906 * All fields in this structure up to byte 60 are used by the microcode.
2907 * The microcode makes assumptions about the size and ordering of fields
2908 * in this structure. Do not change the structure definition here without
2909 * coordinating the change with the microcode.
2910 *
2911 * All fields accessed by microcode must be maintained in little_endian
2912 * order.
2913 */
2914 typedef struct adv_scsi_req_q {
2915 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
2916 uchar target_cmd;
2917 uchar target_id; /* Device target identifier. */
2918 uchar target_lun; /* Device target logical unit number. */
2919 ADV_PADDR data_addr; /* Data buffer physical address. */
2920 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
2921 ADV_PADDR sense_addr;
2922 ADV_PADDR carr_pa;
2923 uchar mflag;
2924 uchar sense_len;
2925 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
2926 uchar scsi_cntl;
2927 uchar done_status; /* Completion status. */
2928 uchar scsi_status; /* SCSI status byte. */
2929 uchar host_status; /* Ucode host status. */
2930 uchar sg_working_ix;
2931 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
2932 ADV_PADDR sg_real_addr; /* SG list physical address. */
2933 ADV_PADDR scsiq_rptr;
2934 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
2935 ADV_VADDR scsiq_ptr;
2936 ADV_VADDR carr_va;
2937 /*
2938 * End of microcode structure - 60 bytes. The rest of the structure
2939 * is used by the Adv Library and ignored by the microcode.
2940 */
2941 ADV_VADDR srb_ptr;
2942 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
2943 char *vdata_addr; /* Data buffer virtual address. */
2944 uchar a_flag;
2945 uchar pad[2]; /* Pad out to a word boundary. */
2946 } ADV_SCSI_REQ_Q;
2947
2948 /*
2949 * Microcode idle loop commands
2950 */
2951 #define IDLE_CMD_COMPLETED 0
2952 #define IDLE_CMD_STOP_CHIP 0x0001
2953 #define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
2954 #define IDLE_CMD_SEND_INT 0x0004
2955 #define IDLE_CMD_ABORT 0x0008
2956 #define IDLE_CMD_DEVICE_RESET 0x0010
2957 #define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
2958 #define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
2959 #define IDLE_CMD_SCSIREQ 0x0080
2960
2961 #define IDLE_CMD_STATUS_SUCCESS 0x0001
2962 #define IDLE_CMD_STATUS_FAILURE 0x0002
2963
2964 /*
2965 * AdvSendIdleCmd() flag definitions.
2966 */
2967 #define ADV_NOWAIT 0x01
2968
2969 /*
2970 * Wait loop time out values.
2971 */
2972 #define SCSI_WAIT_10_SEC 10UL /* 10 seconds */
2973 #define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
2974 #define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
2975 #define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */
2976 #define SCSI_MAX_RETRY 10 /* retry count */
2977
2978 #define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
2979 #define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
2980 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
2981 #define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
2982
2983 #define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
2984
2985 /*
2986 * Device drivers must define the following functions.
2987 */
2988 static inline ulong DvcEnterCritical(void);
2989 static inline void DvcLeaveCritical(ulong);
2990 static void DvcSleepMilliSecond(ADV_DCNT);
2991 static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
2992 uchar *, ASC_SDCNT *, int);
2993 static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
2994
2995 /*
2996 * Adv Library functions available to drivers.
2997 */
2998 static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
2999 static int AdvISR(ADV_DVC_VAR *);
3000 static int AdvInitAsc3550Driver(ADV_DVC_VAR *);
3001 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
3002 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
3003 static int AdvResetChipAndSB(ADV_DVC_VAR *);
3004 static int AdvResetSB(ADV_DVC_VAR *asc_dvc);
3005
3006 /*
3007 * Internal Adv Library functions.
3008 */
3009 static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
3010 static int AdvInitFrom3550EEP(ADV_DVC_VAR *);
3011 static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
3012 static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
3013 static ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3014 static void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3015 static ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3016 static void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3017 static ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3018 static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3019 static void AdvWaitEEPCmd(AdvPortAddr);
3020 static ushort AdvReadEEPWord(AdvPortAddr, int);
3021
3022 /* Read byte from a register. */
3023 #define AdvReadByteRegister(iop_base, reg_off) \
3024 (ADV_MEM_READB((iop_base) + (reg_off)))
3025
3026 /* Write byte to a register. */
3027 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
3028 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3029
3030 /* Read word (2 bytes) from a register. */
3031 #define AdvReadWordRegister(iop_base, reg_off) \
3032 (ADV_MEM_READW((iop_base) + (reg_off)))
3033
3034 /* Write word (2 bytes) to a register. */
3035 #define AdvWriteWordRegister(iop_base, reg_off, word) \
3036 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
3037
3038 /* Write dword (4 bytes) to a register. */
3039 #define AdvWriteDWordRegister(iop_base, reg_off, dword) \
3040 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
3041
3042 /* Read byte from LRAM. */
3043 #define AdvReadByteLram(iop_base, addr, byte) \
3044 do { \
3045 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3046 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3047 } while (0)
3048
3049 /* Write byte to LRAM. */
3050 #define AdvWriteByteLram(iop_base, addr, byte) \
3051 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3052 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3053
3054 /* Read word (2 bytes) from LRAM. */
3055 #define AdvReadWordLram(iop_base, addr, word) \
3056 do { \
3057 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3058 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3059 } while (0)
3060
3061 /* Write word (2 bytes) to LRAM. */
3062 #define AdvWriteWordLram(iop_base, addr, word) \
3063 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3064 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3065
3066 /* Write little-endian double word (4 bytes) to LRAM */
3067 /* Because of unspecified C language ordering don't use auto-increment. */
3068 #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
3069 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3070 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3071 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3072 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3073 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3074 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3075
3076 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
3077 #define AdvReadWordAutoIncLram(iop_base) \
3078 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3079
3080 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
3081 #define AdvWriteWordAutoIncLram(iop_base, word) \
3082 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3083
3084 /*
3085 * Define macro to check for Condor signature.
3086 *
3087 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3088 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3089 */
3090 #define AdvFindSignature(iop_base) \
3091 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3092 ADV_CHIP_ID_BYTE) && \
3093 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3094 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
3095
3096 /*
3097 * Define macro to Return the version number of the chip at 'iop_base'.
3098 *
3099 * The second parameter 'bus_type' is currently unused.
3100 */
3101 #define AdvGetChipVersion(iop_base, bus_type) \
3102 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3103
3104 /*
3105 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3106 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3107 *
3108 * If the request has not yet been sent to the device it will simply be
3109 * aborted from RISC memory. If the request is disconnected it will be
3110 * aborted on reselection by sending an Abort Message to the target ID.
3111 *
3112 * Return value:
3113 * ADV_TRUE(1) - Queue was successfully aborted.
3114 * ADV_FALSE(0) - Queue was not found on the active queue list.
3115 */
3116 #define AdvAbortQueue(asc_dvc, scsiq) \
3117 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3118 (ADV_DCNT) (scsiq))
3119
3120 /*
3121 * Send a Bus Device Reset Message to the specified target ID.
3122 *
3123 * All outstanding commands will be purged if sending the
3124 * Bus Device Reset Message is successful.
3125 *
3126 * Return Value:
3127 * ADV_TRUE(1) - All requests on the target are purged.
3128 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3129 * are not purged.
3130 */
3131 #define AdvResetDevice(asc_dvc, target_id) \
3132 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3133 (ADV_DCNT) (target_id))
3134
3135 /*
3136 * SCSI Wide Type definition.
3137 */
3138 #define ADV_SCSI_BIT_ID_TYPE ushort
3139
3140 /*
3141 * AdvInitScsiTarget() 'cntl_flag' options.
3142 */
3143 #define ADV_SCAN_LUN 0x01
3144 #define ADV_CAPINFO_NOLUN 0x02
3145
3146 /*
3147 * Convert target id to target id bit mask.
3148 */
3149 #define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
3150
3151 /*
3152 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3153 */
3154
3155 #define QD_NO_STATUS 0x00 /* Request not completed yet. */
3156 #define QD_NO_ERROR 0x01
3157 #define QD_ABORTED_BY_HOST 0x02
3158 #define QD_WITH_ERROR 0x04
3159
3160 #define QHSTA_NO_ERROR 0x00
3161 #define QHSTA_M_SEL_TIMEOUT 0x11
3162 #define QHSTA_M_DATA_OVER_RUN 0x12
3163 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3164 #define QHSTA_M_QUEUE_ABORTED 0x15
3165 #define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
3166 #define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
3167 #define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
3168 #define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
3169 #define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
3170 #define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
3171 #define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
3172 /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
3173 #define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
3174 #define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
3175 #define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
3176 #define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
3177 #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
3178 #define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
3179 #define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
3180 #define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
3181 #define QHSTA_M_WTM_TIMEOUT 0x41
3182 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
3183 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
3184 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
3185 #define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
3186 #define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
3187 #define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
3188
3189 /*
3190 * Default EEPROM Configuration structure defined in a_init.c.
3191 */
3192 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
3193 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
3194 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
3195
3196 /*
3197 * DvcGetPhyAddr() flag arguments
3198 */
3199 #define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
3200 #define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
3201 #define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
3202 #define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
3203 #define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
3204 #define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
3205
3206 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
3207 #define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
3208 #define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
3209 #define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
3210
3211 /*
3212 * Total contiguous memory needed for driver SG blocks.
3213 *
3214 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3215 * number of scatter-gather elements the driver supports in a
3216 * single request.
3217 */
3218
3219 #define ADV_SG_LIST_MAX_BYTE_SIZE \
3220 (sizeof(ADV_SG_BLOCK) * \
3221 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3222
3223 /*
3224 * --- Driver Constants and Macros
3225 */
3226
3227 /* Reference Scsi_Host hostdata */
3228 #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3229
3230 /* asc_board_t flags */
3231 #define ASC_HOST_IN_RESET 0x01
3232 #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
3233 #define ASC_SELECT_QUEUE_DEPTHS 0x08
3234
3235 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3236 #define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD)
3237
3238 #define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
3239
3240 #define ASC_INFO_SIZE 128 /* advansys_info() line size */
3241
3242 #ifdef CONFIG_PROC_FS
3243 /* /proc/scsi/advansys/[0...] related definitions */
3244 #define ASC_PRTBUF_SIZE 2048
3245 #define ASC_PRTLINE_SIZE 160
3246
3247 #define ASC_PRT_NEXT() \
3248 if (cp) { \
3249 totlen += len; \
3250 leftlen -= len; \
3251 if (leftlen == 0) { \
3252 return totlen; \
3253 } \
3254 cp += len; \
3255 }
3256 #endif /* CONFIG_PROC_FS */
3257
3258 /* Asc Library return codes */
3259 #define ASC_TRUE 1
3260 #define ASC_FALSE 0
3261 #define ASC_NOERROR 1
3262 #define ASC_BUSY 0
3263 #define ASC_ERROR (-1)
3264
3265 /* struct scsi_cmnd function return codes */
3266 #define STATUS_BYTE(byte) (byte)
3267 #define MSG_BYTE(byte) ((byte) << 8)
3268 #define HOST_BYTE(byte) ((byte) << 16)
3269 #define DRIVER_BYTE(byte) ((byte) << 24)
3270
3271 /*
3272 * The following definitions and macros are OS independent interfaces to
3273 * the queue functions:
3274 * REQ - SCSI request structure
3275 * REQP - pointer to SCSI request structure
3276 * REQPTID(reqp) - reqp's target id
3277 * REQPNEXT(reqp) - reqp's next pointer
3278 * REQPNEXTP(reqp) - pointer to reqp's next pointer
3279 * REQPTIME(reqp) - reqp's time stamp value
3280 * REQTIMESTAMP() - system time stamp value
3281 */
3282 typedef struct scsi_cmnd REQ, *REQP;
3283 #define REQPNEXT(reqp) ((REQP) ((reqp)->host_scribble))
3284 #define REQPNEXTP(reqp) ((REQP *) &((reqp)->host_scribble))
3285 #define REQPTID(reqp) ((reqp)->device->id)
3286 #define REQPTIME(reqp) ((reqp)->SCp.this_residual)
3287 #define REQTIMESTAMP() (jiffies)
3288
3289 #define REQTIMESTAT(function, ascq, reqp, tid) \
3290 { \
3291 /*
3292 * If the request time stamp is less than the system time stamp, then \
3293 * maybe the system time stamp wrapped. Set the request time to zero.\
3294 */ \
3295 if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3296 REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3297 } else { \
3298 /* Indicate an error occurred with the assertion. */ \
3299 ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3300 REQPTIME(reqp) = 0; \
3301 } \
3302 /* Handle first minimum time case without external initialization. */ \
3303 if (((ascq)->q_tot_cnt[tid] == 1) || \
3304 (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3305 (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3306 ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3307 (function), (tid), (ascq)->q_min_tim[tid]); \
3308 } \
3309 if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3310 (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3311 ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3312 (function), tid, (ascq)->q_max_tim[tid]); \
3313 } \
3314 (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3315 /* Reset the time stamp field. */ \
3316 REQPTIME(reqp) = 0; \
3317 }
3318
3319 /* asc_enqueue() flags */
3320 #define ASC_FRONT 1
3321 #define ASC_BACK 2
3322
3323 /* asc_dequeue_list() argument */
3324 #define ASC_TID_ALL (-1)
3325
3326 /* Return non-zero, if the queue is empty. */
3327 #define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0)
3328
3329 #ifndef ADVANSYS_STATS
3330 #define ASC_STATS(shost, counter)
3331 #define ASC_STATS_ADD(shost, counter, count)
3332 #else /* ADVANSYS_STATS */
3333 #define ASC_STATS(shost, counter) \
3334 (ASC_BOARDP(shost)->asc_stats.counter++)
3335
3336 #define ASC_STATS_ADD(shost, counter, count) \
3337 (ASC_BOARDP(shost)->asc_stats.counter += (count))
3338 #endif /* ADVANSYS_STATS */
3339
3340 #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3341
3342 /* If the result wraps when calculating tenths, return 0. */
3343 #define ASC_TENTHS(num, den) \
3344 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3345 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3346
3347 /*
3348 * Display a message to the console.
3349 */
3350 #define ASC_PRINT(s) \
3351 { \
3352 printk("advansys: "); \
3353 printk(s); \
3354 }
3355
3356 #define ASC_PRINT1(s, a1) \
3357 { \
3358 printk("advansys: "); \
3359 printk((s), (a1)); \
3360 }
3361
3362 #define ASC_PRINT2(s, a1, a2) \
3363 { \
3364 printk("advansys: "); \
3365 printk((s), (a1), (a2)); \
3366 }
3367
3368 #define ASC_PRINT3(s, a1, a2, a3) \
3369 { \
3370 printk("advansys: "); \
3371 printk((s), (a1), (a2), (a3)); \
3372 }
3373
3374 #define ASC_PRINT4(s, a1, a2, a3, a4) \
3375 { \
3376 printk("advansys: "); \
3377 printk((s), (a1), (a2), (a3), (a4)); \
3378 }
3379
3380 #ifndef ADVANSYS_DEBUG
3381
3382 #define ASC_DBG(lvl, s)
3383 #define ASC_DBG1(lvl, s, a1)
3384 #define ASC_DBG2(lvl, s, a1, a2)
3385 #define ASC_DBG3(lvl, s, a1, a2, a3)
3386 #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3387 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3388 #define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3389 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3390 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3391 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3392 #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3393 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
3394 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
3395 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
3396 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3397
3398 #else /* ADVANSYS_DEBUG */
3399
3400 /*
3401 * Debugging Message Levels:
3402 * 0: Errors Only
3403 * 1: High-Level Tracing
3404 * 2-N: Verbose Tracing
3405 */
3406
3407 #define ASC_DBG(lvl, s) \
3408 { \
3409 if (asc_dbglvl >= (lvl)) { \
3410 printk(s); \
3411 } \
3412 }
3413
3414 #define ASC_DBG1(lvl, s, a1) \
3415 { \
3416 if (asc_dbglvl >= (lvl)) { \
3417 printk((s), (a1)); \
3418 } \
3419 }
3420
3421 #define ASC_DBG2(lvl, s, a1, a2) \
3422 { \
3423 if (asc_dbglvl >= (lvl)) { \
3424 printk((s), (a1), (a2)); \
3425 } \
3426 }
3427
3428 #define ASC_DBG3(lvl, s, a1, a2, a3) \
3429 { \
3430 if (asc_dbglvl >= (lvl)) { \
3431 printk((s), (a1), (a2), (a3)); \
3432 } \
3433 }
3434
3435 #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3436 { \
3437 if (asc_dbglvl >= (lvl)) { \
3438 printk((s), (a1), (a2), (a3), (a4)); \
3439 } \
3440 }
3441
3442 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3443 { \
3444 if (asc_dbglvl >= (lvl)) { \
3445 asc_prt_scsi_host(s); \
3446 } \
3447 }
3448
3449 #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3450 { \
3451 if (asc_dbglvl >= (lvl)) { \
3452 asc_prt_scsi_cmnd(s); \
3453 } \
3454 }
3455
3456 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3457 { \
3458 if (asc_dbglvl >= (lvl)) { \
3459 asc_prt_asc_scsi_q(scsiqp); \
3460 } \
3461 }
3462
3463 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3464 { \
3465 if (asc_dbglvl >= (lvl)) { \
3466 asc_prt_asc_qdone_info(qdone); \
3467 } \
3468 }
3469
3470 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3471 { \
3472 if (asc_dbglvl >= (lvl)) { \
3473 asc_prt_adv_scsi_req_q(scsiqp); \
3474 } \
3475 }
3476
3477 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3478 { \
3479 if (asc_dbglvl >= (lvl)) { \
3480 asc_prt_hex((name), (start), (length)); \
3481 } \
3482 }
3483
3484 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3485 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3486
3487 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3488 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3489
3490 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3491 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3492 #endif /* ADVANSYS_DEBUG */
3493
3494 #ifndef ADVANSYS_ASSERT
3495 #define ASC_ASSERT(a)
3496 #else /* ADVANSYS_ASSERT */
3497
3498 #define ASC_ASSERT(a) \
3499 { \
3500 if (!(a)) { \
3501 printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3502 __FILE__, __LINE__); \
3503 } \
3504 }
3505
3506 #endif /* ADVANSYS_ASSERT */
3507
3508 /*
3509 * --- Driver Structures
3510 */
3511
3512 #ifdef ADVANSYS_STATS
3513
3514 /* Per board statistics structure */
3515 struct asc_stats {
3516 /* Driver Entrypoint Statistics */
3517 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
3518 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
3519 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
3520 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
3521 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
3522 ADV_DCNT done; /* # calls to request's scsi_done function */
3523 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
3524 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
3525 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
3526 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3527 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
3528 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
3529 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
3530 ADV_DCNT exe_unknown; /* # unknown returns. */
3531 /* Data Transfer Statistics */
3532 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
3533 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
3534 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
3535 ADV_DCNT sg_elem; /* # scatter-gather elements */
3536 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
3537 };
3538 #endif /* ADVANSYS_STATS */
3539
3540 /*
3541 * Request queuing structure
3542 */
3543 typedef struct asc_queue {
3544 ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */
3545 REQP q_first[ADV_MAX_TID + 1]; /* first queued request */
3546 REQP q_last[ADV_MAX_TID + 1]; /* last queued request */
3547 #ifdef ADVANSYS_STATS
3548 short q_cur_cnt[ADV_MAX_TID + 1]; /* current queue count */
3549 short q_max_cnt[ADV_MAX_TID + 1]; /* maximum queue count */
3550 ADV_DCNT q_tot_cnt[ADV_MAX_TID + 1]; /* total enqueue count */
3551 ADV_DCNT q_tot_tim[ADV_MAX_TID + 1]; /* total time queued */
3552 ushort q_max_tim[ADV_MAX_TID + 1]; /* maximum time queued */
3553 ushort q_min_tim[ADV_MAX_TID + 1]; /* minimum time queued */
3554 #endif /* ADVANSYS_STATS */
3555 } asc_queue_t;
3556
3557 /*
3558 * Adv Library Request Structures
3559 *
3560 * The following two structures are used to process Wide Board requests.
3561 *
3562 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
3563 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
3564 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
3565 * Mid-Level SCSI request structure.
3566 *
3567 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
3568 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
3569 * up to 255 scatter-gather elements may be used per request or
3570 * ADV_SCSI_REQ_Q.
3571 *
3572 * Both structures must be 32 byte aligned.
3573 */
3574 typedef struct adv_sgblk {
3575 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
3576 uchar align[32]; /* Sgblock structure padding. */
3577 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
3578 } adv_sgblk_t;
3579
3580 typedef struct adv_req {
3581 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
3582 uchar align[32]; /* Request structure padding. */
3583 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
3584 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
3585 struct adv_req *next_reqp; /* Next Request Structure. */
3586 } adv_req_t;
3587
3588 /*
3589 * Structure allocated for each board.
3590 *
3591 * This structure is allocated by scsi_host_alloc() at the end
3592 * of the 'Scsi_Host' structure starting at the 'hostdata'
3593 * field. It is guaranteed to be allocated from DMA-able memory.
3594 */
3595 typedef struct asc_board {
3596 struct device *dev;
3597 int id; /* Board Id */
3598 uint flags; /* Board flags */
3599 union {
3600 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
3601 ADV_DVC_VAR adv_dvc_var; /* Wide board */
3602 } dvc_var;
3603 union {
3604 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
3605 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
3606 } dvc_cfg;
3607 ushort asc_n_io_port; /* Number I/O ports. */
3608 asc_queue_t active; /* Active command queue */
3609 asc_queue_t waiting; /* Waiting command queue */
3610 asc_queue_t done; /* Done command queue */
3611 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
3612 struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */
3613 ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
3614 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
3615 ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
3616 union {
3617 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
3618 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
3619 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
3620 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
3621 } eep_config;
3622 ulong last_reset; /* Saved last reset time */
3623 spinlock_t lock; /* Board spinlock */
3624 /* /proc/scsi/advansys/[0...] */
3625 char *prtbuf; /* /proc print buffer */
3626 #ifdef ADVANSYS_STATS
3627 struct asc_stats asc_stats; /* Board statistics */
3628 #endif /* ADVANSYS_STATS */
3629 /*
3630 * The following fields are used only for Narrow Boards.
3631 */
3632 uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */
3633 /*
3634 * The following fields are used only for Wide Boards.
3635 */
3636 void __iomem *ioremap_addr; /* I/O Memory remap address. */
3637 ushort ioport; /* I/O Port address. */
3638 ADV_CARR_T *carrp; /* ADV_CARR_T memory block. */
3639 adv_req_t *orig_reqp; /* adv_req_t memory block. */
3640 adv_req_t *adv_reqp; /* Request structures. */
3641 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
3642 ushort bios_signature; /* BIOS Signature. */
3643 ushort bios_version; /* BIOS Version. */
3644 ushort bios_codeseg; /* BIOS Code Segment. */
3645 ushort bios_codelen; /* BIOS Code Segment Length. */
3646 } asc_board_t;
3647
3648 /* Number of boards detected in system. */
3649 static int asc_board_count;
3650
3651 /* Overrun buffer used by all narrow boards. */
3652 static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
3653
3654 /*
3655 * Global structures required to issue a command.
3656 */
3657 static ASC_SCSI_Q asc_scsi_q = { {0} };
3658 static ASC_SG_HEAD asc_sg_head = { 0 };
3659
3660 #ifdef ADVANSYS_DEBUG
3661 static int asc_dbglvl = 3;
3662 #endif /* ADVANSYS_DEBUG */
3663
3664 /*
3665 * --- Driver Function Prototypes
3666 */
3667
3668 static int advansys_slave_configure(struct scsi_device *);
3669 static void asc_scsi_done_list(struct scsi_cmnd *);
3670 static int asc_execute_scsi_cmnd(struct scsi_cmnd *);
3671 static int asc_build_req(asc_board_t *, struct scsi_cmnd *);
3672 static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
3673 static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
3674 static void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
3675 static void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3676 static void adv_async_callback(ADV_DVC_VAR *, uchar);
3677 static void asc_enqueue(asc_queue_t *, REQP, int);
3678 static REQP asc_dequeue(asc_queue_t *, int);
3679 static REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
3680 static int asc_rmqueue(asc_queue_t *, REQP);
3681 static void asc_execute_queue(asc_queue_t *);
3682 #ifdef CONFIG_PROC_FS
3683 static int asc_proc_copy(off_t, off_t, char *, int, char *, int);
3684 static int asc_prt_board_devices(struct Scsi_Host *, char *, int);
3685 static int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
3686 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
3687 static int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
3688 static int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
3689 static int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
3690 static int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
3691 static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
3692 static int asc_prt_line(char *, int, char *fmt, ...);
3693 #endif /* CONFIG_PROC_FS */
3694
3695 /* Statistics function prototypes. */
3696 #ifdef ADVANSYS_STATS
3697 #ifdef CONFIG_PROC_FS
3698 static int asc_prt_board_stats(struct Scsi_Host *, char *, int);
3699 static int asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
3700 #endif /* CONFIG_PROC_FS */
3701 #endif /* ADVANSYS_STATS */
3702
3703 /* Debug function prototypes. */
3704 #ifdef ADVANSYS_DEBUG
3705 static void asc_prt_scsi_host(struct Scsi_Host *);
3706 static void asc_prt_scsi_cmnd(struct scsi_cmnd *);
3707 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
3708 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
3709 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
3710 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
3711 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
3712 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
3713 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
3714 static void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
3715 static void asc_prt_hex(char *f, uchar *, int);
3716 #endif /* ADVANSYS_DEBUG */
3717
3718 #ifdef CONFIG_PROC_FS
3719 /*
3720 * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
3721 *
3722 * *buffer: I/O buffer
3723 * **start: if inout == FALSE pointer into buffer where user read should start
3724 * offset: current offset into a /proc/scsi/advansys/[0...] file
3725 * length: length of buffer
3726 * hostno: Scsi_Host host_no
3727 * inout: TRUE - user is writing; FALSE - user is reading
3728 *
3729 * Return the number of bytes read from or written to a
3730 * /proc/scsi/advansys/[0...] file.
3731 *
3732 * Note: This function uses the per board buffer 'prtbuf' which is
3733 * allocated when the board is initialized in advansys_detect(). The
3734 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
3735 * used to write to the buffer. The way asc_proc_copy() is written
3736 * if 'prtbuf' is too small it will not be overwritten. Instead the
3737 * user just won't get all the available statistics.
3738 */
3739 static int
3740 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
3741 off_t offset, int length, int inout)
3742 {
3743 asc_board_t *boardp;
3744 char *cp;
3745 int cplen;
3746 int cnt;
3747 int totcnt;
3748 int leftlen;
3749 char *curbuf;
3750 off_t advoffset;
3751 #ifdef ADVANSYS_STATS
3752 int tgt_id;
3753 #endif /* ADVANSYS_STATS */
3754
3755 ASC_DBG(1, "advansys_proc_info: begin\n");
3756
3757 /*
3758 * User write not supported.
3759 */
3760 if (inout == TRUE) {
3761 return (-ENOSYS);
3762 }
3763
3764 /*
3765 * User read of /proc/scsi/advansys/[0...] file.
3766 */
3767
3768 boardp = ASC_BOARDP(shost);
3769
3770 /* Copy read data starting at the beginning of the buffer. */
3771 *start = buffer;
3772 curbuf = buffer;
3773 advoffset = 0;
3774 totcnt = 0;
3775 leftlen = length;
3776
3777 /*
3778 * Get board configuration information.
3779 *
3780 * advansys_info() returns the board string from its own static buffer.
3781 */
3782 cp = (char *)advansys_info(shost);
3783 strcat(cp, "\n");
3784 cplen = strlen(cp);
3785 /* Copy board information. */
3786 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3787 totcnt += cnt;
3788 leftlen -= cnt;
3789 if (leftlen == 0) {
3790 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3791 return totcnt;
3792 }
3793 advoffset += cplen;
3794 curbuf += cnt;
3795
3796 /*
3797 * Display Wide Board BIOS Information.
3798 */
3799 if (ASC_WIDE_BOARD(boardp)) {
3800 cp = boardp->prtbuf;
3801 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
3802 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3803 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
3804 cplen);
3805 totcnt += cnt;
3806 leftlen -= cnt;
3807 if (leftlen == 0) {
3808 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3809 return totcnt;
3810 }
3811 advoffset += cplen;
3812 curbuf += cnt;
3813 }
3814
3815 /*
3816 * Display driver information for each device attached to the board.
3817 */
3818 cp = boardp->prtbuf;
3819 cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
3820 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3821 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3822 totcnt += cnt;
3823 leftlen -= cnt;
3824 if (leftlen == 0) {
3825 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3826 return totcnt;
3827 }
3828 advoffset += cplen;
3829 curbuf += cnt;
3830
3831 /*
3832 * Display EEPROM configuration for the board.
3833 */
3834 cp = boardp->prtbuf;
3835 if (ASC_NARROW_BOARD(boardp)) {
3836 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
3837 } else {
3838 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
3839 }
3840 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3841 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3842 totcnt += cnt;
3843 leftlen -= cnt;
3844 if (leftlen == 0) {
3845 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3846 return totcnt;
3847 }
3848 advoffset += cplen;
3849 curbuf += cnt;
3850
3851 /*
3852 * Display driver configuration and information for the board.
3853 */
3854 cp = boardp->prtbuf;
3855 cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
3856 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3857 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3858 totcnt += cnt;
3859 leftlen -= cnt;
3860 if (leftlen == 0) {
3861 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3862 return totcnt;
3863 }
3864 advoffset += cplen;
3865 curbuf += cnt;
3866
3867 #ifdef ADVANSYS_STATS
3868 /*
3869 * Display driver statistics for the board.
3870 */
3871 cp = boardp->prtbuf;
3872 cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
3873 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
3874 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3875 totcnt += cnt;
3876 leftlen -= cnt;
3877 if (leftlen == 0) {
3878 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3879 return totcnt;
3880 }
3881 advoffset += cplen;
3882 curbuf += cnt;
3883
3884 /*
3885 * Display driver statistics for each target.
3886 */
3887 for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
3888 cp = boardp->prtbuf;
3889 cplen = asc_prt_target_stats(shost, tgt_id, cp,
3890 ASC_PRTBUF_SIZE);
3891 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
3892 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
3893 cplen);
3894 totcnt += cnt;
3895 leftlen -= cnt;
3896 if (leftlen == 0) {
3897 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3898 return totcnt;
3899 }
3900 advoffset += cplen;
3901 curbuf += cnt;
3902 }
3903 #endif /* ADVANSYS_STATS */
3904
3905 /*
3906 * Display Asc Library dynamic configuration information
3907 * for the board.
3908 */
3909 cp = boardp->prtbuf;
3910 if (ASC_NARROW_BOARD(boardp)) {
3911 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
3912 } else {
3913 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
3914 }
3915 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3916 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3917 totcnt += cnt;
3918 leftlen -= cnt;
3919 if (leftlen == 0) {
3920 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3921 return totcnt;
3922 }
3923 advoffset += cplen;
3924 curbuf += cnt;
3925
3926 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3927
3928 return totcnt;
3929 }
3930 #endif /* CONFIG_PROC_FS */
3931
3932 /*
3933 * advansys_info()
3934 *
3935 * Return suitable for printing on the console with the argument
3936 * adapter's configuration information.
3937 *
3938 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
3939 * otherwise the static 'info' array will be overrun.
3940 */
3941 static const char *advansys_info(struct Scsi_Host *shost)
3942 {
3943 static char info[ASC_INFO_SIZE];
3944 asc_board_t *boardp;
3945 ASC_DVC_VAR *asc_dvc_varp;
3946 ADV_DVC_VAR *adv_dvc_varp;
3947 char *busname;
3948 char *widename = NULL;
3949
3950 boardp = ASC_BOARDP(shost);
3951 if (ASC_NARROW_BOARD(boardp)) {
3952 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3953 ASC_DBG(1, "advansys_info: begin\n");
3954 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
3955 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
3956 ASC_IS_ISAPNP) {
3957 busname = "ISA PnP";
3958 } else {
3959 busname = "ISA";
3960 }
3961 sprintf(info,
3962 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
3963 ASC_VERSION, busname,
3964 (ulong)shost->io_port,
3965 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
3966 shost->irq, shost->dma_channel);
3967 } else {
3968 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
3969 busname = "VL";
3970 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
3971 busname = "EISA";
3972 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
3973 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
3974 == ASC_IS_PCI_ULTRA) {
3975 busname = "PCI Ultra";
3976 } else {
3977 busname = "PCI";
3978 }
3979 } else {
3980 busname = "?";
3981 ASC_PRINT2("advansys_info: board %d: unknown "
3982 "bus type %d\n", boardp->id,
3983 asc_dvc_varp->bus_type);
3984 }
3985 sprintf(info,
3986 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
3987 ASC_VERSION, busname, (ulong)shost->io_port,
3988 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
3989 shost->irq);
3990 }
3991 } else {
3992 /*
3993 * Wide Adapter Information
3994 *
3995 * Memory-mapped I/O is used instead of I/O space to access
3996 * the adapter, but display the I/O Port range. The Memory
3997 * I/O address is displayed through the driver /proc file.
3998 */
3999 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4000 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4001 widename = "Ultra-Wide";
4002 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4003 widename = "Ultra2-Wide";
4004 } else {
4005 widename = "Ultra3-Wide";
4006 }
4007 sprintf(info,
4008 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
4009 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
4010 (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, shost->irq);
4011 }
4012 ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
4013 ASC_DBG(1, "advansys_info: end\n");
4014 return info;
4015 }
4016
4017 /*
4018 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
4019 *
4020 * This function always returns 0. Command return status is saved
4021 * in the 'scp' result field.
4022 */
4023 static int
4024 advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *))
4025 {
4026 struct Scsi_Host *shost;
4027 asc_board_t *boardp;
4028 ulong flags;
4029 struct scsi_cmnd *done_scp;
4030
4031 shost = scp->device->host;
4032 boardp = ASC_BOARDP(shost);
4033 ASC_STATS(shost, queuecommand);
4034
4035 /* host_lock taken by mid-level prior to call but need to protect */
4036 /* against own ISR */
4037 spin_lock_irqsave(&boardp->lock, flags);
4038
4039 /*
4040 * Block new commands while handling a reset or abort request.
4041 */
4042 if (boardp->flags & ASC_HOST_IN_RESET) {
4043 ASC_DBG1(1,
4044 "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
4045 (ulong)scp);
4046 scp->result = HOST_BYTE(DID_RESET);
4047
4048 /*
4049 * Add blocked requests to the board's 'done' queue. The queued
4050 * requests will be completed at the end of the abort or reset
4051 * handling.
4052 */
4053 asc_enqueue(&boardp->done, scp, ASC_BACK);
4054 spin_unlock_irqrestore(&boardp->lock, flags);
4055 return 0;
4056 }
4057
4058 /*
4059 * Attempt to execute any waiting commands for the board.
4060 */
4061 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4062 ASC_DBG(1,
4063 "advansys_queuecommand: before asc_execute_queue() waiting\n");
4064 asc_execute_queue(&boardp->waiting);
4065 }
4066
4067 /*
4068 * Save the function pointer to Linux mid-level 'done' function
4069 * and attempt to execute the command.
4070 *
4071 * If ASC_NOERROR is returned the request has been added to the
4072 * board's 'active' queue and will be completed by the interrupt
4073 * handler.
4074 *
4075 * If ASC_BUSY is returned add the request to the board's per
4076 * target waiting list. This is the first time the request has
4077 * been tried. Add it to the back of the waiting list. It will be
4078 * retried later.
4079 *
4080 * If an error occurred, the request will have been placed on the
4081 * board's 'done' queue and must be completed before returning.
4082 */
4083 scp->scsi_done = done;
4084 switch (asc_execute_scsi_cmnd(scp)) {
4085 case ASC_NOERROR:
4086 break;
4087 case ASC_BUSY:
4088 asc_enqueue(&boardp->waiting, scp, ASC_BACK);
4089 break;
4090 case ASC_ERROR:
4091 default:
4092 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
4093 /* Interrupts could be enabled here. */
4094 asc_scsi_done_list(done_scp);
4095 break;
4096 }
4097 spin_unlock_irqrestore(&boardp->lock, flags);
4098
4099 return 0;
4100 }
4101
4102 /*
4103 * advansys_reset()
4104 *
4105 * Reset the bus associated with the command 'scp'.
4106 *
4107 * This function runs its own thread. Interrupts must be blocked but
4108 * sleeping is allowed and no locking other than for host structures is
4109 * required. Returns SUCCESS or FAILED.
4110 */
4111 static int advansys_reset(struct scsi_cmnd *scp)
4112 {
4113 struct Scsi_Host *shost;
4114 asc_board_t *boardp;
4115 ASC_DVC_VAR *asc_dvc_varp;
4116 ADV_DVC_VAR *adv_dvc_varp;
4117 ulong flags;
4118 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4119 struct scsi_cmnd *tscp, *new_last_scp;
4120 int status;
4121 int ret = SUCCESS;
4122
4123 ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp);
4124
4125 #ifdef ADVANSYS_STATS
4126 if (scp->device->host != NULL) {
4127 ASC_STATS(scp->device->host, reset);
4128 }
4129 #endif /* ADVANSYS_STATS */
4130
4131 if ((shost = scp->device->host) == NULL) {
4132 scp->result = HOST_BYTE(DID_ERROR);
4133 return FAILED;
4134 }
4135
4136 boardp = ASC_BOARDP(shost);
4137
4138 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
4139 boardp->id);
4140 /*
4141 * Check for re-entrancy.
4142 */
4143 spin_lock_irqsave(&boardp->lock, flags);
4144 if (boardp->flags & ASC_HOST_IN_RESET) {
4145 spin_unlock_irqrestore(&boardp->lock, flags);
4146 return FAILED;
4147 }
4148 boardp->flags |= ASC_HOST_IN_RESET;
4149 spin_unlock_irqrestore(&boardp->lock, flags);
4150
4151 if (ASC_NARROW_BOARD(boardp)) {
4152 /*
4153 * Narrow Board
4154 */
4155 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4156
4157 /*
4158 * Reset the chip and SCSI bus.
4159 */
4160 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
4161 status = AscInitAsc1000Driver(asc_dvc_varp);
4162
4163 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
4164 if (asc_dvc_varp->err_code) {
4165 ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
4166 "error: 0x%x\n", boardp->id,
4167 asc_dvc_varp->err_code);
4168 ret = FAILED;
4169 } else if (status) {
4170 ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
4171 "warning: 0x%x\n", boardp->id, status);
4172 } else {
4173 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
4174 "successful.\n", boardp->id);
4175 }
4176
4177 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
4178 spin_lock_irqsave(&boardp->lock, flags);
4179
4180 } else {
4181 /*
4182 * Wide Board
4183 *
4184 * If the suggest reset bus flags are set, then reset the bus.
4185 * Otherwise only reset the device.
4186 */
4187 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4188
4189 /*
4190 * Reset the target's SCSI bus.
4191 */
4192 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
4193 switch (AdvResetChipAndSB(adv_dvc_varp)) {
4194 case ASC_TRUE:
4195 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
4196 "successful.\n", boardp->id);
4197 break;
4198 case ASC_FALSE:
4199 default:
4200 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
4201 "error.\n", boardp->id);
4202 ret = FAILED;
4203 break;
4204 }
4205 spin_lock_irqsave(&boardp->lock, flags);
4206 (void)AdvISR(adv_dvc_varp);
4207 }
4208 /* Board lock is held. */
4209
4210 /*
4211 * Dequeue all board 'done' requests. A pointer to the last request
4212 * is returned in 'last_scp'.
4213 */
4214 done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
4215
4216 /*
4217 * Dequeue all board 'active' requests for all devices and set
4218 * the request status to DID_RESET. A pointer to the last request
4219 * is returned in 'last_scp'.
4220 */
4221 if (done_scp == NULL) {
4222 done_scp = asc_dequeue_list(&boardp->active, &last_scp,
4223 ASC_TID_ALL);
4224 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4225 tscp->result = HOST_BYTE(DID_RESET);
4226 }
4227 } else {
4228 /* Append to 'done_scp' at the end with 'last_scp'. */
4229 ASC_ASSERT(last_scp != NULL);
4230 last_scp->host_scribble =
4231 (unsigned char *)asc_dequeue_list(&boardp->active,
4232 &new_last_scp,
4233 ASC_TID_ALL);
4234 if (new_last_scp != NULL) {
4235 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4236 for (tscp = REQPNEXT(last_scp); tscp;
4237 tscp = REQPNEXT(tscp)) {
4238 tscp->result = HOST_BYTE(DID_RESET);
4239 }
4240 last_scp = new_last_scp;
4241 }
4242 }
4243
4244 /*
4245 * Dequeue all 'waiting' requests and set the request status
4246 * to DID_RESET.
4247 */
4248 if (done_scp == NULL) {
4249 done_scp = asc_dequeue_list(&boardp->waiting, &last_scp,
4250 ASC_TID_ALL);
4251 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4252 tscp->result = HOST_BYTE(DID_RESET);
4253 }
4254 } else {
4255 /* Append to 'done_scp' at the end with 'last_scp'. */
4256 ASC_ASSERT(last_scp != NULL);
4257 last_scp->host_scribble =
4258 (unsigned char *)asc_dequeue_list(&boardp->waiting,
4259 &new_last_scp,
4260 ASC_TID_ALL);
4261 if (new_last_scp != NULL) {
4262 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4263 for (tscp = REQPNEXT(last_scp); tscp;
4264 tscp = REQPNEXT(tscp)) {
4265 tscp->result = HOST_BYTE(DID_RESET);
4266 }
4267 last_scp = new_last_scp;
4268 }
4269 }
4270
4271 /* Save the time of the most recently completed reset. */
4272 boardp->last_reset = jiffies;
4273
4274 /* Clear reset flag. */
4275 boardp->flags &= ~ASC_HOST_IN_RESET;
4276 spin_unlock_irqrestore(&boardp->lock, flags);
4277
4278 /*
4279 * Complete all the 'done_scp' requests.
4280 */
4281 if (done_scp)
4282 asc_scsi_done_list(done_scp);
4283
4284 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
4285
4286 return ret;
4287 }
4288
4289 /*
4290 * advansys_biosparam()
4291 *
4292 * Translate disk drive geometry if the "BIOS greater than 1 GB"
4293 * support is enabled for a drive.
4294 *
4295 * ip (information pointer) is an int array with the following definition:
4296 * ip[0]: heads
4297 * ip[1]: sectors
4298 * ip[2]: cylinders
4299 */
4300 static int
4301 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
4302 sector_t capacity, int ip[])
4303 {
4304 asc_board_t *boardp;
4305
4306 ASC_DBG(1, "advansys_biosparam: begin\n");
4307 ASC_STATS(sdev->host, biosparam);
4308 boardp = ASC_BOARDP(sdev->host);
4309 if (ASC_NARROW_BOARD(boardp)) {
4310 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
4311 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
4312 ip[0] = 255;
4313 ip[1] = 63;
4314 } else {
4315 ip[0] = 64;
4316 ip[1] = 32;
4317 }
4318 } else {
4319 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
4320 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
4321 ip[0] = 255;
4322 ip[1] = 63;
4323 } else {
4324 ip[0] = 64;
4325 ip[1] = 32;
4326 }
4327 }
4328 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
4329 ASC_DBG(1, "advansys_biosparam: end\n");
4330 return 0;
4331 }
4332
4333 static struct scsi_host_template advansys_template = {
4334 .proc_name = "advansys",
4335 #ifdef CONFIG_PROC_FS
4336 .proc_info = advansys_proc_info,
4337 #endif
4338 .name = "advansys",
4339 .info = advansys_info,
4340 .queuecommand = advansys_queuecommand,
4341 .eh_bus_reset_handler = advansys_reset,
4342 .bios_param = advansys_biosparam,
4343 .slave_configure = advansys_slave_configure,
4344 /*
4345 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
4346 * must be set. The flag will be cleared in advansys_board_found
4347 * for non-ISA adapters.
4348 */
4349 .unchecked_isa_dma = 1,
4350 /*
4351 * All adapters controlled by this driver are capable of large
4352 * scatter-gather lists. According to the mid-level SCSI documentation
4353 * this obviates any performance gain provided by setting
4354 * 'use_clustering'. But empirically while CPU utilization is increased
4355 * by enabling clustering, I/O throughput increases as well.
4356 */
4357 .use_clustering = ENABLE_CLUSTERING,
4358 };
4359
4360 /*
4361 * --- Miscellaneous Driver Functions
4362 */
4363
4364 /*
4365 * First-level interrupt handler.
4366 *
4367 * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
4368 * all boards are currently checked for interrupts on each interrupt, 'dev_id'
4369 * is not referenced. 'dev_id' could be used to identify an interrupt passed
4370 * to the AdvanSys driver which is for a device sharing an interrupt with
4371 * an AdvanSys adapter.
4372 */
4373 static irqreturn_t advansys_interrupt(int irq, void *dev_id)
4374 {
4375 unsigned long flags;
4376 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4377 struct scsi_cmnd *new_last_scp;
4378 struct Scsi_Host *shost = dev_id;
4379 asc_board_t *boardp = ASC_BOARDP(shost);
4380 irqreturn_t result = IRQ_NONE;
4381
4382 ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp);
4383 spin_lock_irqsave(&boardp->lock, flags);
4384 if (ASC_NARROW_BOARD(boardp)) {
4385 /*
4386 * Narrow Board
4387 */
4388 if (AscIsIntPending(shost->io_port)) {
4389 result = IRQ_HANDLED;
4390 ASC_STATS(shost, interrupt);
4391 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
4392 AscISR(&boardp->dvc_var.asc_dvc_var);
4393 }
4394 } else {
4395 /*
4396 * Wide Board
4397 */
4398 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
4399 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
4400 result = IRQ_HANDLED;
4401 ASC_STATS(shost, interrupt);
4402 }
4403 }
4404
4405 /*
4406 * Start waiting requests and create a list of completed requests.
4407 *
4408 * If a reset request is being performed for the board, the reset
4409 * handler will complete pending requests after it has completed.
4410 */
4411 if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
4412 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%p, "
4413 "last_scp 0x%p\n", done_scp, last_scp);
4414
4415 /* Start any waiting commands for the board. */
4416 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4417 ASC_DBG(1, "advansys_interrupt: before "
4418 "asc_execute_queue()\n");
4419 asc_execute_queue(&boardp->waiting);
4420 }
4421
4422 /*
4423 * Add to the list of requests that must be completed.
4424 *
4425 * 'done_scp' will always be NULL on the first iteration of
4426 * this loop. 'last_scp' is set at the same time as 'done_scp'.
4427 */
4428 if (done_scp == NULL) {
4429 done_scp = asc_dequeue_list(&boardp->done,
4430 &last_scp, ASC_TID_ALL);
4431 } else {
4432 ASC_ASSERT(last_scp != NULL);
4433 last_scp->host_scribble =
4434 (unsigned char *)asc_dequeue_list(&boardp->
4435 done,
4436 &new_last_scp,
4437 ASC_TID_ALL);
4438 if (new_last_scp != NULL) {
4439 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4440 last_scp = new_last_scp;
4441 }
4442 }
4443 }
4444 spin_unlock_irqrestore(&boardp->lock, flags);
4445
4446 /*
4447 * If interrupts were enabled on entry, then they
4448 * are now enabled here.
4449 *
4450 * Complete all requests on the done list.
4451 */
4452
4453 asc_scsi_done_list(done_scp);
4454
4455 ASC_DBG(1, "advansys_interrupt: end\n");
4456 return result;
4457 }
4458
4459 static void
4460 advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
4461 {
4462 ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
4463 ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
4464
4465 if (sdev->lun == 0) {
4466 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
4467 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
4468 asc_dvc->init_sdtr |= tid_bit;
4469 } else {
4470 asc_dvc->init_sdtr &= ~tid_bit;
4471 }
4472
4473 if (orig_init_sdtr != asc_dvc->init_sdtr)
4474 AscAsyncFix(asc_dvc, sdev);
4475 }
4476
4477 if (sdev->tagged_supported) {
4478 if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
4479 if (sdev->lun == 0) {
4480 asc_dvc->cfg->can_tagged_qng |= tid_bit;
4481 asc_dvc->use_tagged_qng |= tid_bit;
4482 }
4483 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
4484 asc_dvc->max_dvc_qng[sdev->id]);
4485 }
4486 } else {
4487 if (sdev->lun == 0) {
4488 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
4489 asc_dvc->use_tagged_qng &= ~tid_bit;
4490 }
4491 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
4492 }
4493
4494 if ((sdev->lun == 0) &&
4495 (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
4496 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
4497 asc_dvc->cfg->disc_enable);
4498 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
4499 asc_dvc->use_tagged_qng);
4500 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
4501 asc_dvc->cfg->can_tagged_qng);
4502
4503 asc_dvc->max_dvc_qng[sdev->id] =
4504 asc_dvc->cfg->max_tag_qng[sdev->id];
4505 AscWriteLramByte(asc_dvc->iop_base,
4506 (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
4507 asc_dvc->max_dvc_qng[sdev->id]);
4508 }
4509 }
4510
4511 /*
4512 * Wide Transfers
4513 *
4514 * If the EEPROM enabled WDTR for the device and the device supports wide
4515 * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and
4516 * write the new value to the microcode.
4517 */
4518 static void
4519 advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
4520 {
4521 unsigned short cfg_word;
4522 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
4523 if ((cfg_word & tidmask) != 0)
4524 return;
4525
4526 cfg_word |= tidmask;
4527 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
4528
4529 /*
4530 * Clear the microcode SDTR and WDTR negotiation done indicators for
4531 * the target to cause it to negotiate with the new setting set above.
4532 * WDTR when accepted causes the target to enter asynchronous mode, so
4533 * SDTR must be negotiated.
4534 */
4535 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
4536 cfg_word &= ~tidmask;
4537 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
4538 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
4539 cfg_word &= ~tidmask;
4540 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
4541 }
4542
4543 /*
4544 * Synchronous Transfers
4545 *
4546 * If the EEPROM enabled SDTR for the device and the device
4547 * supports synchronous transfers, then turn on the device's
4548 * 'sdtr_able' bit. Write the new value to the microcode.
4549 */
4550 static void
4551 advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
4552 {
4553 unsigned short cfg_word;
4554 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
4555 if ((cfg_word & tidmask) != 0)
4556 return;
4557
4558 cfg_word |= tidmask;
4559 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
4560
4561 /*
4562 * Clear the microcode "SDTR negotiation" done indicator for the
4563 * target to cause it to negotiate with the new setting set above.
4564 */
4565 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
4566 cfg_word &= ~tidmask;
4567 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
4568 }
4569
4570 /*
4571 * PPR (Parallel Protocol Request) Capable
4572 *
4573 * If the device supports DT mode, then it must be PPR capable.
4574 * The PPR message will be used in place of the SDTR and WDTR
4575 * messages to negotiate synchronous speed and offset, transfer
4576 * width, and protocol options.
4577 */
4578 static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
4579 AdvPortAddr iop_base, unsigned short tidmask)
4580 {
4581 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
4582 adv_dvc->ppr_able |= tidmask;
4583 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
4584 }
4585
4586 static void
4587 advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
4588 {
4589 AdvPortAddr iop_base = adv_dvc->iop_base;
4590 unsigned short tidmask = 1 << sdev->id;
4591
4592 if (sdev->lun == 0) {
4593 /*
4594 * Handle WDTR, SDTR, and Tag Queuing. If the feature
4595 * is enabled in the EEPROM and the device supports the
4596 * feature, then enable it in the microcode.
4597 */
4598
4599 if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
4600 advansys_wide_enable_wdtr(iop_base, tidmask);
4601 if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
4602 advansys_wide_enable_sdtr(iop_base, tidmask);
4603 if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
4604 advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
4605
4606 /*
4607 * Tag Queuing is disabled for the BIOS which runs in polled
4608 * mode and would see no benefit from Tag Queuing. Also by
4609 * disabling Tag Queuing in the BIOS devices with Tag Queuing
4610 * bugs will at least work with the BIOS.
4611 */
4612 if ((adv_dvc->tagqng_able & tidmask) &&
4613 sdev->tagged_supported) {
4614 unsigned short cfg_word;
4615 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
4616 cfg_word |= tidmask;
4617 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
4618 cfg_word);
4619 AdvWriteByteLram(iop_base,
4620 ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
4621 adv_dvc->max_dvc_qng);
4622 }
4623 }
4624
4625 if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) {
4626 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
4627 adv_dvc->max_dvc_qng);
4628 } else {
4629 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
4630 }
4631 }
4632
4633 /*
4634 * Set the number of commands to queue per device for the
4635 * specified host adapter.
4636 */
4637 static int advansys_slave_configure(struct scsi_device *sdev)
4638 {
4639 asc_board_t *boardp = ASC_BOARDP(sdev->host);
4640 boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
4641
4642 /*
4643 * Save a pointer to the sdev and set its initial/maximum
4644 * queue depth. Only save the pointer for a lun0 dev though.
4645 */
4646 if (sdev->lun == 0)
4647 boardp->device[sdev->id] = sdev;
4648
4649 if (ASC_NARROW_BOARD(boardp))
4650 advansys_narrow_slave_configure(sdev,
4651 &boardp->dvc_var.asc_dvc_var);
4652 else
4653 advansys_wide_slave_configure(sdev,
4654 &boardp->dvc_var.adv_dvc_var);
4655
4656 return 0;
4657 }
4658
4659 /*
4660 * Complete all requests on the singly linked list pointed
4661 * to by 'scp'.
4662 *
4663 * Interrupts can be enabled on entry.
4664 */
4665 static void asc_scsi_done_list(struct scsi_cmnd *scp)
4666 {
4667 struct scsi_cmnd *tscp;
4668
4669 ASC_DBG(2, "asc_scsi_done_list: begin\n");
4670 while (scp != NULL) {
4671 asc_board_t *boardp;
4672
4673 ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp);
4674 tscp = REQPNEXT(scp);
4675 scp->host_scribble = NULL;
4676
4677 boardp = ASC_BOARDP(scp->device->host);
4678
4679 if (scp->use_sg)
4680 dma_unmap_sg(boardp->dev,
4681 (struct scatterlist *)scp->request_buffer,
4682 scp->use_sg, scp->sc_data_direction);
4683 else if (scp->request_bufflen)
4684 dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
4685 scp->request_bufflen,
4686 scp->sc_data_direction);
4687
4688 ASC_STATS(scp->device->host, done);
4689 ASC_ASSERT(scp->scsi_done != NULL);
4690
4691 scp->scsi_done(scp);
4692
4693 scp = tscp;
4694 }
4695 ASC_DBG(2, "asc_scsi_done_list: done\n");
4696 return;
4697 }
4698
4699 /*
4700 * Execute a single 'Scsi_Cmnd'.
4701 *
4702 * The function 'done' is called when the request has been completed.
4703 *
4704 * Scsi_Cmnd:
4705 *
4706 * host - board controlling device
4707 * device - device to send command
4708 * target - target of device
4709 * lun - lun of device
4710 * cmd_len - length of SCSI CDB
4711 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
4712 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
4713 *
4714 * if (use_sg == 0) {
4715 * request_buffer - buffer address for request
4716 * request_bufflen - length of request buffer
4717 * } else {
4718 * request_buffer - pointer to scatterlist structure
4719 * }
4720 *
4721 * sense_buffer - sense command buffer
4722 *
4723 * result (4 bytes of an int):
4724 * Byte Meaning
4725 * 0 SCSI Status Byte Code
4726 * 1 SCSI One Byte Message Code
4727 * 2 Host Error Code
4728 * 3 Mid-Level Error Code
4729 *
4730 * host driver fields:
4731 * SCp - Scsi_Pointer used for command processing status
4732 * scsi_done - used to save caller's done function
4733 * host_scribble - used for pointer to another struct scsi_cmnd
4734 *
4735 * If this function returns ASC_NOERROR the request has been enqueued
4736 * on the board's 'active' queue and will be completed from the
4737 * interrupt handler.
4738 *
4739 * If this function returns ASC_NOERROR the request has been enqueued
4740 * on the board's 'done' queue and must be completed by the caller.
4741 *
4742 * If ASC_BUSY is returned the request will be enqueued by the
4743 * caller on the target's waiting queue and re-tried later.
4744 */
4745 static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
4746 {
4747 asc_board_t *boardp;
4748 ASC_DVC_VAR *asc_dvc_varp;
4749 ADV_DVC_VAR *adv_dvc_varp;
4750 ADV_SCSI_REQ_Q *adv_scsiqp;
4751 struct scsi_device *device;
4752 int ret;
4753
4754 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
4755 (ulong)scp, (ulong)scp->scsi_done);
4756
4757 boardp = ASC_BOARDP(scp->device->host);
4758 device = boardp->device[scp->device->id];
4759
4760 if (ASC_NARROW_BOARD(boardp)) {
4761 /*
4762 * Build and execute Narrow Board request.
4763 */
4764
4765 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4766
4767 /*
4768 * Build Asc Library request structure using the
4769 * global structures 'asc_scsi_req' and 'asc_sg_head'.
4770 *
4771 * If an error is returned, then the request has been
4772 * queued on the board done queue. It will be completed
4773 * by the caller.
4774 *
4775 * asc_build_req() can not return ASC_BUSY.
4776 */
4777 if (asc_build_req(boardp, scp) == ASC_ERROR) {
4778 ASC_STATS(scp->device->host, build_error);
4779 return ASC_ERROR;
4780 }
4781
4782 /*
4783 * Execute the command. If there is no error, add the command
4784 * to the active queue.
4785 */
4786 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
4787 case ASC_NOERROR:
4788 ASC_STATS(scp->device->host, exe_noerror);
4789 /*
4790 * Increment monotonically increasing per device
4791 * successful request counter. Wrapping doesn't matter.
4792 */
4793 boardp->reqcnt[scp->device->id]++;
4794 asc_enqueue(&boardp->active, scp, ASC_BACK);
4795 ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue(), "
4796 "ASC_NOERROR\n");
4797 break;
4798 case ASC_BUSY:
4799 /*
4800 * Caller will enqueue request on the target's waiting
4801 * queue and retry later.
4802 */
4803 ASC_STATS(scp->device->host, exe_busy);
4804 break;
4805 case ASC_ERROR:
4806 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4807 "AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4808 boardp->id, asc_dvc_varp->err_code);
4809 ASC_STATS(scp->device->host, exe_error);
4810 scp->result = HOST_BYTE(DID_ERROR);
4811 asc_enqueue(&boardp->done, scp, ASC_BACK);
4812 break;
4813 default:
4814 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4815 "AscExeScsiQueue() unknown, err_code 0x%x\n",
4816 boardp->id, asc_dvc_varp->err_code);
4817 ASC_STATS(scp->device->host, exe_unknown);
4818 scp->result = HOST_BYTE(DID_ERROR);
4819 asc_enqueue(&boardp->done, scp, ASC_BACK);
4820 break;
4821 }
4822 } else {
4823 /*
4824 * Build and execute Wide Board request.
4825 */
4826 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4827
4828 /*
4829 * Build and get a pointer to an Adv Library request structure.
4830 *
4831 * If the request is successfully built then send it below,
4832 * otherwise return with an error.
4833 */
4834 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
4835 case ASC_NOERROR:
4836 ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req "
4837 "ASC_NOERROR\n");
4838 break;
4839 case ASC_BUSY:
4840 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
4841 "ASC_BUSY\n");
4842 /*
4843 * If busy is returned the request has not been
4844 * enqueued. It will be enqueued by the caller on the
4845 * target's waiting queue and retried later.
4846 *
4847 * The asc_stats fields 'adv_build_noreq' and
4848 * 'adv_build_nosg' count wide board busy conditions.
4849 * They are updated in adv_build_req and
4850 * adv_get_sglist, respectively.
4851 */
4852 return ASC_BUSY;
4853 case ASC_ERROR:
4854 /*
4855 * If an error is returned, then the request has been
4856 * queued on the board done queue. It will be completed
4857 * by the caller.
4858 */
4859 default:
4860 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
4861 "ASC_ERROR\n");
4862 ASC_STATS(scp->device->host, build_error);
4863 return ASC_ERROR;
4864 }
4865
4866 /*
4867 * Execute the command. If there is no error, add the command
4868 * to the active queue.
4869 */
4870 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
4871 case ASC_NOERROR:
4872 ASC_STATS(scp->device->host, exe_noerror);
4873 /*
4874 * Increment monotonically increasing per device
4875 * successful request counter. Wrapping doesn't matter.
4876 */
4877 boardp->reqcnt[scp->device->id]++;
4878 asc_enqueue(&boardp->active, scp, ASC_BACK);
4879 ASC_DBG(1, "asc_execute_scsi_cmnd: AdvExeScsiQueue(), "
4880 "ASC_NOERROR\n");
4881 break;
4882 case ASC_BUSY:
4883 /*
4884 * Caller will enqueue request on the target's waiting
4885 * queue and retry later.
4886 */
4887 ASC_STATS(scp->device->host, exe_busy);
4888 break;
4889 case ASC_ERROR:
4890 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4891 "AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4892 boardp->id, adv_dvc_varp->err_code);
4893 ASC_STATS(scp->device->host, exe_error);
4894 scp->result = HOST_BYTE(DID_ERROR);
4895 asc_enqueue(&boardp->done, scp, ASC_BACK);
4896 break;
4897 default:
4898 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4899 "AdvExeScsiQueue() unknown, err_code 0x%x\n",
4900 boardp->id, adv_dvc_varp->err_code);
4901 ASC_STATS(scp->device->host, exe_unknown);
4902 scp->result = HOST_BYTE(DID_ERROR);
4903 asc_enqueue(&boardp->done, scp, ASC_BACK);
4904 break;
4905 }
4906 }
4907
4908 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
4909 return ret;
4910 }
4911
4912 /*
4913 * Build a request structure for the Asc Library (Narrow Board).
4914 *
4915 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
4916 * used to build the request.
4917 *
4918 * If an error occurs, then queue the request on the board done
4919 * queue and return ASC_ERROR.
4920 */
4921 static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
4922 {
4923 /*
4924 * Mutually exclusive access is required to 'asc_scsi_q' and
4925 * 'asc_sg_head' until after the request is started.
4926 */
4927 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
4928
4929 /*
4930 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
4931 */
4932 asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
4933
4934 /*
4935 * Build the ASC_SCSI_Q request.
4936 *
4937 * For narrow boards a CDB length maximum of 12 bytes
4938 * is supported.
4939 */
4940 if (scp->cmd_len > ASC_MAX_CDB_LEN) {
4941 ASC_PRINT3("asc_build_req: board %d: cmd_len %d > "
4942 "ASC_MAX_CDB_LEN %d\n", boardp->id, scp->cmd_len,
4943 ASC_MAX_CDB_LEN);
4944 scp->result = HOST_BYTE(DID_ERROR);
4945 asc_enqueue(&boardp->done, scp, ASC_BACK);
4946 return ASC_ERROR;
4947 }
4948 asc_scsi_q.cdbptr = &scp->cmnd[0];
4949 asc_scsi_q.q2.cdb_len = scp->cmd_len;
4950 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
4951 asc_scsi_q.q1.target_lun = scp->device->lun;
4952 asc_scsi_q.q2.target_ix =
4953 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
4954 asc_scsi_q.q1.sense_addr =
4955 cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
4956 asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
4957
4958 /*
4959 * If there are any outstanding requests for the current target,
4960 * then every 255th request send an ORDERED request. This heuristic
4961 * tries to retain the benefit of request sorting while preventing
4962 * request starvation. 255 is the max number of tags or pending commands
4963 * a device may have outstanding.
4964 *
4965 * The request count is incremented below for every successfully
4966 * started request.
4967 *
4968 */
4969 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
4970 (boardp->reqcnt[scp->device->id] % 255) == 0) {
4971 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
4972 } else {
4973 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
4974 }
4975
4976 /*
4977 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
4978 * buffer command.
4979 */
4980 if (scp->use_sg == 0) {
4981 /*
4982 * CDB request of single contiguous buffer.
4983 */
4984 ASC_STATS(scp->device->host, cont_cnt);
4985 scp->SCp.dma_handle = scp->request_bufflen ?
4986 dma_map_single(boardp->dev, scp->request_buffer,
4987 scp->request_bufflen,
4988 scp->sc_data_direction) : 0;
4989 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
4990 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
4991 ASC_STATS_ADD(scp->device->host, cont_xfer,
4992 ASC_CEILING(scp->request_bufflen, 512));
4993 asc_scsi_q.q1.sg_queue_cnt = 0;
4994 asc_scsi_q.sg_head = NULL;
4995 } else {
4996 /*
4997 * CDB scatter-gather request list.
4998 */
4999 int sgcnt;
5000 int use_sg;
5001 struct scatterlist *slp;
5002
5003 slp = (struct scatterlist *)scp->request_buffer;
5004 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
5005 scp->sc_data_direction);
5006
5007 if (use_sg > scp->device->host->sg_tablesize) {
5008 ASC_PRINT3("asc_build_req: board %d: use_sg %d > "
5009 "sg_tablesize %d\n", boardp->id, use_sg,
5010 scp->device->host->sg_tablesize);
5011 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
5012 scp->sc_data_direction);
5013 scp->result = HOST_BYTE(DID_ERROR);
5014 asc_enqueue(&boardp->done, scp, ASC_BACK);
5015 return ASC_ERROR;
5016 }
5017
5018 ASC_STATS(scp->device->host, sg_cnt);
5019
5020 /*
5021 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
5022 * structure to point to it.
5023 */
5024 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
5025
5026 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
5027 asc_scsi_q.sg_head = &asc_sg_head;
5028 asc_scsi_q.q1.data_cnt = 0;
5029 asc_scsi_q.q1.data_addr = 0;
5030 /* This is a byte value, otherwise it would need to be swapped. */
5031 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
5032 ASC_STATS_ADD(scp->device->host, sg_elem,
5033 asc_sg_head.entry_cnt);
5034
5035 /*
5036 * Convert scatter-gather list into ASC_SG_HEAD list.
5037 */
5038 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
5039 asc_sg_head.sg_list[sgcnt].addr =
5040 cpu_to_le32(sg_dma_address(slp));
5041 asc_sg_head.sg_list[sgcnt].bytes =
5042 cpu_to_le32(sg_dma_len(slp));
5043 ASC_STATS_ADD(scp->device->host, sg_xfer,
5044 ASC_CEILING(sg_dma_len(slp), 512));
5045 }
5046 }
5047
5048 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
5049 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
5050
5051 return ASC_NOERROR;
5052 }
5053
5054 /*
5055 * Build a request structure for the Adv Library (Wide Board).
5056 *
5057 * If an adv_req_t can not be allocated to issue the request,
5058 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
5059 *
5060 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
5061 * microcode for DMA addresses or math operations are byte swapped
5062 * to little-endian order.
5063 */
5064 static int
5065 adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
5066 ADV_SCSI_REQ_Q **adv_scsiqpp)
5067 {
5068 adv_req_t *reqp;
5069 ADV_SCSI_REQ_Q *scsiqp;
5070 int i;
5071 int ret;
5072
5073 /*
5074 * Allocate an adv_req_t structure from the board to execute
5075 * the command.
5076 */
5077 if (boardp->adv_reqp == NULL) {
5078 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
5079 ASC_STATS(scp->device->host, adv_build_noreq);
5080 return ASC_BUSY;
5081 } else {
5082 reqp = boardp->adv_reqp;
5083 boardp->adv_reqp = reqp->next_reqp;
5084 reqp->next_reqp = NULL;
5085 }
5086
5087 /*
5088 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
5089 */
5090 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5091
5092 /*
5093 * Initialize the structure.
5094 */
5095 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
5096
5097 /*
5098 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
5099 */
5100 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
5101
5102 /*
5103 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
5104 */
5105 reqp->cmndp = scp;
5106
5107 /*
5108 * Build the ADV_SCSI_REQ_Q request.
5109 */
5110
5111 /*
5112 * Set CDB length and copy it to the request structure.
5113 * For wide boards a CDB length maximum of 16 bytes
5114 * is supported.
5115 */
5116 if (scp->cmd_len > ADV_MAX_CDB_LEN) {
5117 ASC_PRINT3
5118 ("adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n",
5119 boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
5120 scp->result = HOST_BYTE(DID_ERROR);
5121 asc_enqueue(&boardp->done, scp, ASC_BACK);
5122 return ASC_ERROR;
5123 }
5124 scsiqp->cdb_len = scp->cmd_len;
5125 /* Copy first 12 CDB bytes to cdb[]. */
5126 for (i = 0; i < scp->cmd_len && i < 12; i++) {
5127 scsiqp->cdb[i] = scp->cmnd[i];
5128 }
5129 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
5130 for (; i < scp->cmd_len; i++) {
5131 scsiqp->cdb16[i - 12] = scp->cmnd[i];
5132 }
5133
5134 scsiqp->target_id = scp->device->id;
5135 scsiqp->target_lun = scp->device->lun;
5136
5137 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
5138 scsiqp->sense_len = sizeof(scp->sense_buffer);
5139
5140 /*
5141 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
5142 * buffer command.
5143 */
5144
5145 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
5146 scsiqp->vdata_addr = scp->request_buffer;
5147 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
5148
5149 if (scp->use_sg == 0) {
5150 /*
5151 * CDB request of single contiguous buffer.
5152 */
5153 reqp->sgblkp = NULL;
5154 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
5155 if (scp->request_bufflen) {
5156 scsiqp->vdata_addr = scp->request_buffer;
5157 scp->SCp.dma_handle =
5158 dma_map_single(boardp->dev, scp->request_buffer,
5159 scp->request_bufflen,
5160 scp->sc_data_direction);
5161 } else {
5162 scsiqp->vdata_addr = NULL;
5163 scp->SCp.dma_handle = 0;
5164 }
5165 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
5166 scsiqp->sg_list_ptr = NULL;
5167 scsiqp->sg_real_addr = 0;
5168 ASC_STATS(scp->device->host, cont_cnt);
5169 ASC_STATS_ADD(scp->device->host, cont_xfer,
5170 ASC_CEILING(scp->request_bufflen, 512));
5171 } else {
5172 /*
5173 * CDB scatter-gather request list.
5174 */
5175 struct scatterlist *slp;
5176 int use_sg;
5177
5178 slp = (struct scatterlist *)scp->request_buffer;
5179 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
5180 scp->sc_data_direction);
5181
5182 if (use_sg > ADV_MAX_SG_LIST) {
5183 ASC_PRINT3("adv_build_req: board %d: use_sg %d > "
5184 "ADV_MAX_SG_LIST %d\n", boardp->id, use_sg,
5185 scp->device->host->sg_tablesize);
5186 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
5187 scp->sc_data_direction);
5188 scp->result = HOST_BYTE(DID_ERROR);
5189 asc_enqueue(&boardp->done, scp, ASC_BACK);
5190
5191 /*
5192 * Free the 'adv_req_t' structure by adding it back
5193 * to the board free list.
5194 */
5195 reqp->next_reqp = boardp->adv_reqp;
5196 boardp->adv_reqp = reqp;
5197
5198 return ASC_ERROR;
5199 }
5200
5201 ret = adv_get_sglist(boardp, reqp, scp, use_sg);
5202 if (ret != ADV_SUCCESS) {
5203 /*
5204 * Free the adv_req_t structure by adding it back to
5205 * the board free list.
5206 */
5207 reqp->next_reqp = boardp->adv_reqp;
5208 boardp->adv_reqp = reqp;
5209
5210 return ret;
5211 }
5212
5213 ASC_STATS(scp->device->host, sg_cnt);
5214 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
5215 }
5216
5217 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5218 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
5219
5220 *adv_scsiqpp = scsiqp;
5221
5222 return ASC_NOERROR;
5223 }
5224
5225 /*
5226 * Build scatter-gather list for Adv Library (Wide Board).
5227 *
5228 * Additional ADV_SG_BLOCK structures will need to be allocated
5229 * if the total number of scatter-gather elements exceeds
5230 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
5231 * assumed to be physically contiguous.
5232 *
5233 * Return:
5234 * ADV_SUCCESS(1) - SG List successfully created
5235 * ADV_ERROR(-1) - SG List creation failed
5236 */
5237 static int
5238 adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
5239 int use_sg)
5240 {
5241 adv_sgblk_t *sgblkp;
5242 ADV_SCSI_REQ_Q *scsiqp;
5243 struct scatterlist *slp;
5244 int sg_elem_cnt;
5245 ADV_SG_BLOCK *sg_block, *prev_sg_block;
5246 ADV_PADDR sg_block_paddr;
5247 int i;
5248
5249 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5250 slp = (struct scatterlist *)scp->request_buffer;
5251 sg_elem_cnt = use_sg;
5252 prev_sg_block = NULL;
5253 reqp->sgblkp = NULL;
5254
5255 do {
5256 /*
5257 * Allocate a 'adv_sgblk_t' structure from the board free
5258 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
5259 * (15) scatter-gather elements.
5260 */
5261 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
5262 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
5263 ASC_STATS(scp->device->host, adv_build_nosg);
5264
5265 /*
5266 * Allocation failed. Free 'adv_sgblk_t' structures already
5267 * allocated for the request.
5268 */
5269 while ((sgblkp = reqp->sgblkp) != NULL) {
5270 /* Remove 'sgblkp' from the request list. */
5271 reqp->sgblkp = sgblkp->next_sgblkp;
5272
5273 /* Add 'sgblkp' to the board free list. */
5274 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5275 boardp->adv_sgblkp = sgblkp;
5276 }
5277 return ASC_BUSY;
5278 } else {
5279 /* Complete 'adv_sgblk_t' board allocation. */
5280 boardp->adv_sgblkp = sgblkp->next_sgblkp;
5281 sgblkp->next_sgblkp = NULL;
5282
5283 /*
5284 * Get 8 byte aligned virtual and physical addresses for
5285 * the allocated ADV_SG_BLOCK structure.
5286 */
5287 sg_block =
5288 (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
5289 sg_block_paddr = virt_to_bus(sg_block);
5290
5291 /*
5292 * Check if this is the first 'adv_sgblk_t' for the request.
5293 */
5294 if (reqp->sgblkp == NULL) {
5295 /* Request's first scatter-gather block. */
5296 reqp->sgblkp = sgblkp;
5297
5298 /*
5299 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
5300 * address pointers.
5301 */
5302 scsiqp->sg_list_ptr = sg_block;
5303 scsiqp->sg_real_addr =
5304 cpu_to_le32(sg_block_paddr);
5305 } else {
5306 /* Request's second or later scatter-gather block. */
5307 sgblkp->next_sgblkp = reqp->sgblkp;
5308 reqp->sgblkp = sgblkp;
5309
5310 /*
5311 * Point the previous ADV_SG_BLOCK structure to
5312 * the newly allocated ADV_SG_BLOCK structure.
5313 */
5314 ASC_ASSERT(prev_sg_block != NULL);
5315 prev_sg_block->sg_ptr =
5316 cpu_to_le32(sg_block_paddr);
5317 }
5318 }
5319
5320 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
5321 sg_block->sg_list[i].sg_addr =
5322 cpu_to_le32(sg_dma_address(slp));
5323 sg_block->sg_list[i].sg_count =
5324 cpu_to_le32(sg_dma_len(slp));
5325 ASC_STATS_ADD(scp->device->host, sg_xfer,
5326 ASC_CEILING(sg_dma_len(slp), 512));
5327
5328 if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */
5329 sg_block->sg_cnt = i + 1;
5330 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
5331 return ADV_SUCCESS;
5332 }
5333 slp++;
5334 }
5335 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
5336 prev_sg_block = sg_block;
5337 }
5338 while (1);
5339 /* NOTREACHED */
5340 }
5341
5342 /*
5343 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
5344 *
5345 * Interrupt callback function for the Narrow SCSI Asc Library.
5346 */
5347 static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
5348 {
5349 asc_board_t *boardp;
5350 struct scsi_cmnd *scp;
5351 struct Scsi_Host *shost;
5352
5353 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
5354 (ulong)asc_dvc_varp, (ulong)qdonep);
5355 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
5356
5357 /*
5358 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5359 * command that has been completed.
5360 */
5361 scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
5362 ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp);
5363
5364 if (scp == NULL) {
5365 ASC_PRINT("asc_isr_callback: scp is NULL\n");
5366 return;
5367 }
5368 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5369
5370 shost = scp->device->host;
5371 ASC_STATS(shost, callback);
5372 ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
5373
5374 /*
5375 * If the request isn't found on the active queue, it may
5376 * have been removed to handle a reset request.
5377 * Display a message and return.
5378 */
5379 boardp = ASC_BOARDP(shost);
5380 ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
5381 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5382 ASC_PRINT2
5383 ("asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
5384 boardp->id, (ulong)scp);
5385 return;
5386 }
5387
5388 /*
5389 * 'qdonep' contains the command's ending status.
5390 */
5391 switch (qdonep->d3.done_stat) {
5392 case QD_NO_ERROR:
5393 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
5394 scp->result = 0;
5395
5396 /*
5397 * Check for an underrun condition.
5398 *
5399 * If there was no error and an underrun condition, then
5400 * return the number of underrun bytes.
5401 */
5402 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
5403 qdonep->remain_bytes <= scp->request_bufflen) {
5404 ASC_DBG1(1,
5405 "asc_isr_callback: underrun condition %u bytes\n",
5406 (unsigned)qdonep->remain_bytes);
5407 scp->resid = qdonep->remain_bytes;
5408 }
5409 break;
5410
5411 case QD_WITH_ERROR:
5412 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
5413 switch (qdonep->d3.host_stat) {
5414 case QHSTA_NO_ERROR:
5415 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
5416 ASC_DBG(2,
5417 "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5418 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5419 sizeof(scp->sense_buffer));
5420 /*
5421 * Note: The 'status_byte()' macro used by target drivers
5422 * defined in scsi.h shifts the status byte returned by
5423 * host drivers right by 1 bit. This is why target drivers
5424 * also use right shifted status byte definitions. For
5425 * instance target drivers use CHECK_CONDITION, defined to
5426 * 0x1, instead of the SCSI defined check condition value
5427 * of 0x2. Host drivers are supposed to return the status
5428 * byte as it is defined by SCSI.
5429 */
5430 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5431 STATUS_BYTE(qdonep->d3.scsi_stat);
5432 } else {
5433 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
5434 }
5435 break;
5436
5437 default:
5438 /* QHSTA error occurred */
5439 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
5440 qdonep->d3.host_stat);
5441 scp->result = HOST_BYTE(DID_BAD_TARGET);
5442 break;
5443 }
5444 break;
5445
5446 case QD_ABORTED_BY_HOST:
5447 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
5448 scp->result =
5449 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
5450 scsi_msg) |
5451 STATUS_BYTE(qdonep->d3.scsi_stat);
5452 break;
5453
5454 default:
5455 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n",
5456 qdonep->d3.done_stat);
5457 scp->result =
5458 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
5459 scsi_msg) |
5460 STATUS_BYTE(qdonep->d3.scsi_stat);
5461 break;
5462 }
5463
5464 /*
5465 * If the 'init_tidmask' bit isn't already set for the target and the
5466 * current request finished normally, then set the bit for the target
5467 * to indicate that a device is present.
5468 */
5469 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5470 qdonep->d3.done_stat == QD_NO_ERROR &&
5471 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
5472 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5473 }
5474
5475 /*
5476 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5477 * function, add the command to the end of the board's done queue.
5478 * The done function for the command will be called from
5479 * advansys_interrupt().
5480 */
5481 asc_enqueue(&boardp->done, scp, ASC_BACK);
5482
5483 return;
5484 }
5485
5486 /*
5487 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
5488 *
5489 * Callback function for the Wide SCSI Adv Library.
5490 */
5491 static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
5492 {
5493 asc_board_t *boardp;
5494 adv_req_t *reqp;
5495 adv_sgblk_t *sgblkp;
5496 struct scsi_cmnd *scp;
5497 struct Scsi_Host *shost;
5498 ADV_DCNT resid_cnt;
5499
5500 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
5501 (ulong)adv_dvc_varp, (ulong)scsiqp);
5502 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5503
5504 /*
5505 * Get the adv_req_t structure for the command that has been
5506 * completed. The adv_req_t structure actually contains the
5507 * completed ADV_SCSI_REQ_Q structure.
5508 */
5509 reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
5510 ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp);
5511 if (reqp == NULL) {
5512 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
5513 return;
5514 }
5515
5516 /*
5517 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5518 * command that has been completed.
5519 *
5520 * Note: The adv_req_t request structure and adv_sgblk_t structure,
5521 * if any, are dropped, because a board structure pointer can not be
5522 * determined.
5523 */
5524 scp = reqp->cmndp;
5525 ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp);
5526 if (scp == NULL) {
5527 ASC_PRINT
5528 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
5529 return;
5530 }
5531 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5532
5533 shost = scp->device->host;
5534 ASC_STATS(shost, callback);
5535 ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
5536
5537 /*
5538 * If the request isn't found on the active queue, it may have been
5539 * removed to handle a reset request. Display a message and return.
5540 *
5541 * Note: Because the structure may still be in use don't attempt
5542 * to free the adv_req_t and adv_sgblk_t, if any, structures.
5543 */
5544 boardp = ASC_BOARDP(shost);
5545 ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
5546 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5547 ASC_PRINT2
5548 ("adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
5549 boardp->id, (ulong)scp);
5550 return;
5551 }
5552
5553 /*
5554 * 'done_status' contains the command's ending status.
5555 */
5556 switch (scsiqp->done_status) {
5557 case QD_NO_ERROR:
5558 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
5559 scp->result = 0;
5560
5561 /*
5562 * Check for an underrun condition.
5563 *
5564 * If there was no error and an underrun condition, then
5565 * then return the number of underrun bytes.
5566 */
5567 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
5568 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
5569 resid_cnt <= scp->request_bufflen) {
5570 ASC_DBG1(1,
5571 "adv_isr_callback: underrun condition %lu bytes\n",
5572 (ulong)resid_cnt);
5573 scp->resid = resid_cnt;
5574 }
5575 break;
5576
5577 case QD_WITH_ERROR:
5578 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
5579 switch (scsiqp->host_status) {
5580 case QHSTA_NO_ERROR:
5581 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
5582 ASC_DBG(2,
5583 "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5584 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5585 sizeof(scp->sense_buffer));
5586 /*
5587 * Note: The 'status_byte()' macro used by target drivers
5588 * defined in scsi.h shifts the status byte returned by
5589 * host drivers right by 1 bit. This is why target drivers
5590 * also use right shifted status byte definitions. For
5591 * instance target drivers use CHECK_CONDITION, defined to
5592 * 0x1, instead of the SCSI defined check condition value
5593 * of 0x2. Host drivers are supposed to return the status
5594 * byte as it is defined by SCSI.
5595 */
5596 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5597 STATUS_BYTE(scsiqp->scsi_status);
5598 } else {
5599 scp->result = STATUS_BYTE(scsiqp->scsi_status);
5600 }
5601 break;
5602
5603 default:
5604 /* Some other QHSTA error occurred. */
5605 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
5606 scsiqp->host_status);
5607 scp->result = HOST_BYTE(DID_BAD_TARGET);
5608 break;
5609 }
5610 break;
5611
5612 case QD_ABORTED_BY_HOST:
5613 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
5614 scp->result =
5615 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
5616 break;
5617
5618 default:
5619 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n",
5620 scsiqp->done_status);
5621 scp->result =
5622 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
5623 break;
5624 }
5625
5626 /*
5627 * If the 'init_tidmask' bit isn't already set for the target and the
5628 * current request finished normally, then set the bit for the target
5629 * to indicate that a device is present.
5630 */
5631 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5632 scsiqp->done_status == QD_NO_ERROR &&
5633 scsiqp->host_status == QHSTA_NO_ERROR) {
5634 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5635 }
5636
5637 /*
5638 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5639 * function, add the command to the end of the board's done queue.
5640 * The done function for the command will be called from
5641 * advansys_interrupt().
5642 */
5643 asc_enqueue(&boardp->done, scp, ASC_BACK);
5644
5645 /*
5646 * Free all 'adv_sgblk_t' structures allocated for the request.
5647 */
5648 while ((sgblkp = reqp->sgblkp) != NULL) {
5649 /* Remove 'sgblkp' from the request list. */
5650 reqp->sgblkp = sgblkp->next_sgblkp;
5651
5652 /* Add 'sgblkp' to the board free list. */
5653 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5654 boardp->adv_sgblkp = sgblkp;
5655 }
5656
5657 /*
5658 * Free the adv_req_t structure used with the command by adding
5659 * it back to the board free list.
5660 */
5661 reqp->next_reqp = boardp->adv_reqp;
5662 boardp->adv_reqp = reqp;
5663
5664 ASC_DBG(1, "adv_isr_callback: done\n");
5665
5666 return;
5667 }
5668
5669 /*
5670 * adv_async_callback() - Adv Library asynchronous event callback function.
5671 */
5672 static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
5673 {
5674 switch (code) {
5675 case ADV_ASYNC_SCSI_BUS_RESET_DET:
5676 /*
5677 * The firmware detected a SCSI Bus reset.
5678 */
5679 ASC_DBG(0,
5680 "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
5681 break;
5682
5683 case ADV_ASYNC_RDMA_FAILURE:
5684 /*
5685 * Handle RDMA failure by resetting the SCSI Bus and
5686 * possibly the chip if it is unresponsive. Log the error
5687 * with a unique code.
5688 */
5689 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
5690 AdvResetChipAndSB(adv_dvc_varp);
5691 break;
5692
5693 case ADV_HOST_SCSI_BUS_RESET:
5694 /*
5695 * Host generated SCSI bus reset occurred.
5696 */
5697 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
5698 break;
5699
5700 default:
5701 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
5702 break;
5703 }
5704 }
5705
5706 /*
5707 * Add a 'REQP' to the end of specified queue. Set 'tidmask'
5708 * to indicate a command is queued for the device.
5709 *
5710 * 'flag' may be either ASC_FRONT or ASC_BACK.
5711 *
5712 * 'REQPNEXT(reqp)' returns reqp's next pointer.
5713 */
5714 static void asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
5715 {
5716 int tid;
5717
5718 ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
5719 (ulong)ascq, (ulong)reqp, flag);
5720 ASC_ASSERT(reqp != NULL);
5721 ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
5722 tid = REQPTID(reqp);
5723 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5724 if (flag == ASC_FRONT) {
5725 reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
5726 ascq->q_first[tid] = reqp;
5727 /* If the queue was empty, set the last pointer. */
5728 if (ascq->q_last[tid] == NULL) {
5729 ascq->q_last[tid] = reqp;
5730 }
5731 } else { /* ASC_BACK */
5732 if (ascq->q_last[tid] != NULL) {
5733 ascq->q_last[tid]->host_scribble =
5734 (unsigned char *)reqp;
5735 }
5736 ascq->q_last[tid] = reqp;
5737 reqp->host_scribble = NULL;
5738 /* If the queue was empty, set the first pointer. */
5739 if (ascq->q_first[tid] == NULL) {
5740 ascq->q_first[tid] = reqp;
5741 }
5742 }
5743 /* The queue has at least one entry, set its bit. */
5744 ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
5745 #ifdef ADVANSYS_STATS
5746 /* Maintain request queue statistics. */
5747 ascq->q_tot_cnt[tid]++;
5748 ascq->q_cur_cnt[tid]++;
5749 if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
5750 ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
5751 ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
5752 tid, ascq->q_max_cnt[tid]);
5753 }
5754 REQPTIME(reqp) = REQTIMESTAMP();
5755 #endif /* ADVANSYS_STATS */
5756 ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong)reqp);
5757 return;
5758 }
5759
5760 /*
5761 * Return first queued 'REQP' on the specified queue for
5762 * the specified target device. Clear the 'tidmask' bit for
5763 * the device if no more commands are left queued for it.
5764 *
5765 * 'REQPNEXT(reqp)' returns reqp's next pointer.
5766 */
5767 static REQP asc_dequeue(asc_queue_t *ascq, int tid)
5768 {
5769 REQP reqp;
5770
5771 ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5772 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5773 if ((reqp = ascq->q_first[tid]) != NULL) {
5774 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
5775 ascq->q_first[tid] = REQPNEXT(reqp);
5776 /* If the queue is empty, clear its bit and the last pointer. */
5777 if (ascq->q_first[tid] == NULL) {
5778 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5779 ASC_ASSERT(ascq->q_last[tid] == reqp);
5780 ascq->q_last[tid] = NULL;
5781 }
5782 #ifdef ADVANSYS_STATS
5783 /* Maintain request queue statistics. */
5784 ascq->q_cur_cnt[tid]--;
5785 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
5786 REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
5787 #endif /* ADVANSYS_STATS */
5788 }
5789 ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong)reqp);
5790 return reqp;
5791 }
5792
5793 /*
5794 * Return a pointer to a singly linked list of all the requests queued
5795 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
5796 *
5797 * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
5798 * the last request returned in the singly linked list.
5799 *
5800 * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
5801 * then all queued requests are concatenated into one list and
5802 * returned.
5803 *
5804 * Note: If 'lastpp' is used to append a new list to the end of
5805 * an old list, only change the old list last pointer if '*lastpp'
5806 * (or the function return value) is not NULL, i.e. use a temporary
5807 * variable for 'lastpp' and check its value after the function return
5808 * before assigning it to the list last pointer.
5809 *
5810 * Unfortunately collecting queuing time statistics adds overhead to
5811 * the function that isn't inherent to the function's algorithm.
5812 */
5813 static REQP asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
5814 {
5815 REQP firstp, lastp;
5816 int i;
5817
5818 ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5819 ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
5820
5821 /*
5822 * If 'tid' is not ASC_TID_ALL, return requests only for
5823 * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
5824 * requests for all tids.
5825 */
5826 if (tid != ASC_TID_ALL) {
5827 /* Return all requests for the specified 'tid'. */
5828 if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
5829 /* List is empty; Set first and last return pointers to NULL. */
5830 firstp = lastp = NULL;
5831 } else {
5832 firstp = ascq->q_first[tid];
5833 lastp = ascq->q_last[tid];
5834 ascq->q_first[tid] = ascq->q_last[tid] = NULL;
5835 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5836 #ifdef ADVANSYS_STATS
5837 {
5838 REQP reqp;
5839 ascq->q_cur_cnt[tid] = 0;
5840 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
5841 REQTIMESTAT("asc_dequeue_list", ascq,
5842 reqp, tid);
5843 }
5844 }
5845 #endif /* ADVANSYS_STATS */
5846 }
5847 } else {
5848 /* Return all requests for all tids. */
5849 firstp = lastp = NULL;
5850 for (i = 0; i <= ADV_MAX_TID; i++) {
5851 if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
5852 if (firstp == NULL) {
5853 firstp = ascq->q_first[i];
5854 lastp = ascq->q_last[i];
5855 } else {
5856 ASC_ASSERT(lastp != NULL);
5857 lastp->host_scribble =
5858 (unsigned char *)ascq->q_first[i];
5859 lastp = ascq->q_last[i];
5860 }
5861 ascq->q_first[i] = ascq->q_last[i] = NULL;
5862 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
5863 #ifdef ADVANSYS_STATS
5864 ascq->q_cur_cnt[i] = 0;
5865 #endif /* ADVANSYS_STATS */
5866 }
5867 }
5868 #ifdef ADVANSYS_STATS
5869 {
5870 REQP reqp;
5871 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
5872 REQTIMESTAT("asc_dequeue_list", ascq, reqp,
5873 reqp->device->id);
5874 }
5875 }
5876 #endif /* ADVANSYS_STATS */
5877 }
5878 if (lastpp) {
5879 *lastpp = lastp;
5880 }
5881 ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong)firstp);
5882 return firstp;
5883 }
5884
5885 /*
5886 * Remove the specified 'REQP' from the specified queue for
5887 * the specified target device. Clear the 'tidmask' bit for the
5888 * device if no more commands are left queued for it.
5889 *
5890 * 'REQPNEXT(reqp)' returns reqp's the next pointer.
5891 *
5892 * Return ASC_TRUE if the command was found and removed,
5893 * otherwise return ASC_FALSE.
5894 */
5895 static int asc_rmqueue(asc_queue_t *ascq, REQP reqp)
5896 {
5897 REQP currp, prevp;
5898 int tid;
5899 int ret = ASC_FALSE;
5900
5901 ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
5902 (ulong)ascq, (ulong)reqp);
5903 ASC_ASSERT(reqp != NULL);
5904
5905 tid = REQPTID(reqp);
5906 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5907
5908 /*
5909 * Handle the common case of 'reqp' being the first
5910 * entry on the queue.
5911 */
5912 if (reqp == ascq->q_first[tid]) {
5913 ret = ASC_TRUE;
5914 ascq->q_first[tid] = REQPNEXT(reqp);
5915 /* If the queue is now empty, clear its bit and the last pointer. */
5916 if (ascq->q_first[tid] == NULL) {
5917 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5918 ASC_ASSERT(ascq->q_last[tid] == reqp);
5919 ascq->q_last[tid] = NULL;
5920 }
5921 } else if (ascq->q_first[tid] != NULL) {
5922 ASC_ASSERT(ascq->q_last[tid] != NULL);
5923 /*
5924 * Because the case of 'reqp' being the first entry has been
5925 * handled above and it is known the queue is not empty, if
5926 * 'reqp' is found on the queue it is guaranteed the queue will
5927 * not become empty and that 'q_first[tid]' will not be changed.
5928 *
5929 * Set 'prevp' to the first entry, 'currp' to the second entry,
5930 * and search for 'reqp'.
5931 */
5932 for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
5933 currp; prevp = currp, currp = REQPNEXT(currp)) {
5934 if (currp == reqp) {
5935 ret = ASC_TRUE;
5936 prevp->host_scribble =
5937 (unsigned char *)REQPNEXT(currp);
5938 reqp->host_scribble = NULL;
5939 if (ascq->q_last[tid] == reqp) {
5940 ascq->q_last[tid] = prevp;
5941 }
5942 break;
5943 }
5944 }
5945 }
5946 #ifdef ADVANSYS_STATS
5947 /* Maintain request queue statistics. */
5948 if (ret == ASC_TRUE) {
5949 ascq->q_cur_cnt[tid]--;
5950 REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
5951 }
5952 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
5953 #endif /* ADVANSYS_STATS */
5954 ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong)reqp, ret);
5955 return ret;
5956 }
5957
5958 /*
5959 * Execute as many queued requests as possible for the specified queue.
5960 *
5961 * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd.
5962 */
5963 static void asc_execute_queue(asc_queue_t *ascq)
5964 {
5965 ADV_SCSI_BIT_ID_TYPE scan_tidmask;
5966 REQP reqp;
5967 int i;
5968
5969 ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong)ascq);
5970 /*
5971 * Execute queued commands for devices attached to
5972 * the current board in round-robin fashion.
5973 */
5974 scan_tidmask = ascq->q_tidmask;
5975 do {
5976 for (i = 0; i <= ADV_MAX_TID; i++) {
5977 if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
5978 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
5979 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
5980 } else
5981 if (asc_execute_scsi_cmnd
5982 ((struct scsi_cmnd *)reqp)
5983 == ASC_BUSY) {
5984 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
5985 /*
5986 * The request returned ASC_BUSY. Enqueue at the front of
5987 * target's waiting list to maintain correct ordering.
5988 */
5989 asc_enqueue(ascq, reqp, ASC_FRONT);
5990 }
5991 }
5992 }
5993 } while (scan_tidmask);
5994 return;
5995 }
5996
5997 #ifdef CONFIG_PROC_FS
5998 /*
5999 * asc_prt_board_devices()
6000 *
6001 * Print driver information for devices attached to the board.
6002 *
6003 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6004 * cf. asc_prt_line().
6005 *
6006 * Return the number of characters copied into 'cp'. No more than
6007 * 'cplen' characters will be copied to 'cp'.
6008 */
6009 static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
6010 {
6011 asc_board_t *boardp;
6012 int leftlen;
6013 int totlen;
6014 int len;
6015 int chip_scsi_id;
6016 int i;
6017
6018 boardp = ASC_BOARDP(shost);
6019 leftlen = cplen;
6020 totlen = len = 0;
6021
6022 len = asc_prt_line(cp, leftlen,
6023 "\nDevice Information for AdvanSys SCSI Host %d:\n",
6024 shost->host_no);
6025 ASC_PRT_NEXT();
6026
6027 if (ASC_NARROW_BOARD(boardp)) {
6028 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6029 } else {
6030 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6031 }
6032
6033 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
6034 ASC_PRT_NEXT();
6035 for (i = 0; i <= ADV_MAX_TID; i++) {
6036 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
6037 len = asc_prt_line(cp, leftlen, " %X,", i);
6038 ASC_PRT_NEXT();
6039 }
6040 }
6041 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
6042 ASC_PRT_NEXT();
6043
6044 return totlen;
6045 }
6046
6047 /*
6048 * Display Wide Board BIOS Information.
6049 */
6050 static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
6051 {
6052 asc_board_t *boardp;
6053 int leftlen;
6054 int totlen;
6055 int len;
6056 ushort major, minor, letter;
6057
6058 boardp = ASC_BOARDP(shost);
6059 leftlen = cplen;
6060 totlen = len = 0;
6061
6062 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
6063 ASC_PRT_NEXT();
6064
6065 /*
6066 * If the BIOS saved a valid signature, then fill in
6067 * the BIOS code segment base address.
6068 */
6069 if (boardp->bios_signature != 0x55AA) {
6070 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
6071 ASC_PRT_NEXT();
6072 len = asc_prt_line(cp, leftlen,
6073 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
6074 ASC_PRT_NEXT();
6075 len = asc_prt_line(cp, leftlen,
6076 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
6077 ASC_PRT_NEXT();
6078 } else {
6079 major = (boardp->bios_version >> 12) & 0xF;
6080 minor = (boardp->bios_version >> 8) & 0xF;
6081 letter = (boardp->bios_version & 0xFF);
6082
6083 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
6084 major, minor,
6085 letter >= 26 ? '?' : letter + 'A');
6086 ASC_PRT_NEXT();
6087
6088 /*
6089 * Current available ROM BIOS release is 3.1I for UW
6090 * and 3.2I for U2W. This code doesn't differentiate
6091 * UW and U2W boards.
6092 */
6093 if (major < 3 || (major <= 3 && minor < 1) ||
6094 (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
6095 len = asc_prt_line(cp, leftlen,
6096 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
6097 ASC_PRT_NEXT();
6098 len = asc_prt_line(cp, leftlen,
6099 "ftp://ftp.connectcom.net/pub\n");
6100 ASC_PRT_NEXT();
6101 }
6102 }
6103
6104 return totlen;
6105 }
6106
6107 /*
6108 * Add serial number to information bar if signature AAh
6109 * is found in at bit 15-9 (7 bits) of word 1.
6110 *
6111 * Serial Number consists fo 12 alpha-numeric digits.
6112 *
6113 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
6114 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
6115 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
6116 * 5 - Product revision (A-J) Word0: " "
6117 *
6118 * Signature Word1: 15-9 (7 bits)
6119 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
6120 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
6121 *
6122 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
6123 *
6124 * Note 1: Only production cards will have a serial number.
6125 *
6126 * Note 2: Signature is most significant 7 bits (0xFE).
6127 *
6128 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
6129 */
6130 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
6131 {
6132 ushort w, num;
6133
6134 if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
6135 return ASC_FALSE;
6136 } else {
6137 /*
6138 * First word - 6 digits.
6139 */
6140 w = serialnum[0];
6141
6142 /* Product type - 1st digit. */
6143 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
6144 /* Product type is P=Prototype */
6145 *cp += 0x8;
6146 }
6147 cp++;
6148
6149 /* Manufacturing location - 2nd digit. */
6150 *cp++ = 'A' + ((w & 0x1C00) >> 10);
6151
6152 /* Product ID - 3rd, 4th digits. */
6153 num = w & 0x3FF;
6154 *cp++ = '0' + (num / 100);
6155 num %= 100;
6156 *cp++ = '0' + (num / 10);
6157
6158 /* Product revision - 5th digit. */
6159 *cp++ = 'A' + (num % 10);
6160
6161 /*
6162 * Second word
6163 */
6164 w = serialnum[1];
6165
6166 /*
6167 * Year - 6th digit.
6168 *
6169 * If bit 15 of third word is set, then the
6170 * last digit of the year is greater than 7.
6171 */
6172 if (serialnum[2] & 0x8000) {
6173 *cp++ = '8' + ((w & 0x1C0) >> 6);
6174 } else {
6175 *cp++ = '0' + ((w & 0x1C0) >> 6);
6176 }
6177
6178 /* Week of year - 7th, 8th digits. */
6179 num = w & 0x003F;
6180 *cp++ = '0' + num / 10;
6181 num %= 10;
6182 *cp++ = '0' + num;
6183
6184 /*
6185 * Third word
6186 */
6187 w = serialnum[2] & 0x7FFF;
6188
6189 /* Serial number - 9th digit. */
6190 *cp++ = 'A' + (w / 1000);
6191
6192 /* 10th, 11th, 12th digits. */
6193 num = w % 1000;
6194 *cp++ = '0' + num / 100;
6195 num %= 100;
6196 *cp++ = '0' + num / 10;
6197 num %= 10;
6198 *cp++ = '0' + num;
6199
6200 *cp = '\0'; /* Null Terminate the string. */
6201 return ASC_TRUE;
6202 }
6203 }
6204
6205 /*
6206 * asc_prt_asc_board_eeprom()
6207 *
6208 * Print board EEPROM configuration.
6209 *
6210 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6211 * cf. asc_prt_line().
6212 *
6213 * Return the number of characters copied into 'cp'. No more than
6214 * 'cplen' characters will be copied to 'cp'.
6215 */
6216 static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
6217 {
6218 asc_board_t *boardp;
6219 ASC_DVC_VAR *asc_dvc_varp;
6220 int leftlen;
6221 int totlen;
6222 int len;
6223 ASCEEP_CONFIG *ep;
6224 int i;
6225 #ifdef CONFIG_ISA
6226 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
6227 #endif /* CONFIG_ISA */
6228 uchar serialstr[13];
6229
6230 boardp = ASC_BOARDP(shost);
6231 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6232 ep = &boardp->eep_config.asc_eep;
6233
6234 leftlen = cplen;
6235 totlen = len = 0;
6236
6237 len = asc_prt_line(cp, leftlen,
6238 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6239 shost->host_no);
6240 ASC_PRT_NEXT();
6241
6242 if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
6243 == ASC_TRUE) {
6244 len =
6245 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6246 serialstr);
6247 ASC_PRT_NEXT();
6248 } else {
6249 if (ep->adapter_info[5] == 0xBB) {
6250 len = asc_prt_line(cp, leftlen,
6251 " Default Settings Used for EEPROM-less Adapter.\n");
6252 ASC_PRT_NEXT();
6253 } else {
6254 len = asc_prt_line(cp, leftlen,
6255 " Serial Number Signature Not Present.\n");
6256 ASC_PRT_NEXT();
6257 }
6258 }
6259
6260 len = asc_prt_line(cp, leftlen,
6261 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6262 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
6263 ep->max_tag_qng);
6264 ASC_PRT_NEXT();
6265
6266 len = asc_prt_line(cp, leftlen,
6267 " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
6268 ASC_PRT_NEXT();
6269
6270 len = asc_prt_line(cp, leftlen, " Target ID: ");
6271 ASC_PRT_NEXT();
6272 for (i = 0; i <= ASC_MAX_TID; i++) {
6273 len = asc_prt_line(cp, leftlen, " %d", i);
6274 ASC_PRT_NEXT();
6275 }
6276 len = asc_prt_line(cp, leftlen, "\n");
6277 ASC_PRT_NEXT();
6278
6279 len = asc_prt_line(cp, leftlen, " Disconnects: ");
6280 ASC_PRT_NEXT();
6281 for (i = 0; i <= ASC_MAX_TID; i++) {
6282 len = asc_prt_line(cp, leftlen, " %c",
6283 (ep->
6284 disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6285 'N');
6286 ASC_PRT_NEXT();
6287 }
6288 len = asc_prt_line(cp, leftlen, "\n");
6289 ASC_PRT_NEXT();
6290
6291 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
6292 ASC_PRT_NEXT();
6293 for (i = 0; i <= ASC_MAX_TID; i++) {
6294 len = asc_prt_line(cp, leftlen, " %c",
6295 (ep->
6296 use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6297 'N');
6298 ASC_PRT_NEXT();
6299 }
6300 len = asc_prt_line(cp, leftlen, "\n");
6301 ASC_PRT_NEXT();
6302
6303 len = asc_prt_line(cp, leftlen, " Start Motor: ");
6304 ASC_PRT_NEXT();
6305 for (i = 0; i <= ASC_MAX_TID; i++) {
6306 len = asc_prt_line(cp, leftlen, " %c",
6307 (ep->
6308 start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6309 'N');
6310 ASC_PRT_NEXT();
6311 }
6312 len = asc_prt_line(cp, leftlen, "\n");
6313 ASC_PRT_NEXT();
6314
6315 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6316 ASC_PRT_NEXT();
6317 for (i = 0; i <= ASC_MAX_TID; i++) {
6318 len = asc_prt_line(cp, leftlen, " %c",
6319 (ep->
6320 init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6321 'N');
6322 ASC_PRT_NEXT();
6323 }
6324 len = asc_prt_line(cp, leftlen, "\n");
6325 ASC_PRT_NEXT();
6326
6327 #ifdef CONFIG_ISA
6328 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
6329 len = asc_prt_line(cp, leftlen,
6330 " Host ISA DMA speed: %d MB/S\n",
6331 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
6332 ASC_PRT_NEXT();
6333 }
6334 #endif /* CONFIG_ISA */
6335
6336 return totlen;
6337 }
6338
6339 /*
6340 * asc_prt_adv_board_eeprom()
6341 *
6342 * Print board EEPROM configuration.
6343 *
6344 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6345 * cf. asc_prt_line().
6346 *
6347 * Return the number of characters copied into 'cp'. No more than
6348 * 'cplen' characters will be copied to 'cp'.
6349 */
6350 static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
6351 {
6352 asc_board_t *boardp;
6353 ADV_DVC_VAR *adv_dvc_varp;
6354 int leftlen;
6355 int totlen;
6356 int len;
6357 int i;
6358 char *termstr;
6359 uchar serialstr[13];
6360 ADVEEP_3550_CONFIG *ep_3550 = NULL;
6361 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
6362 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
6363 ushort word;
6364 ushort *wordp;
6365 ushort sdtr_speed = 0;
6366
6367 boardp = ASC_BOARDP(shost);
6368 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6369 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6370 ep_3550 = &boardp->eep_config.adv_3550_eep;
6371 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6372 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
6373 } else {
6374 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
6375 }
6376
6377 leftlen = cplen;
6378 totlen = len = 0;
6379
6380 len = asc_prt_line(cp, leftlen,
6381 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6382 shost->host_no);
6383 ASC_PRT_NEXT();
6384
6385 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6386 wordp = &ep_3550->serial_number_word1;
6387 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6388 wordp = &ep_38C0800->serial_number_word1;
6389 } else {
6390 wordp = &ep_38C1600->serial_number_word1;
6391 }
6392
6393 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
6394 len =
6395 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6396 serialstr);
6397 ASC_PRT_NEXT();
6398 } else {
6399 len = asc_prt_line(cp, leftlen,
6400 " Serial Number Signature Not Present.\n");
6401 ASC_PRT_NEXT();
6402 }
6403
6404 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6405 len = asc_prt_line(cp, leftlen,
6406 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6407 ep_3550->adapter_scsi_id,
6408 ep_3550->max_host_qng, ep_3550->max_dvc_qng);
6409 ASC_PRT_NEXT();
6410 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6411 len = asc_prt_line(cp, leftlen,
6412 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6413 ep_38C0800->adapter_scsi_id,
6414 ep_38C0800->max_host_qng,
6415 ep_38C0800->max_dvc_qng);
6416 ASC_PRT_NEXT();
6417 } else {
6418 len = asc_prt_line(cp, leftlen,
6419 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6420 ep_38C1600->adapter_scsi_id,
6421 ep_38C1600->max_host_qng,
6422 ep_38C1600->max_dvc_qng);
6423 ASC_PRT_NEXT();
6424 }
6425 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6426 word = ep_3550->termination;
6427 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6428 word = ep_38C0800->termination_lvd;
6429 } else {
6430 word = ep_38C1600->termination_lvd;
6431 }
6432 switch (word) {
6433 case 1:
6434 termstr = "Low Off/High Off";
6435 break;
6436 case 2:
6437 termstr = "Low Off/High On";
6438 break;
6439 case 3:
6440 termstr = "Low On/High On";
6441 break;
6442 default:
6443 case 0:
6444 termstr = "Automatic";
6445 break;
6446 }
6447
6448 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6449 len = asc_prt_line(cp, leftlen,
6450 " termination: %u (%s), bios_ctrl: 0x%x\n",
6451 ep_3550->termination, termstr,
6452 ep_3550->bios_ctrl);
6453 ASC_PRT_NEXT();
6454 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6455 len = asc_prt_line(cp, leftlen,
6456 " termination: %u (%s), bios_ctrl: 0x%x\n",
6457 ep_38C0800->termination_lvd, termstr,
6458 ep_38C0800->bios_ctrl);
6459 ASC_PRT_NEXT();
6460 } else {
6461 len = asc_prt_line(cp, leftlen,
6462 " termination: %u (%s), bios_ctrl: 0x%x\n",
6463 ep_38C1600->termination_lvd, termstr,
6464 ep_38C1600->bios_ctrl);
6465 ASC_PRT_NEXT();
6466 }
6467
6468 len = asc_prt_line(cp, leftlen, " Target ID: ");
6469 ASC_PRT_NEXT();
6470 for (i = 0; i <= ADV_MAX_TID; i++) {
6471 len = asc_prt_line(cp, leftlen, " %X", i);
6472 ASC_PRT_NEXT();
6473 }
6474 len = asc_prt_line(cp, leftlen, "\n");
6475 ASC_PRT_NEXT();
6476
6477 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6478 word = ep_3550->disc_enable;
6479 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6480 word = ep_38C0800->disc_enable;
6481 } else {
6482 word = ep_38C1600->disc_enable;
6483 }
6484 len = asc_prt_line(cp, leftlen, " Disconnects: ");
6485 ASC_PRT_NEXT();
6486 for (i = 0; i <= ADV_MAX_TID; i++) {
6487 len = asc_prt_line(cp, leftlen, " %c",
6488 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6489 ASC_PRT_NEXT();
6490 }
6491 len = asc_prt_line(cp, leftlen, "\n");
6492 ASC_PRT_NEXT();
6493
6494 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6495 word = ep_3550->tagqng_able;
6496 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6497 word = ep_38C0800->tagqng_able;
6498 } else {
6499 word = ep_38C1600->tagqng_able;
6500 }
6501 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
6502 ASC_PRT_NEXT();
6503 for (i = 0; i <= ADV_MAX_TID; i++) {
6504 len = asc_prt_line(cp, leftlen, " %c",
6505 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6506 ASC_PRT_NEXT();
6507 }
6508 len = asc_prt_line(cp, leftlen, "\n");
6509 ASC_PRT_NEXT();
6510
6511 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6512 word = ep_3550->start_motor;
6513 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6514 word = ep_38C0800->start_motor;
6515 } else {
6516 word = ep_38C1600->start_motor;
6517 }
6518 len = asc_prt_line(cp, leftlen, " Start Motor: ");
6519 ASC_PRT_NEXT();
6520 for (i = 0; i <= ADV_MAX_TID; i++) {
6521 len = asc_prt_line(cp, leftlen, " %c",
6522 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6523 ASC_PRT_NEXT();
6524 }
6525 len = asc_prt_line(cp, leftlen, "\n");
6526 ASC_PRT_NEXT();
6527
6528 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6529 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6530 ASC_PRT_NEXT();
6531 for (i = 0; i <= ADV_MAX_TID; i++) {
6532 len = asc_prt_line(cp, leftlen, " %c",
6533 (ep_3550->
6534 sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
6535 'Y' : 'N');
6536 ASC_PRT_NEXT();
6537 }
6538 len = asc_prt_line(cp, leftlen, "\n");
6539 ASC_PRT_NEXT();
6540 }
6541
6542 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6543 len = asc_prt_line(cp, leftlen, " Ultra Transfer: ");
6544 ASC_PRT_NEXT();
6545 for (i = 0; i <= ADV_MAX_TID; i++) {
6546 len = asc_prt_line(cp, leftlen, " %c",
6547 (ep_3550->
6548 ultra_able & ADV_TID_TO_TIDMASK(i))
6549 ? 'Y' : 'N');
6550 ASC_PRT_NEXT();
6551 }
6552 len = asc_prt_line(cp, leftlen, "\n");
6553 ASC_PRT_NEXT();
6554 }
6555
6556 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6557 word = ep_3550->wdtr_able;
6558 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6559 word = ep_38C0800->wdtr_able;
6560 } else {
6561 word = ep_38C1600->wdtr_able;
6562 }
6563 len = asc_prt_line(cp, leftlen, " Wide Transfer: ");
6564 ASC_PRT_NEXT();
6565 for (i = 0; i <= ADV_MAX_TID; i++) {
6566 len = asc_prt_line(cp, leftlen, " %c",
6567 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6568 ASC_PRT_NEXT();
6569 }
6570 len = asc_prt_line(cp, leftlen, "\n");
6571 ASC_PRT_NEXT();
6572
6573 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
6574 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
6575 len = asc_prt_line(cp, leftlen,
6576 " Synchronous Transfer Speed (Mhz):\n ");
6577 ASC_PRT_NEXT();
6578 for (i = 0; i <= ADV_MAX_TID; i++) {
6579 char *speed_str;
6580
6581 if (i == 0) {
6582 sdtr_speed = adv_dvc_varp->sdtr_speed1;
6583 } else if (i == 4) {
6584 sdtr_speed = adv_dvc_varp->sdtr_speed2;
6585 } else if (i == 8) {
6586 sdtr_speed = adv_dvc_varp->sdtr_speed3;
6587 } else if (i == 12) {
6588 sdtr_speed = adv_dvc_varp->sdtr_speed4;
6589 }
6590 switch (sdtr_speed & ADV_MAX_TID) {
6591 case 0:
6592 speed_str = "Off";
6593 break;
6594 case 1:
6595 speed_str = " 5";
6596 break;
6597 case 2:
6598 speed_str = " 10";
6599 break;
6600 case 3:
6601 speed_str = " 20";
6602 break;
6603 case 4:
6604 speed_str = " 40";
6605 break;
6606 case 5:
6607 speed_str = " 80";
6608 break;
6609 default:
6610 speed_str = "Unk";
6611 break;
6612 }
6613 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
6614 ASC_PRT_NEXT();
6615 if (i == 7) {
6616 len = asc_prt_line(cp, leftlen, "\n ");
6617 ASC_PRT_NEXT();
6618 }
6619 sdtr_speed >>= 4;
6620 }
6621 len = asc_prt_line(cp, leftlen, "\n");
6622 ASC_PRT_NEXT();
6623 }
6624
6625 return totlen;
6626 }
6627
6628 /*
6629 * asc_prt_driver_conf()
6630 *
6631 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6632 * cf. asc_prt_line().
6633 *
6634 * Return the number of characters copied into 'cp'. No more than
6635 * 'cplen' characters will be copied to 'cp'.
6636 */
6637 static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
6638 {
6639 asc_board_t *boardp;
6640 int leftlen;
6641 int totlen;
6642 int len;
6643 int chip_scsi_id;
6644
6645 boardp = ASC_BOARDP(shost);
6646
6647 leftlen = cplen;
6648 totlen = len = 0;
6649
6650 len = asc_prt_line(cp, leftlen,
6651 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
6652 shost->host_no);
6653 ASC_PRT_NEXT();
6654
6655 len = asc_prt_line(cp, leftlen,
6656 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
6657 shost->host_busy, shost->last_reset, shost->max_id,
6658 shost->max_lun, shost->max_channel);
6659 ASC_PRT_NEXT();
6660
6661 len = asc_prt_line(cp, leftlen,
6662 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
6663 shost->unique_id, shost->can_queue, shost->this_id,
6664 shost->sg_tablesize, shost->cmd_per_lun);
6665 ASC_PRT_NEXT();
6666
6667 len = asc_prt_line(cp, leftlen,
6668 " unchecked_isa_dma %d, use_clustering %d\n",
6669 shost->unchecked_isa_dma, shost->use_clustering);
6670 ASC_PRT_NEXT();
6671
6672 len = asc_prt_line(cp, leftlen,
6673 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
6674 boardp->flags, boardp->last_reset, jiffies,
6675 boardp->asc_n_io_port);
6676 ASC_PRT_NEXT();
6677
6678 len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port);
6679 ASC_PRT_NEXT();
6680
6681 if (ASC_NARROW_BOARD(boardp)) {
6682 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6683 } else {
6684 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6685 }
6686
6687 return totlen;
6688 }
6689
6690 /*
6691 * asc_prt_asc_board_info()
6692 *
6693 * Print dynamic board configuration information.
6694 *
6695 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6696 * cf. asc_prt_line().
6697 *
6698 * Return the number of characters copied into 'cp'. No more than
6699 * 'cplen' characters will be copied to 'cp'.
6700 */
6701 static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
6702 {
6703 asc_board_t *boardp;
6704 int chip_scsi_id;
6705 int leftlen;
6706 int totlen;
6707 int len;
6708 ASC_DVC_VAR *v;
6709 ASC_DVC_CFG *c;
6710 int i;
6711 int renegotiate = 0;
6712
6713 boardp = ASC_BOARDP(shost);
6714 v = &boardp->dvc_var.asc_dvc_var;
6715 c = &boardp->dvc_cfg.asc_dvc_cfg;
6716 chip_scsi_id = c->chip_scsi_id;
6717
6718 leftlen = cplen;
6719 totlen = len = 0;
6720
6721 len = asc_prt_line(cp, leftlen,
6722 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6723 shost->host_no);
6724 ASC_PRT_NEXT();
6725
6726 len = asc_prt_line(cp, leftlen,
6727 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
6728 c->chip_version, c->lib_version, c->lib_serial_no,
6729 c->mcode_date);
6730 ASC_PRT_NEXT();
6731
6732 len = asc_prt_line(cp, leftlen,
6733 " mcode_version 0x%x, err_code %u\n",
6734 c->mcode_version, v->err_code);
6735 ASC_PRT_NEXT();
6736
6737 /* Current number of commands waiting for the host. */
6738 len = asc_prt_line(cp, leftlen,
6739 " Total Command Pending: %d\n", v->cur_total_qng);
6740 ASC_PRT_NEXT();
6741
6742 len = asc_prt_line(cp, leftlen, " Command Queuing:");
6743 ASC_PRT_NEXT();
6744 for (i = 0; i <= ASC_MAX_TID; i++) {
6745 if ((chip_scsi_id == i) ||
6746 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6747 continue;
6748 }
6749 len = asc_prt_line(cp, leftlen, " %X:%c",
6750 i,
6751 (v->
6752 use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
6753 'Y' : 'N');
6754 ASC_PRT_NEXT();
6755 }
6756 len = asc_prt_line(cp, leftlen, "\n");
6757 ASC_PRT_NEXT();
6758
6759 /* Current number of commands waiting for a device. */
6760 len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
6761 ASC_PRT_NEXT();
6762 for (i = 0; i <= ASC_MAX_TID; i++) {
6763 if ((chip_scsi_id == i) ||
6764 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6765 continue;
6766 }
6767 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
6768 ASC_PRT_NEXT();
6769 }
6770 len = asc_prt_line(cp, leftlen, "\n");
6771 ASC_PRT_NEXT();
6772
6773 /* Current limit on number of commands that can be sent to a device. */
6774 len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
6775 ASC_PRT_NEXT();
6776 for (i = 0; i <= ASC_MAX_TID; i++) {
6777 if ((chip_scsi_id == i) ||
6778 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6779 continue;
6780 }
6781 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
6782 ASC_PRT_NEXT();
6783 }
6784 len = asc_prt_line(cp, leftlen, "\n");
6785 ASC_PRT_NEXT();
6786
6787 /* Indicate whether the device has returned queue full status. */
6788 len = asc_prt_line(cp, leftlen, " Command Queue Full:");
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 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
6796 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
6797 i, boardp->queue_full_cnt[i]);
6798 } else {
6799 len = asc_prt_line(cp, leftlen, " %X:N", i);
6800 }
6801 ASC_PRT_NEXT();
6802 }
6803 len = asc_prt_line(cp, leftlen, "\n");
6804 ASC_PRT_NEXT();
6805
6806 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6807 ASC_PRT_NEXT();
6808 for (i = 0; i <= ASC_MAX_TID; i++) {
6809 if ((chip_scsi_id == i) ||
6810 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6811 continue;
6812 }
6813 len = asc_prt_line(cp, leftlen, " %X:%c",
6814 i,
6815 (v->
6816 sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6817 'N');
6818 ASC_PRT_NEXT();
6819 }
6820 len = asc_prt_line(cp, leftlen, "\n");
6821 ASC_PRT_NEXT();
6822
6823 for (i = 0; i <= ASC_MAX_TID; i++) {
6824 uchar syn_period_ix;
6825
6826 if ((chip_scsi_id == i) ||
6827 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
6828 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
6829 continue;
6830 }
6831
6832 len = asc_prt_line(cp, leftlen, " %X:", i);
6833 ASC_PRT_NEXT();
6834
6835 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
6836 len = asc_prt_line(cp, leftlen, " Asynchronous");
6837 ASC_PRT_NEXT();
6838 } else {
6839 syn_period_ix =
6840 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
6841 1);
6842
6843 len = asc_prt_line(cp, leftlen,
6844 " Transfer Period Factor: %d (%d.%d Mhz),",
6845 v->sdtr_period_tbl[syn_period_ix],
6846 250 /
6847 v->sdtr_period_tbl[syn_period_ix],
6848 ASC_TENTHS(250,
6849 v->
6850 sdtr_period_tbl
6851 [syn_period_ix]));
6852 ASC_PRT_NEXT();
6853
6854 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
6855 boardp->
6856 sdtr_data[i] & ASC_SYN_MAX_OFFSET);
6857 ASC_PRT_NEXT();
6858 }
6859
6860 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
6861 len = asc_prt_line(cp, leftlen, "*\n");
6862 renegotiate = 1;
6863 } else {
6864 len = asc_prt_line(cp, leftlen, "\n");
6865 }
6866 ASC_PRT_NEXT();
6867 }
6868
6869 if (renegotiate) {
6870 len = asc_prt_line(cp, leftlen,
6871 " * = Re-negotiation pending before next command.\n");
6872 ASC_PRT_NEXT();
6873 }
6874
6875 return totlen;
6876 }
6877
6878 /*
6879 * asc_prt_adv_board_info()
6880 *
6881 * Print dynamic board configuration information.
6882 *
6883 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6884 * cf. asc_prt_line().
6885 *
6886 * Return the number of characters copied into 'cp'. No more than
6887 * 'cplen' characters will be copied to 'cp'.
6888 */
6889 static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
6890 {
6891 asc_board_t *boardp;
6892 int leftlen;
6893 int totlen;
6894 int len;
6895 int i;
6896 ADV_DVC_VAR *v;
6897 ADV_DVC_CFG *c;
6898 AdvPortAddr iop_base;
6899 ushort chip_scsi_id;
6900 ushort lramword;
6901 uchar lrambyte;
6902 ushort tagqng_able;
6903 ushort sdtr_able, wdtr_able;
6904 ushort wdtr_done, sdtr_done;
6905 ushort period = 0;
6906 int renegotiate = 0;
6907
6908 boardp = ASC_BOARDP(shost);
6909 v = &boardp->dvc_var.adv_dvc_var;
6910 c = &boardp->dvc_cfg.adv_dvc_cfg;
6911 iop_base = v->iop_base;
6912 chip_scsi_id = v->chip_scsi_id;
6913
6914 leftlen = cplen;
6915 totlen = len = 0;
6916
6917 len = asc_prt_line(cp, leftlen,
6918 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6919 shost->host_no);
6920 ASC_PRT_NEXT();
6921
6922 len = asc_prt_line(cp, leftlen,
6923 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
6924 v->iop_base,
6925 AdvReadWordRegister(iop_base,
6926 IOPW_SCSI_CFG1) & CABLE_DETECT,
6927 v->err_code);
6928 ASC_PRT_NEXT();
6929
6930 len = asc_prt_line(cp, leftlen,
6931 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
6932 c->chip_version, c->lib_version, c->mcode_date,
6933 c->mcode_version);
6934 ASC_PRT_NEXT();
6935
6936 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
6937 len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
6938 ASC_PRT_NEXT();
6939 for (i = 0; i <= ADV_MAX_TID; i++) {
6940 if ((chip_scsi_id == i) ||
6941 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6942 continue;
6943 }
6944
6945 len = asc_prt_line(cp, leftlen, " %X:%c",
6946 i,
6947 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6948 'N');
6949 ASC_PRT_NEXT();
6950 }
6951 len = asc_prt_line(cp, leftlen, "\n");
6952 ASC_PRT_NEXT();
6953
6954 len = asc_prt_line(cp, leftlen, " Queue Limit:");
6955 ASC_PRT_NEXT();
6956 for (i = 0; i <= ADV_MAX_TID; i++) {
6957 if ((chip_scsi_id == i) ||
6958 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6959 continue;
6960 }
6961
6962 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
6963 lrambyte);
6964
6965 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
6966 ASC_PRT_NEXT();
6967 }
6968 len = asc_prt_line(cp, leftlen, "\n");
6969 ASC_PRT_NEXT();
6970
6971 len = asc_prt_line(cp, leftlen, " Command Pending:");
6972 ASC_PRT_NEXT();
6973 for (i = 0; i <= ADV_MAX_TID; i++) {
6974 if ((chip_scsi_id == i) ||
6975 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6976 continue;
6977 }
6978
6979 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
6980 lrambyte);
6981
6982 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
6983 ASC_PRT_NEXT();
6984 }
6985 len = asc_prt_line(cp, leftlen, "\n");
6986 ASC_PRT_NEXT();
6987
6988 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
6989 len = asc_prt_line(cp, leftlen, " Wide Enabled:");
6990 ASC_PRT_NEXT();
6991 for (i = 0; i <= ADV_MAX_TID; i++) {
6992 if ((chip_scsi_id == i) ||
6993 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6994 continue;
6995 }
6996
6997 len = asc_prt_line(cp, leftlen, " %X:%c",
6998 i,
6999 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7000 'N');
7001 ASC_PRT_NEXT();
7002 }
7003 len = asc_prt_line(cp, leftlen, "\n");
7004 ASC_PRT_NEXT();
7005
7006 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
7007 len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
7008 ASC_PRT_NEXT();
7009 for (i = 0; i <= ADV_MAX_TID; i++) {
7010 if ((chip_scsi_id == i) ||
7011 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7012 continue;
7013 }
7014
7015 AdvReadWordLram(iop_base,
7016 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7017 lramword);
7018
7019 len = asc_prt_line(cp, leftlen, " %X:%d",
7020 i, (lramword & 0x8000) ? 16 : 8);
7021 ASC_PRT_NEXT();
7022
7023 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
7024 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7025 len = asc_prt_line(cp, leftlen, "*");
7026 ASC_PRT_NEXT();
7027 renegotiate = 1;
7028 }
7029 }
7030 len = asc_prt_line(cp, leftlen, "\n");
7031 ASC_PRT_NEXT();
7032
7033 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7034 len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
7035 ASC_PRT_NEXT();
7036 for (i = 0; i <= ADV_MAX_TID; i++) {
7037 if ((chip_scsi_id == i) ||
7038 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7039 continue;
7040 }
7041
7042 len = asc_prt_line(cp, leftlen, " %X:%c",
7043 i,
7044 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7045 'N');
7046 ASC_PRT_NEXT();
7047 }
7048 len = asc_prt_line(cp, leftlen, "\n");
7049 ASC_PRT_NEXT();
7050
7051 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
7052 for (i = 0; i <= ADV_MAX_TID; i++) {
7053
7054 AdvReadWordLram(iop_base,
7055 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7056 lramword);
7057 lramword &= ~0x8000;
7058
7059 if ((chip_scsi_id == i) ||
7060 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
7061 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
7062 continue;
7063 }
7064
7065 len = asc_prt_line(cp, leftlen, " %X:", i);
7066 ASC_PRT_NEXT();
7067
7068 if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */
7069 len = asc_prt_line(cp, leftlen, " Asynchronous");
7070 ASC_PRT_NEXT();
7071 } else {
7072 len =
7073 asc_prt_line(cp, leftlen,
7074 " Transfer Period Factor: ");
7075 ASC_PRT_NEXT();
7076
7077 if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */
7078 len =
7079 asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
7080 ASC_PRT_NEXT();
7081 } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */
7082 len =
7083 asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
7084 ASC_PRT_NEXT();
7085 } else { /* 20 Mhz or below. */
7086
7087 period = (((lramword >> 8) * 25) + 50) / 4;
7088
7089 if (period == 0) { /* Should never happen. */
7090 len =
7091 asc_prt_line(cp, leftlen,
7092 "%d (? Mhz), ");
7093 ASC_PRT_NEXT();
7094 } else {
7095 len = asc_prt_line(cp, leftlen,
7096 "%d (%d.%d Mhz),",
7097 period, 250 / period,
7098 ASC_TENTHS(250,
7099 period));
7100 ASC_PRT_NEXT();
7101 }
7102 }
7103
7104 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
7105 lramword & 0x1F);
7106 ASC_PRT_NEXT();
7107 }
7108
7109 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7110 len = asc_prt_line(cp, leftlen, "*\n");
7111 renegotiate = 1;
7112 } else {
7113 len = asc_prt_line(cp, leftlen, "\n");
7114 }
7115 ASC_PRT_NEXT();
7116 }
7117
7118 if (renegotiate) {
7119 len = asc_prt_line(cp, leftlen,
7120 " * = Re-negotiation pending before next command.\n");
7121 ASC_PRT_NEXT();
7122 }
7123
7124 return totlen;
7125 }
7126
7127 /*
7128 * asc_proc_copy()
7129 *
7130 * Copy proc information to a read buffer taking into account the current
7131 * read offset in the file and the remaining space in the read buffer.
7132 */
7133 static int
7134 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
7135 char *cp, int cplen)
7136 {
7137 int cnt = 0;
7138
7139 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
7140 (unsigned)offset, (unsigned)advoffset, cplen);
7141 if (offset <= advoffset) {
7142 /* Read offset below current offset, copy everything. */
7143 cnt = min(cplen, leftlen);
7144 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7145 (ulong)curbuf, (ulong)cp, cnt);
7146 memcpy(curbuf, cp, cnt);
7147 } else if (offset < advoffset + cplen) {
7148 /* Read offset within current range, partial copy. */
7149 cnt = (advoffset + cplen) - offset;
7150 cp = (cp + cplen) - cnt;
7151 cnt = min(cnt, leftlen);
7152 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7153 (ulong)curbuf, (ulong)cp, cnt);
7154 memcpy(curbuf, cp, cnt);
7155 }
7156 return cnt;
7157 }
7158
7159 /*
7160 * asc_prt_line()
7161 *
7162 * If 'cp' is NULL print to the console, otherwise print to a buffer.
7163 *
7164 * Return 0 if printing to the console, otherwise return the number of
7165 * bytes written to the buffer.
7166 *
7167 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
7168 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
7169 */
7170 static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
7171 {
7172 va_list args;
7173 int ret;
7174 char s[ASC_PRTLINE_SIZE];
7175
7176 va_start(args, fmt);
7177 ret = vsprintf(s, fmt, args);
7178 ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
7179 if (buf == NULL) {
7180 (void)printk(s);
7181 ret = 0;
7182 } else {
7183 ret = min(buflen, ret);
7184 memcpy(buf, s, ret);
7185 }
7186 va_end(args);
7187 return ret;
7188 }
7189 #endif /* CONFIG_PROC_FS */
7190
7191 /*
7192 * --- Functions Required by the Asc Library
7193 */
7194
7195 /*
7196 * Delay for 'n' milliseconds. Don't use the 'jiffies'
7197 * global variable which is incremented once every 5 ms
7198 * from a timer interrupt, because this function may be
7199 * called when interrupts are disabled.
7200 */
7201 static void DvcSleepMilliSecond(ADV_DCNT n)
7202 {
7203 ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong)n);
7204 mdelay(n);
7205 }
7206
7207 /*
7208 * Currently and inline noop but leave as a placeholder.
7209 * Leave DvcEnterCritical() as a noop placeholder.
7210 */
7211 static inline ulong DvcEnterCritical(void)
7212 {
7213 return 0;
7214 }
7215
7216 /*
7217 * Critical sections are all protected by the board spinlock.
7218 * Leave DvcLeaveCritical() as a noop placeholder.
7219 */
7220 static inline void DvcLeaveCritical(ulong flags)
7221 {
7222 return;
7223 }
7224
7225 /*
7226 * void
7227 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7228 *
7229 * Calling/Exit State:
7230 * none
7231 *
7232 * Description:
7233 * Output an ASC_SCSI_Q structure to the chip
7234 */
7235 static void
7236 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7237 {
7238 int i;
7239
7240 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
7241 AscSetChipLramAddr(iop_base, s_addr);
7242 for (i = 0; i < 2 * words; i += 2) {
7243 if (i == 4 || i == 20) {
7244 continue;
7245 }
7246 outpw(iop_base + IOP_RAM_DATA,
7247 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
7248 }
7249 }
7250
7251 /*
7252 * void
7253 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7254 *
7255 * Calling/Exit State:
7256 * none
7257 *
7258 * Description:
7259 * Input an ASC_QDONE_INFO structure from the chip
7260 */
7261 static void
7262 DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7263 {
7264 int i;
7265 ushort word;
7266
7267 AscSetChipLramAddr(iop_base, s_addr);
7268 for (i = 0; i < 2 * words; i += 2) {
7269 if (i == 10) {
7270 continue;
7271 }
7272 word = inpw(iop_base + IOP_RAM_DATA);
7273 inbuf[i] = word & 0xff;
7274 inbuf[i + 1] = (word >> 8) & 0xff;
7275 }
7276 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
7277 }
7278
7279 /*
7280 * Return the BIOS address of the adapter at the specified
7281 * I/O port and with the specified bus type.
7282 */
7283 static unsigned short __devinit
7284 AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type)
7285 {
7286 unsigned short cfg_lsw;
7287 unsigned short bios_addr;
7288
7289 /*
7290 * The PCI BIOS is re-located by the motherboard BIOS. Because
7291 * of this the driver can not determine where a PCI BIOS is
7292 * loaded and executes.
7293 */
7294 if (bus_type & ASC_IS_PCI)
7295 return 0;
7296
7297 #ifdef CONFIG_ISA
7298 if ((bus_type & ASC_IS_EISA) != 0) {
7299 cfg_lsw = AscGetEisaChipCfg(iop_base);
7300 cfg_lsw &= 0x000F;
7301 bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
7302 return bios_addr;
7303 }
7304 #endif /* CONFIG_ISA */
7305
7306 cfg_lsw = AscGetChipCfgLsw(iop_base);
7307
7308 /*
7309 * ISA PnP uses the top bit as the 32K BIOS flag
7310 */
7311 if (bus_type == ASC_IS_ISAPNP)
7312 cfg_lsw &= 0x7FFF;
7313 bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
7314 return bios_addr;
7315 }
7316
7317 /*
7318 * --- Functions Required by the Adv Library
7319 */
7320
7321 /*
7322 * DvcGetPhyAddr()
7323 *
7324 * Return the physical address of 'vaddr' and set '*lenp' to the
7325 * number of physically contiguous bytes that follow 'vaddr'.
7326 * 'flag' indicates the type of structure whose physical address
7327 * is being translated.
7328 *
7329 * Note: Because Linux currently doesn't page the kernel and all
7330 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
7331 */
7332 ADV_PADDR
7333 DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
7334 uchar *vaddr, ADV_SDCNT *lenp, int flag)
7335 {
7336 ADV_PADDR paddr;
7337
7338 paddr = virt_to_bus(vaddr);
7339
7340 ASC_DBG4(4,
7341 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
7342 (ulong)vaddr, (ulong)lenp, (ulong)*((ulong *)lenp),
7343 (ulong)paddr);
7344
7345 return paddr;
7346 }
7347
7348 /*
7349 * --- Tracing and Debugging Functions
7350 */
7351
7352 #ifdef ADVANSYS_STATS
7353 #ifdef CONFIG_PROC_FS
7354 /*
7355 * asc_prt_board_stats()
7356 *
7357 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7358 * cf. asc_prt_line().
7359 *
7360 * Return the number of characters copied into 'cp'. No more than
7361 * 'cplen' characters will be copied to 'cp'.
7362 */
7363 static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
7364 {
7365 int leftlen;
7366 int totlen;
7367 int len;
7368 struct asc_stats *s;
7369 asc_board_t *boardp;
7370
7371 leftlen = cplen;
7372 totlen = len = 0;
7373
7374 boardp = ASC_BOARDP(shost);
7375 s = &boardp->asc_stats;
7376
7377 len = asc_prt_line(cp, leftlen,
7378 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
7379 shost->host_no);
7380 ASC_PRT_NEXT();
7381
7382 len = asc_prt_line(cp, leftlen,
7383 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
7384 s->queuecommand, s->reset, s->biosparam,
7385 s->interrupt);
7386 ASC_PRT_NEXT();
7387
7388 len = asc_prt_line(cp, leftlen,
7389 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
7390 s->callback, s->done, s->build_error,
7391 s->adv_build_noreq, s->adv_build_nosg);
7392 ASC_PRT_NEXT();
7393
7394 len = asc_prt_line(cp, leftlen,
7395 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
7396 s->exe_noerror, s->exe_busy, s->exe_error,
7397 s->exe_unknown);
7398 ASC_PRT_NEXT();
7399
7400 /*
7401 * Display data transfer statistics.
7402 */
7403 if (s->cont_cnt > 0) {
7404 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
7405 ASC_PRT_NEXT();
7406
7407 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
7408 s->cont_xfer / 2,
7409 ASC_TENTHS(s->cont_xfer, 2));
7410 ASC_PRT_NEXT();
7411
7412 /* Contiguous transfer average size */
7413 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
7414 (s->cont_xfer / 2) / s->cont_cnt,
7415 ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
7416 ASC_PRT_NEXT();
7417 }
7418
7419 if (s->sg_cnt > 0) {
7420
7421 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
7422 s->sg_cnt, s->sg_elem);
7423 ASC_PRT_NEXT();
7424
7425 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
7426 s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
7427 ASC_PRT_NEXT();
7428
7429 /* Scatter gather transfer statistics */
7430 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
7431 s->sg_elem / s->sg_cnt,
7432 ASC_TENTHS(s->sg_elem, s->sg_cnt));
7433 ASC_PRT_NEXT();
7434
7435 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
7436 (s->sg_xfer / 2) / s->sg_elem,
7437 ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
7438 ASC_PRT_NEXT();
7439
7440 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
7441 (s->sg_xfer / 2) / s->sg_cnt,
7442 ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
7443 ASC_PRT_NEXT();
7444 }
7445
7446 /*
7447 * Display request queuing statistics.
7448 */
7449 len = asc_prt_line(cp, leftlen,
7450 " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
7451 HZ);
7452 ASC_PRT_NEXT();
7453
7454 return totlen;
7455 }
7456
7457 /*
7458 * asc_prt_target_stats()
7459 *
7460 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7461 * cf. asc_prt_line().
7462 *
7463 * This is separated from asc_prt_board_stats because a full set
7464 * of targets will overflow ASC_PRTBUF_SIZE.
7465 *
7466 * Return the number of characters copied into 'cp'. No more than
7467 * 'cplen' characters will be copied to 'cp'.
7468 */
7469 static int
7470 asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen)
7471 {
7472 int leftlen;
7473 int totlen;
7474 int len;
7475 struct asc_stats *s;
7476 ushort chip_scsi_id;
7477 asc_board_t *boardp;
7478 asc_queue_t *active;
7479 asc_queue_t *waiting;
7480
7481 leftlen = cplen;
7482 totlen = len = 0;
7483
7484 boardp = ASC_BOARDP(shost);
7485 s = &boardp->asc_stats;
7486
7487 active = &ASC_BOARDP(shost)->active;
7488 waiting = &ASC_BOARDP(shost)->waiting;
7489
7490 if (ASC_NARROW_BOARD(boardp)) {
7491 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7492 } else {
7493 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7494 }
7495
7496 if ((chip_scsi_id == tgt_id) ||
7497 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
7498 return 0;
7499 }
7500
7501 do {
7502 if (active->q_tot_cnt[tgt_id] > 0
7503 || waiting->q_tot_cnt[tgt_id] > 0) {
7504 len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
7505 ASC_PRT_NEXT();
7506
7507 len = asc_prt_line(cp, leftlen,
7508 " active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
7509 active->q_cur_cnt[tgt_id],
7510 active->q_max_cnt[tgt_id],
7511 active->q_tot_cnt[tgt_id],
7512 active->q_min_tim[tgt_id],
7513 active->q_max_tim[tgt_id],
7514 (active->q_tot_cnt[tgt_id] ==
7515 0) ? 0 : (active->
7516 q_tot_tim[tgt_id] /
7517 active->
7518 q_tot_cnt[tgt_id]),
7519 (active->q_tot_cnt[tgt_id] ==
7520 0) ? 0 : ASC_TENTHS(active->
7521 q_tot_tim
7522 [tgt_id],
7523 active->
7524 q_tot_cnt
7525 [tgt_id]));
7526 ASC_PRT_NEXT();
7527
7528 len = asc_prt_line(cp, leftlen,
7529 " waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
7530 waiting->q_cur_cnt[tgt_id],
7531 waiting->q_max_cnt[tgt_id],
7532 waiting->q_tot_cnt[tgt_id],
7533 waiting->q_min_tim[tgt_id],
7534 waiting->q_max_tim[tgt_id],
7535 (waiting->q_tot_cnt[tgt_id] ==
7536 0) ? 0 : (waiting->
7537 q_tot_tim[tgt_id] /
7538 waiting->
7539 q_tot_cnt[tgt_id]),
7540 (waiting->q_tot_cnt[tgt_id] ==
7541 0) ? 0 : ASC_TENTHS(waiting->
7542 q_tot_tim
7543 [tgt_id],
7544 waiting->
7545 q_tot_cnt
7546 [tgt_id]));
7547 ASC_PRT_NEXT();
7548 }
7549 } while (0);
7550
7551 return totlen;
7552 }
7553 #endif /* CONFIG_PROC_FS */
7554 #endif /* ADVANSYS_STATS */
7555
7556 #ifdef ADVANSYS_DEBUG
7557 /*
7558 * asc_prt_scsi_host()
7559 */
7560 static void asc_prt_scsi_host(struct Scsi_Host *s)
7561 {
7562 asc_board_t *boardp;
7563
7564 boardp = ASC_BOARDP(s);
7565
7566 printk("Scsi_Host at addr 0x%lx\n", (ulong)s);
7567 printk(" host_busy %u, host_no %d, last_reset %d,\n",
7568 s->host_busy, s->host_no, (unsigned)s->last_reset);
7569
7570 printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n",
7571 (ulong)s->base, (ulong)s->io_port, s->irq);
7572
7573 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
7574 s->dma_channel, s->this_id, s->can_queue);
7575
7576 printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
7577 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
7578
7579 if (ASC_NARROW_BOARD(boardp)) {
7580 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
7581 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
7582 } else {
7583 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
7584 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
7585 }
7586 }
7587
7588 /*
7589 * asc_prt_scsi_cmnd()
7590 */
7591 static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
7592 {
7593 printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s);
7594
7595 printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
7596 (ulong)s->device->host, (ulong)s->device, s->device->id,
7597 s->device->lun, s->device->channel);
7598
7599 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
7600
7601 printk("sc_data_direction %u, resid %d\n",
7602 s->sc_data_direction, s->resid);
7603
7604 printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len);
7605
7606 printk(" serial_number 0x%x, retries %d, allowed %d\n",
7607 (unsigned)s->serial_number, s->retries, s->allowed);
7608
7609 printk(" timeout_per_command %d\n", s->timeout_per_command);
7610
7611 printk(" scsi_done 0x%p, done 0x%p, host_scribble 0x%p, result 0x%x\n",
7612 s->scsi_done, s->done, s->host_scribble, s->result);
7613
7614 printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
7615 }
7616
7617 /*
7618 * asc_prt_asc_dvc_var()
7619 */
7620 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
7621 {
7622 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
7623
7624 printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl "
7625 "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
7626
7627 printk(" bus_type %d, isr_callback 0x%p, exe_callback 0x%p, "
7628 "init_sdtr 0x%x,\n", h->bus_type, h->isr_callback,
7629 h->exe_callback, (unsigned)h->init_sdtr);
7630
7631 printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, "
7632 "chip_no 0x%x,\n", (unsigned)h->sdtr_done,
7633 (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready,
7634 (unsigned)h->chip_no);
7635
7636 printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait "
7637 "%u,\n", (unsigned)h->queue_full_or_busy,
7638 (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
7639
7640 printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, "
7641 "in_critical_cnt %u,\n", (unsigned)h->is_in_int,
7642 (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng,
7643 (unsigned)h->in_critical_cnt);
7644
7645 printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, "
7646 "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage,
7647 (unsigned)h->init_state, (unsigned)h->no_scam,
7648 (unsigned)h->pci_fix_asyn_xfer);
7649
7650 printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no);
7651 }
7652
7653 /*
7654 * asc_prt_asc_dvc_cfg()
7655 */
7656 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
7657 {
7658 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
7659
7660 printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
7661 h->can_tagged_qng, h->cmd_qng_enabled);
7662 printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
7663 h->disc_enable, h->sdtr_enable);
7664
7665 printk
7666 (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
7667 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
7668 h->chip_version);
7669
7670 printk
7671 (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
7672 to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
7673 h->mcode_date);
7674
7675 printk(" mcode_version %d, overrun_buf 0x%lx\n",
7676 h->mcode_version, (ulong)h->overrun_buf);
7677 }
7678
7679 /*
7680 * asc_prt_asc_scsi_q()
7681 */
7682 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
7683 {
7684 ASC_SG_HEAD *sgp;
7685 int i;
7686
7687 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
7688
7689 printk
7690 (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
7691 q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
7692 q->q2.tag_code);
7693
7694 printk
7695 (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7696 (ulong)le32_to_cpu(q->q1.data_addr),
7697 (ulong)le32_to_cpu(q->q1.data_cnt),
7698 (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
7699
7700 printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
7701 (ulong)q->cdbptr, q->q2.cdb_len,
7702 (ulong)q->sg_head, q->q1.sg_queue_cnt);
7703
7704 if (q->sg_head) {
7705 sgp = q->sg_head;
7706 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
7707 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
7708 sgp->queue_cnt);
7709 for (i = 0; i < sgp->entry_cnt; i++) {
7710 printk(" [%u]: addr 0x%lx, bytes %lu\n",
7711 i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
7712 (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
7713 }
7714
7715 }
7716 }
7717
7718 /*
7719 * asc_prt_asc_qdone_info()
7720 */
7721 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
7722 {
7723 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
7724 printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
7725 (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
7726 q->d2.tag_code);
7727 printk
7728 (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
7729 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
7730 }
7731
7732 /*
7733 * asc_prt_adv_dvc_var()
7734 *
7735 * Display an ADV_DVC_VAR structure.
7736 */
7737 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
7738 {
7739 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
7740
7741 printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
7742 (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
7743
7744 printk(" isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
7745 (ulong)h->isr_callback, (unsigned)h->sdtr_able,
7746 (unsigned)h->wdtr_able);
7747
7748 printk(" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
7749 (unsigned)h->start_motor,
7750 (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no);
7751
7752 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
7753 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
7754 (ulong)h->carr_freelist);
7755
7756 printk(" icq_sp 0x%lx, irq_sp 0x%lx\n",
7757 (ulong)h->icq_sp, (ulong)h->irq_sp);
7758
7759 printk(" no_scam 0x%x, tagqng_able 0x%x\n",
7760 (unsigned)h->no_scam, (unsigned)h->tagqng_able);
7761
7762 printk(" chip_scsi_id 0x%x, cfg 0x%lx\n",
7763 (unsigned)h->chip_scsi_id, (ulong)h->cfg);
7764 }
7765
7766 /*
7767 * asc_prt_adv_dvc_cfg()
7768 *
7769 * Display an ADV_DVC_CFG structure.
7770 */
7771 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
7772 {
7773 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
7774
7775 printk(" disc_enable 0x%x, termination 0x%x\n",
7776 h->disc_enable, h->termination);
7777
7778 printk(" chip_version 0x%x, mcode_date 0x%x\n",
7779 h->chip_version, h->mcode_date);
7780
7781 printk(" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
7782 h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
7783
7784 printk(" control_flag 0x%x, pci_slot_info 0x%x\n",
7785 h->control_flag, h->pci_slot_info);
7786 }
7787
7788 /*
7789 * asc_prt_adv_scsi_req_q()
7790 *
7791 * Display an ADV_SCSI_REQ_Q structure.
7792 */
7793 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
7794 {
7795 int sg_blk_cnt;
7796 struct asc_sg_block *sg_ptr;
7797
7798 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
7799
7800 printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
7801 q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
7802
7803 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
7804 q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
7805
7806 printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7807 (ulong)le32_to_cpu(q->data_cnt),
7808 (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
7809
7810 printk
7811 (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
7812 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
7813
7814 printk(" sg_working_ix 0x%x, target_cmd %u\n",
7815 q->sg_working_ix, q->target_cmd);
7816
7817 printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
7818 (ulong)le32_to_cpu(q->scsiq_rptr),
7819 (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
7820
7821 /* Display the request's ADV_SG_BLOCK structures. */
7822 if (q->sg_list_ptr != NULL) {
7823 sg_blk_cnt = 0;
7824 while (1) {
7825 /*
7826 * 'sg_ptr' is a physical address. Convert it to a virtual
7827 * address by indexing 'sg_blk_cnt' into the virtual address
7828 * array 'sg_list_ptr'.
7829 *
7830 * XXX - Assumes all SG physical blocks are virtually contiguous.
7831 */
7832 sg_ptr =
7833 &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
7834 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
7835 if (sg_ptr->sg_ptr == 0) {
7836 break;
7837 }
7838 sg_blk_cnt++;
7839 }
7840 }
7841 }
7842
7843 /*
7844 * asc_prt_adv_sgblock()
7845 *
7846 * Display an ADV_SG_BLOCK structure.
7847 */
7848 static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
7849 {
7850 int i;
7851
7852 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
7853 (ulong)b, sgblockno);
7854 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
7855 b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
7856 ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
7857 if (b->sg_ptr != 0) {
7858 ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
7859 }
7860 for (i = 0; i < b->sg_cnt; i++) {
7861 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
7862 i, (ulong)b->sg_list[i].sg_addr,
7863 (ulong)b->sg_list[i].sg_count);
7864 }
7865 }
7866
7867 /*
7868 * asc_prt_hex()
7869 *
7870 * Print hexadecimal output in 4 byte groupings 32 bytes
7871 * or 8 double-words per line.
7872 */
7873 static void asc_prt_hex(char *f, uchar *s, int l)
7874 {
7875 int i;
7876 int j;
7877 int k;
7878 int m;
7879
7880 printk("%s: (%d bytes)\n", f, l);
7881
7882 for (i = 0; i < l; i += 32) {
7883
7884 /* Display a maximum of 8 double-words per line. */
7885 if ((k = (l - i) / 4) >= 8) {
7886 k = 8;
7887 m = 0;
7888 } else {
7889 m = (l - i) % 4;
7890 }
7891
7892 for (j = 0; j < k; j++) {
7893 printk(" %2.2X%2.2X%2.2X%2.2X",
7894 (unsigned)s[i + (j * 4)],
7895 (unsigned)s[i + (j * 4) + 1],
7896 (unsigned)s[i + (j * 4) + 2],
7897 (unsigned)s[i + (j * 4) + 3]);
7898 }
7899
7900 switch (m) {
7901 case 0:
7902 default:
7903 break;
7904 case 1:
7905 printk(" %2.2X", (unsigned)s[i + (j * 4)]);
7906 break;
7907 case 2:
7908 printk(" %2.2X%2.2X",
7909 (unsigned)s[i + (j * 4)],
7910 (unsigned)s[i + (j * 4) + 1]);
7911 break;
7912 case 3:
7913 printk(" %2.2X%2.2X%2.2X",
7914 (unsigned)s[i + (j * 4) + 1],
7915 (unsigned)s[i + (j * 4) + 2],
7916 (unsigned)s[i + (j * 4) + 3]);
7917 break;
7918 }
7919
7920 printk("\n");
7921 }
7922 }
7923 #endif /* ADVANSYS_DEBUG */
7924
7925 /*
7926 * --- Asc Library Functions
7927 */
7928
7929 static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
7930 {
7931 PortAddr eisa_cfg_iop;
7932
7933 eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
7934 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
7935 return (inpw(eisa_cfg_iop));
7936 }
7937
7938 static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
7939 {
7940 ushort cfg_lsw;
7941
7942 if (AscGetChipScsiID(iop_base) == new_host_id) {
7943 return (new_host_id);
7944 }
7945 cfg_lsw = AscGetChipCfgLsw(iop_base);
7946 cfg_lsw &= 0xF8FF;
7947 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
7948 AscSetChipCfgLsw(iop_base, cfg_lsw);
7949 return (AscGetChipScsiID(iop_base));
7950 }
7951
7952 static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base)
7953 {
7954 unsigned char sc;
7955
7956 AscSetBank(iop_base, 1);
7957 sc = inp(iop_base + IOP_REG_SC);
7958 AscSetBank(iop_base, 0);
7959 return sc;
7960 }
7961
7962 static unsigned char __devinit
7963 AscGetChipVersion(PortAddr iop_base, unsigned short bus_type)
7964 {
7965 if (bus_type & ASC_IS_EISA) {
7966 PortAddr eisa_iop;
7967 unsigned char revision;
7968 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
7969 (PortAddr) ASC_EISA_REV_IOP_MASK;
7970 revision = inp(eisa_iop);
7971 return ASC_CHIP_MIN_VER_EISA - 1 + revision;
7972 }
7973 return AscGetChipVerNo(iop_base);
7974 }
7975
7976 static ASC_DCNT
7977 AscLoadMicroCode(PortAddr iop_base,
7978 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
7979 {
7980 ASC_DCNT chksum;
7981 ushort mcode_word_size;
7982 ushort mcode_chksum;
7983
7984 /* Write the microcode buffer starting at LRAM address 0. */
7985 mcode_word_size = (ushort)(mcode_size >> 1);
7986 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
7987 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
7988
7989 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
7990 ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum);
7991 mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
7992 (ushort)ASC_CODE_SEC_BEG,
7993 (ushort)((mcode_size -
7994 s_addr - (ushort)
7995 ASC_CODE_SEC_BEG) /
7996 2));
7997 ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
7998 (ulong)mcode_chksum);
7999 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
8000 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
8001 return (chksum);
8002 }
8003
8004 static int AscFindSignature(PortAddr iop_base)
8005 {
8006 ushort sig_word;
8007
8008 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
8009 iop_base, AscGetChipSignatureByte(iop_base));
8010 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
8011 ASC_DBG2(1,
8012 "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
8013 iop_base, AscGetChipSignatureWord(iop_base));
8014 sig_word = AscGetChipSignatureWord(iop_base);
8015 if ((sig_word == (ushort)ASC_1000_ID0W) ||
8016 (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
8017 return (1);
8018 }
8019 }
8020 return (0);
8021 }
8022
8023 static void __devinit AscToggleIRQAct(PortAddr iop_base)
8024 {
8025 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
8026 AscSetChipStatus(iop_base, 0);
8027 return;
8028 }
8029
8030 static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
8031 {
8032 ushort cfg_lsw;
8033 uchar chip_irq;
8034
8035 if ((bus_type & ASC_IS_EISA) != 0) {
8036 cfg_lsw = AscGetEisaChipCfg(iop_base);
8037 chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10);
8038 if ((chip_irq == 13) || (chip_irq > 15)) {
8039 return (0);
8040 }
8041 return (chip_irq);
8042 }
8043 if ((bus_type & ASC_IS_VL) != 0) {
8044 cfg_lsw = AscGetChipCfgLsw(iop_base);
8045 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07));
8046 if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) {
8047 return (0);
8048 }
8049 return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1)));
8050 }
8051 cfg_lsw = AscGetChipCfgLsw(iop_base);
8052 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03));
8053 if (chip_irq == 3)
8054 chip_irq += (uchar)2;
8055 return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
8056 }
8057
8058 static uchar __devinit
8059 AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
8060 {
8061 ushort cfg_lsw;
8062
8063 if ((bus_type & ASC_IS_VL) != 0) {
8064 if (irq_no != 0) {
8065 if ((irq_no < ASC_MIN_IRQ_NO)
8066 || (irq_no > ASC_MAX_IRQ_NO)) {
8067 irq_no = 0;
8068 } else {
8069 irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1));
8070 }
8071 }
8072 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3);
8073 cfg_lsw |= (ushort)0x0010;
8074 AscSetChipCfgLsw(iop_base, cfg_lsw);
8075 AscToggleIRQAct(iop_base);
8076 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0);
8077 cfg_lsw |= (ushort)((irq_no & 0x07) << 2);
8078 AscSetChipCfgLsw(iop_base, cfg_lsw);
8079 AscToggleIRQAct(iop_base);
8080 return (AscGetChipIRQ(iop_base, bus_type));
8081 }
8082 if ((bus_type & (ASC_IS_ISA)) != 0) {
8083 if (irq_no == 15)
8084 irq_no -= (uchar)2;
8085 irq_no -= (uchar)ASC_MIN_IRQ_NO;
8086 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3);
8087 cfg_lsw |= (ushort)((irq_no & 0x03) << 2);
8088 AscSetChipCfgLsw(iop_base, cfg_lsw);
8089 return (AscGetChipIRQ(iop_base, bus_type));
8090 }
8091 return (0);
8092 }
8093
8094 #ifdef CONFIG_ISA
8095 static void __devinit AscEnableIsaDma(uchar dma_channel)
8096 {
8097 if (dma_channel < 4) {
8098 outp(0x000B, (ushort)(0xC0 | dma_channel));
8099 outp(0x000A, dma_channel);
8100 } else if (dma_channel < 8) {
8101 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
8102 outp(0x00D4, (ushort)(dma_channel - 4));
8103 }
8104 return;
8105 }
8106 #endif /* CONFIG_ISA */
8107
8108 static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
8109 {
8110 EXT_MSG ext_msg;
8111 EXT_MSG out_msg;
8112 ushort halt_q_addr;
8113 int sdtr_accept;
8114 ushort int_halt_code;
8115 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8116 ASC_SCSI_BIT_ID_TYPE target_id;
8117 PortAddr iop_base;
8118 uchar tag_code;
8119 uchar q_status;
8120 uchar halt_qp;
8121 uchar sdtr_data;
8122 uchar target_ix;
8123 uchar q_cntl, tid_no;
8124 uchar cur_dvc_qng;
8125 uchar asyn_sdtr;
8126 uchar scsi_status;
8127 asc_board_t *boardp;
8128
8129 ASC_ASSERT(asc_dvc->drv_ptr != NULL);
8130 boardp = asc_dvc->drv_ptr;
8131
8132 iop_base = asc_dvc->iop_base;
8133 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
8134
8135 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
8136 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
8137 target_ix = AscReadLramByte(iop_base,
8138 (ushort)(halt_q_addr +
8139 (ushort)ASC_SCSIQ_B_TARGET_IX));
8140 q_cntl =
8141 AscReadLramByte(iop_base,
8142 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8143 tid_no = ASC_TIX_TO_TID(target_ix);
8144 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
8145 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8146 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
8147 } else {
8148 asyn_sdtr = 0;
8149 }
8150 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
8151 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8152 AscSetChipSDTR(iop_base, 0, tid_no);
8153 boardp->sdtr_data[tid_no] = 0;
8154 }
8155 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8156 return (0);
8157 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
8158 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8159 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8160 boardp->sdtr_data[tid_no] = asyn_sdtr;
8161 }
8162 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8163 return (0);
8164 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
8165
8166 AscMemWordCopyPtrFromLram(iop_base,
8167 ASCV_MSGIN_BEG,
8168 (uchar *)&ext_msg,
8169 sizeof(EXT_MSG) >> 1);
8170
8171 if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8172 ext_msg.msg_req == EXTENDED_SDTR &&
8173 ext_msg.msg_len == MS_SDTR_LEN) {
8174 sdtr_accept = TRUE;
8175 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
8176
8177 sdtr_accept = FALSE;
8178 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
8179 }
8180 if ((ext_msg.xfer_period <
8181 asc_dvc->sdtr_period_tbl[asc_dvc->
8182 host_init_sdtr_index])
8183 || (ext_msg.xfer_period >
8184 asc_dvc->sdtr_period_tbl[asc_dvc->
8185 max_sdtr_index])) {
8186 sdtr_accept = FALSE;
8187 ext_msg.xfer_period =
8188 asc_dvc->sdtr_period_tbl[asc_dvc->
8189 host_init_sdtr_index];
8190 }
8191 if (sdtr_accept) {
8192 sdtr_data =
8193 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
8194 ext_msg.req_ack_offset);
8195 if ((sdtr_data == 0xFF)) {
8196
8197 q_cntl |= QC_MSG_OUT;
8198 asc_dvc->init_sdtr &= ~target_id;
8199 asc_dvc->sdtr_done &= ~target_id;
8200 AscSetChipSDTR(iop_base, asyn_sdtr,
8201 tid_no);
8202 boardp->sdtr_data[tid_no] = asyn_sdtr;
8203 }
8204 }
8205 if (ext_msg.req_ack_offset == 0) {
8206
8207 q_cntl &= ~QC_MSG_OUT;
8208 asc_dvc->init_sdtr &= ~target_id;
8209 asc_dvc->sdtr_done &= ~target_id;
8210 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8211 } else {
8212 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
8213
8214 q_cntl &= ~QC_MSG_OUT;
8215 asc_dvc->sdtr_done |= target_id;
8216 asc_dvc->init_sdtr |= target_id;
8217 asc_dvc->pci_fix_asyn_xfer &=
8218 ~target_id;
8219 sdtr_data =
8220 AscCalSDTRData(asc_dvc,
8221 ext_msg.xfer_period,
8222 ext_msg.
8223 req_ack_offset);
8224 AscSetChipSDTR(iop_base, sdtr_data,
8225 tid_no);
8226 boardp->sdtr_data[tid_no] = sdtr_data;
8227 } else {
8228
8229 q_cntl |= QC_MSG_OUT;
8230 AscMsgOutSDTR(asc_dvc,
8231 ext_msg.xfer_period,
8232 ext_msg.req_ack_offset);
8233 asc_dvc->pci_fix_asyn_xfer &=
8234 ~target_id;
8235 sdtr_data =
8236 AscCalSDTRData(asc_dvc,
8237 ext_msg.xfer_period,
8238 ext_msg.
8239 req_ack_offset);
8240 AscSetChipSDTR(iop_base, sdtr_data,
8241 tid_no);
8242 boardp->sdtr_data[tid_no] = sdtr_data;
8243 asc_dvc->sdtr_done |= target_id;
8244 asc_dvc->init_sdtr |= target_id;
8245 }
8246 }
8247
8248 AscWriteLramByte(iop_base,
8249 (ushort)(halt_q_addr +
8250 (ushort)ASC_SCSIQ_B_CNTL),
8251 q_cntl);
8252 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8253 return (0);
8254 } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8255 ext_msg.msg_req == EXTENDED_WDTR &&
8256 ext_msg.msg_len == MS_WDTR_LEN) {
8257
8258 ext_msg.wdtr_width = 0;
8259 AscMemWordCopyPtrToLram(iop_base,
8260 ASCV_MSGOUT_BEG,
8261 (uchar *)&ext_msg,
8262 sizeof(EXT_MSG) >> 1);
8263 q_cntl |= QC_MSG_OUT;
8264 AscWriteLramByte(iop_base,
8265 (ushort)(halt_q_addr +
8266 (ushort)ASC_SCSIQ_B_CNTL),
8267 q_cntl);
8268 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8269 return (0);
8270 } else {
8271
8272 ext_msg.msg_type = MESSAGE_REJECT;
8273 AscMemWordCopyPtrToLram(iop_base,
8274 ASCV_MSGOUT_BEG,
8275 (uchar *)&ext_msg,
8276 sizeof(EXT_MSG) >> 1);
8277 q_cntl |= QC_MSG_OUT;
8278 AscWriteLramByte(iop_base,
8279 (ushort)(halt_q_addr +
8280 (ushort)ASC_SCSIQ_B_CNTL),
8281 q_cntl);
8282 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8283 return (0);
8284 }
8285 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
8286
8287 q_cntl |= QC_REQ_SENSE;
8288
8289 if ((asc_dvc->init_sdtr & target_id) != 0) {
8290
8291 asc_dvc->sdtr_done &= ~target_id;
8292
8293 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8294 q_cntl |= QC_MSG_OUT;
8295 AscMsgOutSDTR(asc_dvc,
8296 asc_dvc->
8297 sdtr_period_tbl[(sdtr_data >> 4) &
8298 (uchar)(asc_dvc->
8299 max_sdtr_index -
8300 1)],
8301 (uchar)(sdtr_data & (uchar)
8302 ASC_SYN_MAX_OFFSET));
8303 }
8304
8305 AscWriteLramByte(iop_base,
8306 (ushort)(halt_q_addr +
8307 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8308
8309 tag_code = AscReadLramByte(iop_base,
8310 (ushort)(halt_q_addr + (ushort)
8311 ASC_SCSIQ_B_TAG_CODE));
8312 tag_code &= 0xDC;
8313 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
8314 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
8315 ) {
8316
8317 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
8318 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
8319
8320 }
8321 AscWriteLramByte(iop_base,
8322 (ushort)(halt_q_addr +
8323 (ushort)ASC_SCSIQ_B_TAG_CODE),
8324 tag_code);
8325
8326 q_status = AscReadLramByte(iop_base,
8327 (ushort)(halt_q_addr + (ushort)
8328 ASC_SCSIQ_B_STATUS));
8329 q_status |= (QS_READY | QS_BUSY);
8330 AscWriteLramByte(iop_base,
8331 (ushort)(halt_q_addr +
8332 (ushort)ASC_SCSIQ_B_STATUS),
8333 q_status);
8334
8335 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
8336 scsi_busy &= ~target_id;
8337 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8338
8339 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8340 return (0);
8341 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
8342
8343 AscMemWordCopyPtrFromLram(iop_base,
8344 ASCV_MSGOUT_BEG,
8345 (uchar *)&out_msg,
8346 sizeof(EXT_MSG) >> 1);
8347
8348 if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
8349 (out_msg.msg_len == MS_SDTR_LEN) &&
8350 (out_msg.msg_req == EXTENDED_SDTR)) {
8351
8352 asc_dvc->init_sdtr &= ~target_id;
8353 asc_dvc->sdtr_done &= ~target_id;
8354 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8355 boardp->sdtr_data[tid_no] = asyn_sdtr;
8356 }
8357 q_cntl &= ~QC_MSG_OUT;
8358 AscWriteLramByte(iop_base,
8359 (ushort)(halt_q_addr +
8360 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8361 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8362 return (0);
8363 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
8364
8365 scsi_status = AscReadLramByte(iop_base,
8366 (ushort)((ushort)halt_q_addr +
8367 (ushort)
8368 ASC_SCSIQ_SCSI_STATUS));
8369 cur_dvc_qng =
8370 AscReadLramByte(iop_base,
8371 (ushort)((ushort)ASC_QADR_BEG +
8372 (ushort)target_ix));
8373 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
8374
8375 scsi_busy = AscReadLramByte(iop_base,
8376 (ushort)ASCV_SCSIBUSY_B);
8377 scsi_busy |= target_id;
8378 AscWriteLramByte(iop_base,
8379 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8380 asc_dvc->queue_full_or_busy |= target_id;
8381
8382 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
8383 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
8384 cur_dvc_qng -= 1;
8385 asc_dvc->max_dvc_qng[tid_no] =
8386 cur_dvc_qng;
8387
8388 AscWriteLramByte(iop_base,
8389 (ushort)((ushort)
8390 ASCV_MAX_DVC_QNG_BEG
8391 + (ushort)
8392 tid_no),
8393 cur_dvc_qng);
8394
8395 /*
8396 * Set the device queue depth to the number of
8397 * active requests when the QUEUE FULL condition
8398 * was encountered.
8399 */
8400 boardp->queue_full |= target_id;
8401 boardp->queue_full_cnt[tid_no] =
8402 cur_dvc_qng;
8403 }
8404 }
8405 }
8406 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8407 return (0);
8408 }
8409 #if CC_VERY_LONG_SG_LIST
8410 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
8411 uchar q_no;
8412 ushort q_addr;
8413 uchar sg_wk_q_no;
8414 uchar first_sg_wk_q_no;
8415 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
8416 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
8417 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
8418 ushort sg_list_dwords;
8419 ushort sg_entry_cnt;
8420 uchar next_qp;
8421 int i;
8422
8423 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
8424 if (q_no == ASC_QLINK_END) {
8425 return (0);
8426 }
8427
8428 q_addr = ASC_QNO_TO_QADDR(q_no);
8429
8430 /*
8431 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
8432 * structure pointer using a macro provided by the driver.
8433 * The ASC_SCSI_REQ pointer provides a pointer to the
8434 * host ASC_SG_HEAD structure.
8435 */
8436 /* Read request's SRB pointer. */
8437 scsiq = (ASC_SCSI_Q *)
8438 ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
8439 (ushort)
8440 (q_addr +
8441 ASC_SCSIQ_D_SRBPTR))));
8442
8443 /*
8444 * Get request's first and working SG queue.
8445 */
8446 sg_wk_q_no = AscReadLramByte(iop_base,
8447 (ushort)(q_addr +
8448 ASC_SCSIQ_B_SG_WK_QP));
8449
8450 first_sg_wk_q_no = AscReadLramByte(iop_base,
8451 (ushort)(q_addr +
8452 ASC_SCSIQ_B_FIRST_SG_WK_QP));
8453
8454 /*
8455 * Reset request's working SG queue back to the
8456 * first SG queue.
8457 */
8458 AscWriteLramByte(iop_base,
8459 (ushort)(q_addr +
8460 (ushort)ASC_SCSIQ_B_SG_WK_QP),
8461 first_sg_wk_q_no);
8462
8463 sg_head = scsiq->sg_head;
8464
8465 /*
8466 * Set sg_entry_cnt to the number of SG elements
8467 * that will be completed on this interrupt.
8468 *
8469 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
8470 * SG elements. The data_cnt and data_addr fields which
8471 * add 1 to the SG element capacity are not used when
8472 * restarting SG handling after a halt.
8473 */
8474 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
8475 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
8476
8477 /*
8478 * Keep track of remaining number of SG elements that will
8479 * need to be handled on the next interrupt.
8480 */
8481 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
8482 } else {
8483 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
8484 scsiq->remain_sg_entry_cnt = 0;
8485 }
8486
8487 /*
8488 * Copy SG elements into the list of allocated SG queues.
8489 *
8490 * Last index completed is saved in scsiq->next_sg_index.
8491 */
8492 next_qp = first_sg_wk_q_no;
8493 q_addr = ASC_QNO_TO_QADDR(next_qp);
8494 scsi_sg_q.sg_head_qp = q_no;
8495 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
8496 for (i = 0; i < sg_head->queue_cnt; i++) {
8497 scsi_sg_q.seq_no = i + 1;
8498 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
8499 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
8500 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
8501 /*
8502 * After very first SG queue RISC FW uses next
8503 * SG queue first element then checks sg_list_cnt
8504 * against zero and then decrements, so set
8505 * sg_list_cnt 1 less than number of SG elements
8506 * in each SG queue.
8507 */
8508 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
8509 scsi_sg_q.sg_cur_list_cnt =
8510 ASC_SG_LIST_PER_Q - 1;
8511 } else {
8512 /*
8513 * This is the last SG queue in the list of
8514 * allocated SG queues. If there are more
8515 * SG elements than will fit in the allocated
8516 * queues, then set the QCSG_SG_XFER_MORE flag.
8517 */
8518 if (scsiq->remain_sg_entry_cnt != 0) {
8519 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
8520 } else {
8521 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
8522 }
8523 /* equals sg_entry_cnt * 2 */
8524 sg_list_dwords = sg_entry_cnt << 1;
8525 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
8526 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
8527 sg_entry_cnt = 0;
8528 }
8529
8530 scsi_sg_q.q_no = next_qp;
8531 AscMemWordCopyPtrToLram(iop_base,
8532 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
8533 (uchar *)&scsi_sg_q,
8534 sizeof(ASC_SG_LIST_Q) >> 1);
8535
8536 AscMemDWordCopyPtrToLram(iop_base,
8537 q_addr + ASC_SGQ_LIST_BEG,
8538 (uchar *)&sg_head->
8539 sg_list[scsiq->next_sg_index],
8540 sg_list_dwords);
8541
8542 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
8543
8544 /*
8545 * If the just completed SG queue contained the
8546 * last SG element, then no more SG queues need
8547 * to be written.
8548 */
8549 if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
8550 break;
8551 }
8552
8553 next_qp = AscReadLramByte(iop_base,
8554 (ushort)(q_addr +
8555 ASC_SCSIQ_B_FWD));
8556 q_addr = ASC_QNO_TO_QADDR(next_qp);
8557 }
8558
8559 /*
8560 * Clear the halt condition so the RISC will be restarted
8561 * after the return.
8562 */
8563 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8564 return (0);
8565 }
8566 #endif /* CC_VERY_LONG_SG_LIST */
8567 return (0);
8568 }
8569
8570 static uchar
8571 _AscCopyLramScsiDoneQ(PortAddr iop_base,
8572 ushort q_addr,
8573 ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
8574 {
8575 ushort _val;
8576 uchar sg_queue_cnt;
8577
8578 DvcGetQinfo(iop_base,
8579 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
8580 (uchar *)scsiq,
8581 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
8582
8583 _val = AscReadLramWord(iop_base,
8584 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
8585 scsiq->q_status = (uchar)_val;
8586 scsiq->q_no = (uchar)(_val >> 8);
8587 _val = AscReadLramWord(iop_base,
8588 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8589 scsiq->cntl = (uchar)_val;
8590 sg_queue_cnt = (uchar)(_val >> 8);
8591 _val = AscReadLramWord(iop_base,
8592 (ushort)(q_addr +
8593 (ushort)ASC_SCSIQ_B_SENSE_LEN));
8594 scsiq->sense_len = (uchar)_val;
8595 scsiq->extra_bytes = (uchar)(_val >> 8);
8596
8597 /*
8598 * Read high word of remain bytes from alternate location.
8599 */
8600 scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
8601 (ushort)(q_addr +
8602 (ushort)
8603 ASC_SCSIQ_W_ALT_DC1)))
8604 << 16);
8605 /*
8606 * Read low word of remain bytes from original location.
8607 */
8608 scsiq->remain_bytes += AscReadLramWord(iop_base,
8609 (ushort)(q_addr + (ushort)
8610 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
8611
8612 scsiq->remain_bytes &= max_dma_count;
8613 return (sg_queue_cnt);
8614 }
8615
8616 static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
8617 {
8618 uchar next_qp;
8619 uchar n_q_used;
8620 uchar sg_list_qp;
8621 uchar sg_queue_cnt;
8622 uchar q_cnt;
8623 uchar done_q_tail;
8624 uchar tid_no;
8625 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8626 ASC_SCSI_BIT_ID_TYPE target_id;
8627 PortAddr iop_base;
8628 ushort q_addr;
8629 ushort sg_q_addr;
8630 uchar cur_target_qng;
8631 ASC_QDONE_INFO scsiq_buf;
8632 ASC_QDONE_INFO *scsiq;
8633 int false_overrun;
8634 ASC_ISR_CALLBACK asc_isr_callback;
8635
8636 iop_base = asc_dvc->iop_base;
8637 asc_isr_callback = asc_dvc->isr_callback;
8638 n_q_used = 1;
8639 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
8640 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
8641 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
8642 next_qp = AscReadLramByte(iop_base,
8643 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
8644 if (next_qp != ASC_QLINK_END) {
8645 AscPutVarDoneQTail(iop_base, next_qp);
8646 q_addr = ASC_QNO_TO_QADDR(next_qp);
8647 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
8648 asc_dvc->max_dma_count);
8649 AscWriteLramByte(iop_base,
8650 (ushort)(q_addr +
8651 (ushort)ASC_SCSIQ_B_STATUS),
8652 (uchar)(scsiq->
8653 q_status & (uchar)~(QS_READY |
8654 QS_ABORTED)));
8655 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
8656 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
8657 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
8658 sg_q_addr = q_addr;
8659 sg_list_qp = next_qp;
8660 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
8661 sg_list_qp = AscReadLramByte(iop_base,
8662 (ushort)(sg_q_addr
8663 + (ushort)
8664 ASC_SCSIQ_B_FWD));
8665 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
8666 if (sg_list_qp == ASC_QLINK_END) {
8667 AscSetLibErrorCode(asc_dvc,
8668 ASCQ_ERR_SG_Q_LINKS);
8669 scsiq->d3.done_stat = QD_WITH_ERROR;
8670 scsiq->d3.host_stat =
8671 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
8672 goto FATAL_ERR_QDONE;
8673 }
8674 AscWriteLramByte(iop_base,
8675 (ushort)(sg_q_addr + (ushort)
8676 ASC_SCSIQ_B_STATUS),
8677 QS_FREE);
8678 }
8679 n_q_used = sg_queue_cnt + 1;
8680 AscPutVarDoneQTail(iop_base, sg_list_qp);
8681 }
8682 if (asc_dvc->queue_full_or_busy & target_id) {
8683 cur_target_qng = AscReadLramByte(iop_base,
8684 (ushort)((ushort)
8685 ASC_QADR_BEG
8686 + (ushort)
8687 scsiq->d2.
8688 target_ix));
8689 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
8690 scsi_busy = AscReadLramByte(iop_base, (ushort)
8691 ASCV_SCSIBUSY_B);
8692 scsi_busy &= ~target_id;
8693 AscWriteLramByte(iop_base,
8694 (ushort)ASCV_SCSIBUSY_B,
8695 scsi_busy);
8696 asc_dvc->queue_full_or_busy &= ~target_id;
8697 }
8698 }
8699 if (asc_dvc->cur_total_qng >= n_q_used) {
8700 asc_dvc->cur_total_qng -= n_q_used;
8701 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
8702 asc_dvc->cur_dvc_qng[tid_no]--;
8703 }
8704 } else {
8705 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
8706 scsiq->d3.done_stat = QD_WITH_ERROR;
8707 goto FATAL_ERR_QDONE;
8708 }
8709 if ((scsiq->d2.srb_ptr == 0UL) ||
8710 ((scsiq->q_status & QS_ABORTED) != 0)) {
8711 return (0x11);
8712 } else if (scsiq->q_status == QS_DONE) {
8713 false_overrun = FALSE;
8714 if (scsiq->extra_bytes != 0) {
8715 scsiq->remain_bytes +=
8716 (ADV_DCNT)scsiq->extra_bytes;
8717 }
8718 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
8719 if (scsiq->d3.host_stat ==
8720 QHSTA_M_DATA_OVER_RUN) {
8721 if ((scsiq->
8722 cntl & (QC_DATA_IN | QC_DATA_OUT))
8723 == 0) {
8724 scsiq->d3.done_stat =
8725 QD_NO_ERROR;
8726 scsiq->d3.host_stat =
8727 QHSTA_NO_ERROR;
8728 } else if (false_overrun) {
8729 scsiq->d3.done_stat =
8730 QD_NO_ERROR;
8731 scsiq->d3.host_stat =
8732 QHSTA_NO_ERROR;
8733 }
8734 } else if (scsiq->d3.host_stat ==
8735 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
8736 AscStopChip(iop_base);
8737 AscSetChipControl(iop_base,
8738 (uchar)(CC_SCSI_RESET
8739 | CC_HALT));
8740 DvcDelayNanoSecond(asc_dvc, 60000);
8741 AscSetChipControl(iop_base, CC_HALT);
8742 AscSetChipStatus(iop_base,
8743 CIW_CLR_SCSI_RESET_INT);
8744 AscSetChipStatus(iop_base, 0);
8745 AscSetChipControl(iop_base, 0);
8746 }
8747 }
8748 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
8749 (*asc_isr_callback) (asc_dvc, scsiq);
8750 } else {
8751 if ((AscReadLramByte(iop_base,
8752 (ushort)(q_addr + (ushort)
8753 ASC_SCSIQ_CDB_BEG))
8754 == START_STOP)) {
8755 asc_dvc->unit_not_ready &= ~target_id;
8756 if (scsiq->d3.done_stat != QD_NO_ERROR) {
8757 asc_dvc->start_motor &=
8758 ~target_id;
8759 }
8760 }
8761 }
8762 return (1);
8763 } else {
8764 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
8765 FATAL_ERR_QDONE:
8766 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
8767 (*asc_isr_callback) (asc_dvc, scsiq);
8768 }
8769 return (0x80);
8770 }
8771 }
8772 return (0);
8773 }
8774
8775 static int AscISR(ASC_DVC_VAR *asc_dvc)
8776 {
8777 ASC_CS_TYPE chipstat;
8778 PortAddr iop_base;
8779 ushort saved_ram_addr;
8780 uchar ctrl_reg;
8781 uchar saved_ctrl_reg;
8782 int int_pending;
8783 int status;
8784 uchar host_flag;
8785
8786 iop_base = asc_dvc->iop_base;
8787 int_pending = FALSE;
8788
8789 if (AscIsIntPending(iop_base) == 0) {
8790 return int_pending;
8791 }
8792
8793 if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
8794 || (asc_dvc->isr_callback == 0)
8795 ) {
8796 return (ERR);
8797 }
8798 if (asc_dvc->in_critical_cnt != 0) {
8799 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
8800 return (ERR);
8801 }
8802 if (asc_dvc->is_in_int) {
8803 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
8804 return (ERR);
8805 }
8806 asc_dvc->is_in_int = TRUE;
8807 ctrl_reg = AscGetChipControl(iop_base);
8808 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
8809 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
8810 chipstat = AscGetChipStatus(iop_base);
8811 if (chipstat & CSW_SCSI_RESET_LATCH) {
8812 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
8813 int i = 10;
8814 int_pending = TRUE;
8815 asc_dvc->sdtr_done = 0;
8816 saved_ctrl_reg &= (uchar)(~CC_HALT);
8817 while ((AscGetChipStatus(iop_base) &
8818 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
8819 DvcSleepMilliSecond(100);
8820 }
8821 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
8822 AscSetChipControl(iop_base, CC_HALT);
8823 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
8824 AscSetChipStatus(iop_base, 0);
8825 chipstat = AscGetChipStatus(iop_base);
8826 }
8827 }
8828 saved_ram_addr = AscGetChipLramAddr(iop_base);
8829 host_flag = AscReadLramByte(iop_base,
8830 ASCV_HOST_FLAG_B) &
8831 (uchar)(~ASC_HOST_FLAG_IN_ISR);
8832 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
8833 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
8834 if ((chipstat & CSW_INT_PENDING)
8835 || (int_pending)
8836 ) {
8837 AscAckInterrupt(iop_base);
8838 int_pending = TRUE;
8839 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
8840 if (AscIsrChipHalted(asc_dvc) == ERR) {
8841 goto ISR_REPORT_QDONE_FATAL_ERROR;
8842 } else {
8843 saved_ctrl_reg &= (uchar)(~CC_HALT);
8844 }
8845 } else {
8846 ISR_REPORT_QDONE_FATAL_ERROR:
8847 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
8848 while (((status =
8849 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
8850 }
8851 } else {
8852 do {
8853 if ((status =
8854 AscIsrQDone(asc_dvc)) == 1) {
8855 break;
8856 }
8857 } while (status == 0x11);
8858 }
8859 if ((status & 0x80) != 0)
8860 int_pending = ERR;
8861 }
8862 }
8863 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
8864 AscSetChipLramAddr(iop_base, saved_ram_addr);
8865 AscSetChipControl(iop_base, saved_ctrl_reg);
8866 asc_dvc->is_in_int = FALSE;
8867 return (int_pending);
8868 }
8869
8870 /* Microcode buffer is kept after initialization for error recovery. */
8871 static uchar _asc_mcode_buf[] = {
8872 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8873 0x00, 0x00, 0x00, 0x00,
8874 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00,
8875 0x00, 0x00, 0x00, 0x00,
8876 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8877 0x00, 0x00, 0x00, 0x00,
8878 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8879 0x00, 0x00, 0x00, 0x00,
8880 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00,
8881 0x00, 0xFF, 0x00, 0x00,
8882 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00,
8883 0x00, 0x00, 0x00, 0x00,
8884 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
8885 0x00, 0x00, 0x00, 0x00,
8886 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88,
8887 0x00, 0x00, 0x00, 0x00,
8888 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73,
8889 0x03, 0x23, 0x36, 0x40,
8890 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
8891 0xC2, 0x00, 0x92, 0x80,
8892 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60,
8893 0xB6, 0x00, 0x92, 0x80,
8894 0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00,
8895 0x92, 0x80, 0x80, 0x62,
8896 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
8897 0xCD, 0x04, 0x4D, 0x00,
8898 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01,
8899 0xE6, 0x84, 0xD2, 0xC1,
8900 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97,
8901 0xC6, 0x81, 0xC2, 0x88,
8902 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
8903 0x84, 0x97, 0x07, 0xA6,
8904 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE,
8905 0xC2, 0x88, 0xCE, 0x00,
8906 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01,
8907 0x80, 0x63, 0x07, 0xA6,
8908 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
8909 0x34, 0x01, 0x00, 0x33,
8910 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23,
8911 0x68, 0x98, 0x4D, 0x04,
8912 0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23,
8913 0xF8, 0x88, 0xFB, 0x23,
8914 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
8915 0x00, 0x33, 0x0A, 0x00,
8916 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00,
8917 0xC2, 0x88, 0xCD, 0x04,
8918 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81,
8919 0x06, 0xAB, 0x82, 0x01,
8920 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
8921 0x3C, 0x01, 0x00, 0x05,
8922 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01,
8923 0x15, 0x23, 0xA1, 0x01,
8924 0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00,
8925 0x06, 0x61, 0x00, 0xA0,
8926 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
8927 0xC2, 0x88, 0x06, 0x23,
8928 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01,
8929 0x57, 0x60, 0x00, 0xA0,
8930 0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73,
8931 0x4B, 0x00, 0x06, 0x61,
8932 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
8933 0x4F, 0x00, 0x84, 0x97,
8934 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97,
8935 0x48, 0x04, 0x84, 0x80,
8936 0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00,
8937 0x81, 0x73, 0x06, 0x29,
8938 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
8939 0x04, 0x98, 0xF0, 0x80,
8940 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6,
8941 0x34, 0x02, 0x03, 0xA6,
8942 0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96,
8943 0x46, 0x82, 0xFE, 0x95,
8944 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
8945 0x07, 0xA6, 0x5A, 0x02,
8946 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95,
8947 0x48, 0x82, 0x60, 0x96,
8948 0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84,
8949 0x04, 0x01, 0x0C, 0xDC,
8950 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
8951 0x6F, 0x00, 0xA5, 0x01,
8952 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01,
8953 0x02, 0xA6, 0xAA, 0x02,
8954 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04,
8955 0x01, 0xA6, 0xB4, 0x02,
8956 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
8957 0x80, 0x63, 0x00, 0x43,
8958 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23,
8959 0x04, 0x61, 0x84, 0x01,
8960 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F,
8961 0x00, 0x00, 0xEA, 0x82,
8962 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
8963 0x00, 0x33, 0x1F, 0x00,
8964 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98,
8965 0xB6, 0x2D, 0x01, 0xA6,
8966 0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6,
8967 0x10, 0x03, 0x03, 0xA6,
8968 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
8969 0x7C, 0x95, 0xEE, 0x82,
8970 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4,
8971 0x04, 0x01, 0x2D, 0xC8,
8972 0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01,
8973 0x05, 0x05, 0x86, 0x98,
8974 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
8975 0x3C, 0x04, 0x06, 0xA6,
8976 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88,
8977 0x7C, 0x95, 0x32, 0x83,
8978 0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05,
8979 0xEB, 0x04, 0x00, 0x33,
8980 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
8981 0xFF, 0xA2, 0x7A, 0x03,
8982 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01,
8983 0x00, 0xA2, 0x9A, 0x03,
8984 0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00,
8985 0x01, 0xA6, 0x96, 0x03,
8986 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
8987 0xA4, 0x03, 0x00, 0xA6,
8988 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03,
8989 0x07, 0xA6, 0xB2, 0x03,
8990 0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88,
8991 0xA8, 0x98, 0x80, 0x42,
8992 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
8993 0xC0, 0x83, 0x00, 0x33,
8994 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23,
8995 0xA0, 0x01, 0x12, 0x23,
8996 0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B,
8997 0x80, 0x67, 0x05, 0x23,
8998 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
8999 0x06, 0xA6, 0x0A, 0x04,
9000 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96,
9001 0xF4, 0x83, 0x20, 0x84,
9002 0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
9003 0x83, 0x03, 0x80, 0x63,
9004 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
9005 0x38, 0x04, 0x00, 0x33,
9006 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84,
9007 0x1D, 0x01, 0x06, 0xCC,
9008 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62,
9009 0xA2, 0x0D, 0x80, 0x63,
9010 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
9011 0x80, 0x63, 0xA3, 0x01,
9012 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0,
9013 0x76, 0x04, 0xE0, 0x00,
9014 0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00,
9015 0x00, 0x33, 0x1E, 0x00,
9016 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
9017 0x08, 0x23, 0x22, 0xA3,
9018 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3,
9019 0xC4, 0x04, 0x42, 0x23,
9020 0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23,
9021 0xF8, 0x88, 0x04, 0x98,
9022 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
9023 0x81, 0x62, 0xE8, 0x81,
9024 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98,
9025 0x00, 0x33, 0x00, 0x81,
9026 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23,
9027 0xF8, 0x88, 0x04, 0x23,
9028 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
9029 0xF4, 0x04, 0x00, 0x33,
9030 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01,
9031 0x04, 0x23, 0xA0, 0x01,
9032 0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00,
9033 0x00, 0xA3, 0x22, 0x05,
9034 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
9035 0x46, 0x97, 0xCD, 0x04,
9036 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23,
9037 0x82, 0x01, 0x34, 0x85,
9038 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05,
9039 0x1D, 0x01, 0x04, 0xD6,
9040 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
9041 0x49, 0x00, 0x81, 0x01,
9042 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01,
9043 0x49, 0x04, 0x80, 0x01,
9044 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04,
9045 0x01, 0x23, 0xEA, 0x00,
9046 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
9047 0x07, 0xA4, 0xF8, 0x05,
9048 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00,
9049 0xC2, 0x88, 0x04, 0xA0,
9050 0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61,
9051 0x00, 0xA2, 0xA4, 0x05,
9052 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
9053 0x62, 0x97, 0x04, 0x85,
9054 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05,
9055 0xF4, 0x85, 0x03, 0xA0,
9056 0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63,
9057 0xCC, 0x86, 0x07, 0xA0,
9058 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
9059 0x80, 0x67, 0x80, 0x63,
9060 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23,
9061 0xF8, 0x88, 0x07, 0x23,
9062 0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00,
9063 0x00, 0x63, 0x4A, 0x00,
9064 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
9065 0x07, 0x41, 0x83, 0x03,
9066 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88,
9067 0x1D, 0x01, 0x01, 0xD6,
9068 0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00,
9069 0x07, 0xA6, 0x7C, 0x05,
9070 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
9071 0x52, 0x00, 0x06, 0x61,
9072 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41,
9073 0x00, 0x63, 0x1D, 0x01,
9074 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23,
9075 0x07, 0x41, 0x00, 0x63,
9076 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
9077 0xDF, 0x00, 0x06, 0xA6,
9078 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33,
9079 0x00, 0x40, 0xC0, 0x20,
9080 0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63,
9081 0x06, 0xA6, 0x94, 0x06,
9082 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
9083 0x40, 0x0E, 0x80, 0x63,
9084 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E,
9085 0x80, 0x63, 0x00, 0x43,
9086 0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05,
9087 0x80, 0x67, 0x40, 0x0E,
9088 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
9089 0x07, 0xA6, 0xD6, 0x06,
9090 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00,
9091 0x0A, 0x2B, 0x07, 0xA6,
9092 0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2,
9093 0xF4, 0x06, 0xC0, 0x0E,
9094 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
9095 0x81, 0x62, 0x04, 0x01,
9096 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6,
9097 0x8C, 0x06, 0x00, 0x33,
9098 0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03,
9099 0x80, 0x63, 0x06, 0xA6,
9100 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
9101 0x00, 0x00, 0x80, 0x67,
9102 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05,
9103 0xBF, 0x23, 0x04, 0x61,
9104 0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00,
9105 0x00, 0x01, 0xF2, 0x00,
9106 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
9107 0x80, 0x05, 0x81, 0x05,
9108 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00,
9109 0x70, 0x00, 0x81, 0x01,
9110 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04,
9111 0x70, 0x00, 0x80, 0x01,
9112 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
9113 0xF1, 0x00, 0x70, 0x00,
9114 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01,
9115 0x71, 0x04, 0x70, 0x00,
9116 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05,
9117 0xA3, 0x01, 0xA2, 0x01,
9118 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
9119 0xC4, 0x07, 0x00, 0x33,
9120 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8,
9121 0x48, 0x00, 0xB0, 0x01,
9122 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43,
9123 0x00, 0xA2, 0xE4, 0x07,
9124 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
9125 0x05, 0x05, 0x00, 0x63,
9126 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43,
9127 0x76, 0x08, 0x80, 0x02,
9128 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
9129 0x00, 0x02, 0x00, 0xA0,
9130 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
9131 0x00, 0x63, 0xF3, 0x04,
9132 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40,
9133 0x00, 0xA2, 0x44, 0x08,
9134 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1,
9135 0x24, 0x08, 0x04, 0x98,
9136 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
9137 0x5A, 0x88, 0x02, 0x01,
9138 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00,
9139 0x00, 0xA3, 0x64, 0x08,
9140 0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63,
9141 0x06, 0xA6, 0x76, 0x08,
9142 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
9143 0x00, 0x63, 0x38, 0x2B,
9144 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98,
9145 0x05, 0x05, 0xB2, 0x09,
9146 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63,
9147 0x80, 0x32, 0x80, 0x36,
9148 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
9149 0x40, 0x36, 0x40, 0x3A,
9150 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08,
9151 0x5D, 0x00, 0xFE, 0xC3,
9152 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73,
9153 0xFF, 0xFD, 0x80, 0x73,
9154 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
9155 0xA1, 0x23, 0xA1, 0x01,
9156 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2,
9157 0x80, 0x00, 0x03, 0xC2,
9158 0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23,
9159 0xA0, 0x01, 0xE6, 0x84,
9160 };
9161
9162 static ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
9163 static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
9164
9165 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
9166 static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
9167 INQUIRY,
9168 REQUEST_SENSE,
9169 READ_CAPACITY,
9170 READ_TOC,
9171 MODE_SELECT,
9172 MODE_SENSE,
9173 MODE_SELECT_10,
9174 MODE_SENSE_10,
9175 0xFF,
9176 0xFF,
9177 0xFF,
9178 0xFF,
9179 0xFF,
9180 0xFF,
9181 0xFF,
9182 0xFF
9183 };
9184
9185 static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
9186 {
9187 PortAddr iop_base;
9188 ulong last_int_level;
9189 int sta;
9190 int n_q_required;
9191 int disable_syn_offset_one_fix;
9192 int i;
9193 ASC_PADDR addr;
9194 ASC_EXE_CALLBACK asc_exe_callback;
9195 ushort sg_entry_cnt = 0;
9196 ushort sg_entry_cnt_minus_one = 0;
9197 uchar target_ix;
9198 uchar tid_no;
9199 uchar sdtr_data;
9200 uchar extra_bytes;
9201 uchar scsi_cmd;
9202 uchar disable_cmd;
9203 ASC_SG_HEAD *sg_head;
9204 ASC_DCNT data_cnt;
9205
9206 iop_base = asc_dvc->iop_base;
9207 sg_head = scsiq->sg_head;
9208 asc_exe_callback = asc_dvc->exe_callback;
9209 if (asc_dvc->err_code != 0)
9210 return (ERR);
9211 if (scsiq == (ASC_SCSI_Q *)0L) {
9212 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
9213 return (ERR);
9214 }
9215 scsiq->q1.q_no = 0;
9216 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
9217 scsiq->q1.extra_bytes = 0;
9218 }
9219 sta = 0;
9220 target_ix = scsiq->q2.target_ix;
9221 tid_no = ASC_TIX_TO_TID(target_ix);
9222 n_q_required = 1;
9223 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
9224 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
9225 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
9226 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9227 AscMsgOutSDTR(asc_dvc,
9228 asc_dvc->
9229 sdtr_period_tbl[(sdtr_data >> 4) &
9230 (uchar)(asc_dvc->
9231 max_sdtr_index -
9232 1)],
9233 (uchar)(sdtr_data & (uchar)
9234 ASC_SYN_MAX_OFFSET));
9235 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
9236 }
9237 }
9238 last_int_level = DvcEnterCritical();
9239 if (asc_dvc->in_critical_cnt != 0) {
9240 DvcLeaveCritical(last_int_level);
9241 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
9242 return (ERR);
9243 }
9244 asc_dvc->in_critical_cnt++;
9245 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9246 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
9247 asc_dvc->in_critical_cnt--;
9248 DvcLeaveCritical(last_int_level);
9249 return (ERR);
9250 }
9251 #if !CC_VERY_LONG_SG_LIST
9252 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9253 asc_dvc->in_critical_cnt--;
9254 DvcLeaveCritical(last_int_level);
9255 return (ERR);
9256 }
9257 #endif /* !CC_VERY_LONG_SG_LIST */
9258 if (sg_entry_cnt == 1) {
9259 scsiq->q1.data_addr =
9260 (ADV_PADDR)sg_head->sg_list[0].addr;
9261 scsiq->q1.data_cnt =
9262 (ADV_DCNT)sg_head->sg_list[0].bytes;
9263 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
9264 }
9265 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
9266 }
9267 scsi_cmd = scsiq->cdbptr[0];
9268 disable_syn_offset_one_fix = FALSE;
9269 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
9270 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
9271 if (scsiq->q1.cntl & QC_SG_HEAD) {
9272 data_cnt = 0;
9273 for (i = 0; i < sg_entry_cnt; i++) {
9274 data_cnt +=
9275 (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
9276 bytes);
9277 }
9278 } else {
9279 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
9280 }
9281 if (data_cnt != 0UL) {
9282 if (data_cnt < 512UL) {
9283 disable_syn_offset_one_fix = TRUE;
9284 } else {
9285 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
9286 i++) {
9287 disable_cmd =
9288 _syn_offset_one_disable_cmd[i];
9289 if (disable_cmd == 0xFF) {
9290 break;
9291 }
9292 if (scsi_cmd == disable_cmd) {
9293 disable_syn_offset_one_fix =
9294 TRUE;
9295 break;
9296 }
9297 }
9298 }
9299 }
9300 }
9301 if (disable_syn_offset_one_fix) {
9302 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9303 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
9304 ASC_TAG_FLAG_DISABLE_DISCONNECT);
9305 } else {
9306 scsiq->q2.tag_code &= 0x27;
9307 }
9308 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9309 if (asc_dvc->bug_fix_cntl) {
9310 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9311 if ((scsi_cmd == READ_6) ||
9312 (scsi_cmd == READ_10)) {
9313 addr =
9314 (ADV_PADDR)le32_to_cpu(sg_head->
9315 sg_list
9316 [sg_entry_cnt_minus_one].
9317 addr) +
9318 (ADV_DCNT)le32_to_cpu(sg_head->
9319 sg_list
9320 [sg_entry_cnt_minus_one].
9321 bytes);
9322 extra_bytes =
9323 (uchar)((ushort)addr & 0x0003);
9324 if ((extra_bytes != 0)
9325 &&
9326 ((scsiq->q2.
9327 tag_code &
9328 ASC_TAG_FLAG_EXTRA_BYTES)
9329 == 0)) {
9330 scsiq->q2.tag_code |=
9331 ASC_TAG_FLAG_EXTRA_BYTES;
9332 scsiq->q1.extra_bytes =
9333 extra_bytes;
9334 data_cnt =
9335 le32_to_cpu(sg_head->
9336 sg_list
9337 [sg_entry_cnt_minus_one].
9338 bytes);
9339 data_cnt -=
9340 (ASC_DCNT) extra_bytes;
9341 sg_head->
9342 sg_list
9343 [sg_entry_cnt_minus_one].
9344 bytes =
9345 cpu_to_le32(data_cnt);
9346 }
9347 }
9348 }
9349 }
9350 sg_head->entry_to_copy = sg_head->entry_cnt;
9351 #if CC_VERY_LONG_SG_LIST
9352 /*
9353 * Set the sg_entry_cnt to the maximum possible. The rest of
9354 * the SG elements will be copied when the RISC completes the
9355 * SG elements that fit and halts.
9356 */
9357 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9358 sg_entry_cnt = ASC_MAX_SG_LIST;
9359 }
9360 #endif /* CC_VERY_LONG_SG_LIST */
9361 n_q_required = AscSgListToQueue(sg_entry_cnt);
9362 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
9363 (uint) n_q_required)
9364 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9365 if ((sta =
9366 AscSendScsiQueue(asc_dvc, scsiq,
9367 n_q_required)) == 1) {
9368 asc_dvc->in_critical_cnt--;
9369 if (asc_exe_callback != 0) {
9370 (*asc_exe_callback) (asc_dvc, scsiq);
9371 }
9372 DvcLeaveCritical(last_int_level);
9373 return (sta);
9374 }
9375 }
9376 } else {
9377 if (asc_dvc->bug_fix_cntl) {
9378 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9379 if ((scsi_cmd == READ_6) ||
9380 (scsi_cmd == READ_10)) {
9381 addr =
9382 le32_to_cpu(scsiq->q1.data_addr) +
9383 le32_to_cpu(scsiq->q1.data_cnt);
9384 extra_bytes =
9385 (uchar)((ushort)addr & 0x0003);
9386 if ((extra_bytes != 0)
9387 &&
9388 ((scsiq->q2.
9389 tag_code &
9390 ASC_TAG_FLAG_EXTRA_BYTES)
9391 == 0)) {
9392 data_cnt =
9393 le32_to_cpu(scsiq->q1.
9394 data_cnt);
9395 if (((ushort)data_cnt & 0x01FF)
9396 == 0) {
9397 scsiq->q2.tag_code |=
9398 ASC_TAG_FLAG_EXTRA_BYTES;
9399 data_cnt -= (ASC_DCNT)
9400 extra_bytes;
9401 scsiq->q1.data_cnt =
9402 cpu_to_le32
9403 (data_cnt);
9404 scsiq->q1.extra_bytes =
9405 extra_bytes;
9406 }
9407 }
9408 }
9409 }
9410 }
9411 n_q_required = 1;
9412 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
9413 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9414 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
9415 n_q_required)) == 1) {
9416 asc_dvc->in_critical_cnt--;
9417 if (asc_exe_callback != 0) {
9418 (*asc_exe_callback) (asc_dvc, scsiq);
9419 }
9420 DvcLeaveCritical(last_int_level);
9421 return (sta);
9422 }
9423 }
9424 }
9425 asc_dvc->in_critical_cnt--;
9426 DvcLeaveCritical(last_int_level);
9427 return (sta);
9428 }
9429
9430 static int
9431 AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
9432 {
9433 PortAddr iop_base;
9434 uchar free_q_head;
9435 uchar next_qp;
9436 uchar tid_no;
9437 uchar target_ix;
9438 int sta;
9439
9440 iop_base = asc_dvc->iop_base;
9441 target_ix = scsiq->q2.target_ix;
9442 tid_no = ASC_TIX_TO_TID(target_ix);
9443 sta = 0;
9444 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
9445 if (n_q_required > 1) {
9446 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
9447 free_q_head, (uchar)
9448 (n_q_required)))
9449 != (uchar)ASC_QLINK_END) {
9450 asc_dvc->last_q_shortage = 0;
9451 scsiq->sg_head->queue_cnt = n_q_required - 1;
9452 scsiq->q1.q_no = free_q_head;
9453 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
9454 free_q_head)) == 1) {
9455 AscPutVarFreeQHead(iop_base, next_qp);
9456 asc_dvc->cur_total_qng += (uchar)(n_q_required);
9457 asc_dvc->cur_dvc_qng[tid_no]++;
9458 }
9459 return (sta);
9460 }
9461 } else if (n_q_required == 1) {
9462 if ((next_qp = AscAllocFreeQueue(iop_base,
9463 free_q_head)) !=
9464 ASC_QLINK_END) {
9465 scsiq->q1.q_no = free_q_head;
9466 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
9467 free_q_head)) == 1) {
9468 AscPutVarFreeQHead(iop_base, next_qp);
9469 asc_dvc->cur_total_qng++;
9470 asc_dvc->cur_dvc_qng[tid_no]++;
9471 }
9472 return (sta);
9473 }
9474 }
9475 return (sta);
9476 }
9477
9478 static int AscSgListToQueue(int sg_list)
9479 {
9480 int n_sg_list_qs;
9481
9482 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
9483 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
9484 n_sg_list_qs++;
9485 return (n_sg_list_qs + 1);
9486 }
9487
9488 static uint
9489 AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
9490 {
9491 uint cur_used_qs;
9492 uint cur_free_qs;
9493 ASC_SCSI_BIT_ID_TYPE target_id;
9494 uchar tid_no;
9495
9496 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
9497 tid_no = ASC_TIX_TO_TID(target_ix);
9498 if ((asc_dvc->unit_not_ready & target_id) ||
9499 (asc_dvc->queue_full_or_busy & target_id)) {
9500 return (0);
9501 }
9502 if (n_qs == 1) {
9503 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9504 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
9505 } else {
9506 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9507 (uint) ASC_MIN_FREE_Q;
9508 }
9509 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
9510 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
9511 if (asc_dvc->cur_dvc_qng[tid_no] >=
9512 asc_dvc->max_dvc_qng[tid_no]) {
9513 return (0);
9514 }
9515 return (cur_free_qs);
9516 }
9517 if (n_qs > 1) {
9518 if ((n_qs > asc_dvc->last_q_shortage)
9519 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
9520 asc_dvc->last_q_shortage = n_qs;
9521 }
9522 }
9523 return (0);
9524 }
9525
9526 static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
9527 {
9528 ushort q_addr;
9529 uchar tid_no;
9530 uchar sdtr_data;
9531 uchar syn_period_ix;
9532 uchar syn_offset;
9533 PortAddr iop_base;
9534
9535 iop_base = asc_dvc->iop_base;
9536 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
9537 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
9538 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
9539 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9540 syn_period_ix =
9541 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
9542 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
9543 AscMsgOutSDTR(asc_dvc,
9544 asc_dvc->sdtr_period_tbl[syn_period_ix],
9545 syn_offset);
9546 scsiq->q1.cntl |= QC_MSG_OUT;
9547 }
9548 q_addr = ASC_QNO_TO_QADDR(q_no);
9549 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
9550 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9551 }
9552 scsiq->q1.status = QS_FREE;
9553 AscMemWordCopyPtrToLram(iop_base,
9554 q_addr + ASC_SCSIQ_CDB_BEG,
9555 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
9556
9557 DvcPutScsiQ(iop_base,
9558 q_addr + ASC_SCSIQ_CPY_BEG,
9559 (uchar *)&scsiq->q1.cntl,
9560 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
9561 AscWriteLramWord(iop_base,
9562 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
9563 (ushort)(((ushort)scsiq->q1.
9564 q_no << 8) | (ushort)QS_READY));
9565 return (1);
9566 }
9567
9568 static int
9569 AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
9570 {
9571 int sta;
9572 int i;
9573 ASC_SG_HEAD *sg_head;
9574 ASC_SG_LIST_Q scsi_sg_q;
9575 ASC_DCNT saved_data_addr;
9576 ASC_DCNT saved_data_cnt;
9577 PortAddr iop_base;
9578 ushort sg_list_dwords;
9579 ushort sg_index;
9580 ushort sg_entry_cnt;
9581 ushort q_addr;
9582 uchar next_qp;
9583
9584 iop_base = asc_dvc->iop_base;
9585 sg_head = scsiq->sg_head;
9586 saved_data_addr = scsiq->q1.data_addr;
9587 saved_data_cnt = scsiq->q1.data_cnt;
9588 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
9589 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
9590 #if CC_VERY_LONG_SG_LIST
9591 /*
9592 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
9593 * then not all SG elements will fit in the allocated queues.
9594 * The rest of the SG elements will be copied when the RISC
9595 * completes the SG elements that fit and halts.
9596 */
9597 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9598 /*
9599 * Set sg_entry_cnt to be the number of SG elements that
9600 * will fit in the allocated SG queues. It is minus 1, because
9601 * the first SG element is handled above. ASC_MAX_SG_LIST is
9602 * already inflated by 1 to account for this. For example it
9603 * may be 50 which is 1 + 7 queues * 7 SG elements.
9604 */
9605 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
9606
9607 /*
9608 * Keep track of remaining number of SG elements that will
9609 * need to be handled from a_isr.c.
9610 */
9611 scsiq->remain_sg_entry_cnt =
9612 sg_head->entry_cnt - ASC_MAX_SG_LIST;
9613 } else {
9614 #endif /* CC_VERY_LONG_SG_LIST */
9615 /*
9616 * Set sg_entry_cnt to be the number of SG elements that
9617 * will fit in the allocated SG queues. It is minus 1, because
9618 * the first SG element is handled above.
9619 */
9620 sg_entry_cnt = sg_head->entry_cnt - 1;
9621 #if CC_VERY_LONG_SG_LIST
9622 }
9623 #endif /* CC_VERY_LONG_SG_LIST */
9624 if (sg_entry_cnt != 0) {
9625 scsiq->q1.cntl |= QC_SG_HEAD;
9626 q_addr = ASC_QNO_TO_QADDR(q_no);
9627 sg_index = 1;
9628 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
9629 scsi_sg_q.sg_head_qp = q_no;
9630 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
9631 for (i = 0; i < sg_head->queue_cnt; i++) {
9632 scsi_sg_q.seq_no = i + 1;
9633 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
9634 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
9635 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
9636 if (i == 0) {
9637 scsi_sg_q.sg_list_cnt =
9638 ASC_SG_LIST_PER_Q;
9639 scsi_sg_q.sg_cur_list_cnt =
9640 ASC_SG_LIST_PER_Q;
9641 } else {
9642 scsi_sg_q.sg_list_cnt =
9643 ASC_SG_LIST_PER_Q - 1;
9644 scsi_sg_q.sg_cur_list_cnt =
9645 ASC_SG_LIST_PER_Q - 1;
9646 }
9647 } else {
9648 #if CC_VERY_LONG_SG_LIST
9649 /*
9650 * This is the last SG queue in the list of
9651 * allocated SG queues. If there are more
9652 * SG elements than will fit in the allocated
9653 * queues, then set the QCSG_SG_XFER_MORE flag.
9654 */
9655 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9656 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
9657 } else {
9658 #endif /* CC_VERY_LONG_SG_LIST */
9659 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
9660 #if CC_VERY_LONG_SG_LIST
9661 }
9662 #endif /* CC_VERY_LONG_SG_LIST */
9663 sg_list_dwords = sg_entry_cnt << 1;
9664 if (i == 0) {
9665 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
9666 scsi_sg_q.sg_cur_list_cnt =
9667 sg_entry_cnt;
9668 } else {
9669 scsi_sg_q.sg_list_cnt =
9670 sg_entry_cnt - 1;
9671 scsi_sg_q.sg_cur_list_cnt =
9672 sg_entry_cnt - 1;
9673 }
9674 sg_entry_cnt = 0;
9675 }
9676 next_qp = AscReadLramByte(iop_base,
9677 (ushort)(q_addr +
9678 ASC_SCSIQ_B_FWD));
9679 scsi_sg_q.q_no = next_qp;
9680 q_addr = ASC_QNO_TO_QADDR(next_qp);
9681 AscMemWordCopyPtrToLram(iop_base,
9682 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
9683 (uchar *)&scsi_sg_q,
9684 sizeof(ASC_SG_LIST_Q) >> 1);
9685 AscMemDWordCopyPtrToLram(iop_base,
9686 q_addr + ASC_SGQ_LIST_BEG,
9687 (uchar *)&sg_head->
9688 sg_list[sg_index],
9689 sg_list_dwords);
9690 sg_index += ASC_SG_LIST_PER_Q;
9691 scsiq->next_sg_index = sg_index;
9692 }
9693 } else {
9694 scsiq->q1.cntl &= ~QC_SG_HEAD;
9695 }
9696 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
9697 scsiq->q1.data_addr = saved_data_addr;
9698 scsiq->q1.data_cnt = saved_data_cnt;
9699 return (sta);
9700 }
9701
9702 static int
9703 AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
9704 {
9705 int sta = FALSE;
9706
9707 if (AscHostReqRiscHalt(iop_base)) {
9708 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9709 AscStartChip(iop_base);
9710 return (sta);
9711 }
9712 return (sta);
9713 }
9714
9715 static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
9716 {
9717 ASC_SCSI_BIT_ID_TYPE org_id;
9718 int i;
9719 int sta = TRUE;
9720
9721 AscSetBank(iop_base, 1);
9722 org_id = AscReadChipDvcID(iop_base);
9723 for (i = 0; i <= ASC_MAX_TID; i++) {
9724 if (org_id == (0x01 << i))
9725 break;
9726 }
9727 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
9728 AscWriteChipDvcID(iop_base, id);
9729 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
9730 AscSetBank(iop_base, 0);
9731 AscSetChipSyn(iop_base, sdtr_data);
9732 if (AscGetChipSyn(iop_base) != sdtr_data) {
9733 sta = FALSE;
9734 }
9735 } else {
9736 sta = FALSE;
9737 }
9738 AscSetBank(iop_base, 1);
9739 AscWriteChipDvcID(iop_base, org_id);
9740 AscSetBank(iop_base, 0);
9741 return (sta);
9742 }
9743
9744 static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
9745 {
9746 uchar i;
9747 ushort s_addr;
9748 PortAddr iop_base;
9749 ushort warn_code;
9750
9751 iop_base = asc_dvc->iop_base;
9752 warn_code = 0;
9753 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
9754 (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
9755 64) >> 1)
9756 );
9757 i = ASC_MIN_ACTIVE_QNO;
9758 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
9759 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9760 (uchar)(i + 1));
9761 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9762 (uchar)(asc_dvc->max_total_qng));
9763 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9764 (uchar)i);
9765 i++;
9766 s_addr += ASC_QBLK_SIZE;
9767 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
9768 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9769 (uchar)(i + 1));
9770 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9771 (uchar)(i - 1));
9772 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9773 (uchar)i);
9774 }
9775 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9776 (uchar)ASC_QLINK_END);
9777 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9778 (uchar)(asc_dvc->max_total_qng - 1));
9779 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9780 (uchar)asc_dvc->max_total_qng);
9781 i++;
9782 s_addr += ASC_QBLK_SIZE;
9783 for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
9784 i++, s_addr += ASC_QBLK_SIZE) {
9785 AscWriteLramByte(iop_base,
9786 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
9787 AscWriteLramByte(iop_base,
9788 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
9789 AscWriteLramByte(iop_base,
9790 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
9791 }
9792 return (warn_code);
9793 }
9794
9795 static ushort AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
9796 {
9797 PortAddr iop_base;
9798 int i;
9799 ushort lram_addr;
9800
9801 iop_base = asc_dvc->iop_base;
9802 AscPutRiscVarFreeQHead(iop_base, 1);
9803 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
9804 AscPutVarFreeQHead(iop_base, 1);
9805 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
9806 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
9807 (uchar)((int)asc_dvc->max_total_qng + 1));
9808 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
9809 (uchar)((int)asc_dvc->max_total_qng + 2));
9810 AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
9811 asc_dvc->max_total_qng);
9812 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
9813 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9814 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
9815 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
9816 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
9817 AscPutQDoneInProgress(iop_base, 0);
9818 lram_addr = ASC_QADR_BEG;
9819 for (i = 0; i < 32; i++, lram_addr += 2) {
9820 AscWriteLramWord(iop_base, lram_addr, 0);
9821 }
9822 return (0);
9823 }
9824
9825 static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
9826 {
9827 if (asc_dvc->err_code == 0) {
9828 asc_dvc->err_code = err_code;
9829 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
9830 err_code);
9831 }
9832 return (err_code);
9833 }
9834
9835 static uchar
9836 AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
9837 {
9838 EXT_MSG sdtr_buf;
9839 uchar sdtr_period_index;
9840 PortAddr iop_base;
9841
9842 iop_base = asc_dvc->iop_base;
9843 sdtr_buf.msg_type = EXTENDED_MESSAGE;
9844 sdtr_buf.msg_len = MS_SDTR_LEN;
9845 sdtr_buf.msg_req = EXTENDED_SDTR;
9846 sdtr_buf.xfer_period = sdtr_period;
9847 sdtr_offset &= ASC_SYN_MAX_OFFSET;
9848 sdtr_buf.req_ack_offset = sdtr_offset;
9849 if ((sdtr_period_index =
9850 AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
9851 asc_dvc->max_sdtr_index) {
9852 AscMemWordCopyPtrToLram(iop_base,
9853 ASCV_MSGOUT_BEG,
9854 (uchar *)&sdtr_buf,
9855 sizeof(EXT_MSG) >> 1);
9856 return ((sdtr_period_index << 4) | sdtr_offset);
9857 } else {
9858
9859 sdtr_buf.req_ack_offset = 0;
9860 AscMemWordCopyPtrToLram(iop_base,
9861 ASCV_MSGOUT_BEG,
9862 (uchar *)&sdtr_buf,
9863 sizeof(EXT_MSG) >> 1);
9864 return (0);
9865 }
9866 }
9867
9868 static uchar
9869 AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
9870 {
9871 uchar byte;
9872 uchar sdtr_period_ix;
9873
9874 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
9875 if ((sdtr_period_ix > asc_dvc->max_sdtr_index)
9876 ) {
9877 return (0xFF);
9878 }
9879 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
9880 return (byte);
9881 }
9882
9883 static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
9884 {
9885 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9886 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
9887 return;
9888 }
9889
9890 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
9891 {
9892 uchar *period_table;
9893 int max_index;
9894 int min_index;
9895 int i;
9896
9897 period_table = asc_dvc->sdtr_period_tbl;
9898 max_index = (int)asc_dvc->max_sdtr_index;
9899 min_index = (int)asc_dvc->host_init_sdtr_index;
9900 if ((syn_time <= period_table[max_index])) {
9901 for (i = min_index; i < (max_index - 1); i++) {
9902 if (syn_time <= period_table[i]) {
9903 return ((uchar)i);
9904 }
9905 }
9906 return ((uchar)max_index);
9907 } else {
9908 return ((uchar)(max_index + 1));
9909 }
9910 }
9911
9912 static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
9913 {
9914 ushort q_addr;
9915 uchar next_qp;
9916 uchar q_status;
9917
9918 q_addr = ASC_QNO_TO_QADDR(free_q_head);
9919 q_status = (uchar)AscReadLramByte(iop_base,
9920 (ushort)(q_addr +
9921 ASC_SCSIQ_B_STATUS));
9922 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
9923 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
9924 return (next_qp);
9925 }
9926 return (ASC_QLINK_END);
9927 }
9928
9929 static uchar
9930 AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
9931 {
9932 uchar i;
9933
9934 for (i = 0; i < n_free_q; i++) {
9935 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
9936 == ASC_QLINK_END) {
9937 return (ASC_QLINK_END);
9938 }
9939 }
9940 return (free_q_head);
9941 }
9942
9943 static int AscHostReqRiscHalt(PortAddr iop_base)
9944 {
9945 int count = 0;
9946 int sta = 0;
9947 uchar saved_stop_code;
9948
9949 if (AscIsChipHalted(iop_base))
9950 return (1);
9951 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
9952 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
9953 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
9954 do {
9955 if (AscIsChipHalted(iop_base)) {
9956 sta = 1;
9957 break;
9958 }
9959 DvcSleepMilliSecond(100);
9960 } while (count++ < 20);
9961 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
9962 return (sta);
9963 }
9964
9965 static int AscStopQueueExe(PortAddr iop_base)
9966 {
9967 int count = 0;
9968
9969 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
9970 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
9971 ASC_STOP_REQ_RISC_STOP);
9972 do {
9973 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
9974 ASC_STOP_ACK_RISC_STOP) {
9975 return (1);
9976 }
9977 DvcSleepMilliSecond(100);
9978 } while (count++ < 20);
9979 }
9980 return (0);
9981 }
9982
9983 static void DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
9984 {
9985 udelay(micro_sec);
9986 }
9987
9988 static void DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
9989 {
9990 udelay((nano_sec + 999) / 1000);
9991 }
9992
9993 static int AscStartChip(PortAddr iop_base)
9994 {
9995 AscSetChipControl(iop_base, 0);
9996 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
9997 return (0);
9998 }
9999 return (1);
10000 }
10001
10002 static int AscStopChip(PortAddr iop_base)
10003 {
10004 uchar cc_val;
10005
10006 cc_val =
10007 AscGetChipControl(iop_base) &
10008 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
10009 AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
10010 AscSetChipIH(iop_base, INS_HALT);
10011 AscSetChipIH(iop_base, INS_RFLAG_WTM);
10012 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
10013 return (0);
10014 }
10015 return (1);
10016 }
10017
10018 static int AscIsChipHalted(PortAddr iop_base)
10019 {
10020 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
10021 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
10022 return (1);
10023 }
10024 }
10025 return (0);
10026 }
10027
10028 static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
10029 {
10030 AscSetBank(iop_base, 1);
10031 AscWriteChipIH(iop_base, ins_code);
10032 AscSetBank(iop_base, 0);
10033 return;
10034 }
10035
10036 static void AscAckInterrupt(PortAddr iop_base)
10037 {
10038 uchar host_flag;
10039 uchar risc_flag;
10040 ushort loop;
10041
10042 loop = 0;
10043 do {
10044 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
10045 if (loop++ > 0x7FFF) {
10046 break;
10047 }
10048 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
10049 host_flag =
10050 AscReadLramByte(iop_base,
10051 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
10052 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10053 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
10054 AscSetChipStatus(iop_base, CIW_INT_ACK);
10055 loop = 0;
10056 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
10057 AscSetChipStatus(iop_base, CIW_INT_ACK);
10058 if (loop++ > 3) {
10059 break;
10060 }
10061 }
10062 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10063 return;
10064 }
10065
10066 static void AscDisableInterrupt(PortAddr iop_base)
10067 {
10068 ushort cfg;
10069
10070 cfg = AscGetChipCfgLsw(iop_base);
10071 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
10072 return;
10073 }
10074
10075 static void AscEnableInterrupt(PortAddr iop_base)
10076 {
10077 ushort cfg;
10078
10079 cfg = AscGetChipCfgLsw(iop_base);
10080 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
10081 return;
10082 }
10083
10084 static void AscSetBank(PortAddr iop_base, uchar bank)
10085 {
10086 uchar val;
10087
10088 val = AscGetChipControl(iop_base) &
10089 (~
10090 (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
10091 CC_CHIP_RESET));
10092 if (bank == 1) {
10093 val |= CC_BANK_ONE;
10094 } else if (bank == 2) {
10095 val |= CC_DIAG | CC_BANK_ONE;
10096 } else {
10097 val &= ~CC_BANK_ONE;
10098 }
10099 AscSetChipControl(iop_base, val);
10100 return;
10101 }
10102
10103 static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
10104 {
10105 PortAddr iop_base;
10106 int i = 10;
10107
10108 iop_base = asc_dvc->iop_base;
10109 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
10110 && (i-- > 0)) {
10111 DvcSleepMilliSecond(100);
10112 }
10113 AscStopChip(iop_base);
10114 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
10115 DvcDelayNanoSecond(asc_dvc, 60000);
10116 AscSetChipIH(iop_base, INS_RFLAG_WTM);
10117 AscSetChipIH(iop_base, INS_HALT);
10118 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
10119 AscSetChipControl(iop_base, CC_HALT);
10120 DvcSleepMilliSecond(200);
10121 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10122 AscSetChipStatus(iop_base, 0);
10123 return (AscIsChipHalted(iop_base));
10124 }
10125
10126 static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
10127 {
10128 if (bus_type & ASC_IS_ISA)
10129 return (ASC_MAX_ISA_DMA_COUNT);
10130 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
10131 return (ASC_MAX_VL_DMA_COUNT);
10132 return (ASC_MAX_PCI_DMA_COUNT);
10133 }
10134
10135 #ifdef CONFIG_ISA
10136 static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
10137 {
10138 ushort channel;
10139
10140 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
10141 if (channel == 0x03)
10142 return (0);
10143 else if (channel == 0x00)
10144 return (7);
10145 return (channel + 4);
10146 }
10147
10148 static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
10149 {
10150 ushort cfg_lsw;
10151 uchar value;
10152
10153 if ((dma_channel >= 5) && (dma_channel <= 7)) {
10154 if (dma_channel == 7)
10155 value = 0x00;
10156 else
10157 value = dma_channel - 4;
10158 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
10159 cfg_lsw |= value;
10160 AscSetChipCfgLsw(iop_base, cfg_lsw);
10161 return (AscGetIsaDmaChannel(iop_base));
10162 }
10163 return (0);
10164 }
10165
10166 static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
10167 {
10168 speed_value &= 0x07;
10169 AscSetBank(iop_base, 1);
10170 AscWriteChipDmaSpeed(iop_base, speed_value);
10171 AscSetBank(iop_base, 0);
10172 return (AscGetIsaDmaSpeed(iop_base));
10173 }
10174
10175 static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
10176 {
10177 uchar speed_value;
10178
10179 AscSetBank(iop_base, 1);
10180 speed_value = AscReadChipDmaSpeed(iop_base);
10181 speed_value &= 0x07;
10182 AscSetBank(iop_base, 0);
10183 return (speed_value);
10184 }
10185 #endif /* CONFIG_ISA */
10186
10187 static ushort __devinit AscInitGetConfig(ASC_DVC_VAR *asc_dvc)
10188 {
10189 unsigned short warn_code = 0;
10190
10191 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
10192 if (asc_dvc->err_code != 0)
10193 return (UW_ERR);
10194
10195 if (AscFindSignature(asc_dvc->iop_base)) {
10196 warn_code |= AscInitAscDvcVar(asc_dvc);
10197 warn_code |= AscInitFromEEP(asc_dvc);
10198 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
10199 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
10200 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
10201 } else {
10202 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10203 }
10204 return warn_code;
10205 }
10206
10207 static unsigned short __devinit
10208 AscInitSetConfig(struct pci_dev *pdev, ASC_DVC_VAR *asc_dvc)
10209 {
10210 PortAddr iop_base = asc_dvc->iop_base;
10211 unsigned short cfg_msw;
10212 unsigned short warn_code = 0;
10213
10214 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
10215 if (asc_dvc->err_code != 0)
10216 return UW_ERR;
10217 if (!AscFindSignature(asc_dvc->iop_base)) {
10218 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10219 return 0;
10220 }
10221
10222 cfg_msw = AscGetChipCfgMsw(iop_base);
10223 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10224 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10225 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10226 AscSetChipCfgMsw(iop_base, cfg_msw);
10227 }
10228 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
10229 asc_dvc->cfg->cmd_qng_enabled) {
10230 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
10231 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10232 }
10233 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10234 warn_code |= ASC_WARN_AUTO_CONFIG;
10235 }
10236 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
10237 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
10238 != asc_dvc->irq_no) {
10239 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
10240 }
10241 }
10242 #ifdef CONFIG_PCI
10243 if (asc_dvc->bus_type & ASC_IS_PCI) {
10244 cfg_msw &= 0xFFC0;
10245 AscSetChipCfgMsw(iop_base, cfg_msw);
10246 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
10247 } else {
10248 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
10249 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
10250 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
10251 asc_dvc->bug_fix_cntl |=
10252 ASC_BUG_FIX_ASYN_USE_SYN;
10253 }
10254 }
10255 } else
10256 #endif /* CONFIG_PCI */
10257 if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
10258 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
10259 == ASC_CHIP_VER_ASYN_BUG) {
10260 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
10261 }
10262 }
10263 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
10264 asc_dvc->cfg->chip_scsi_id) {
10265 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
10266 }
10267 #ifdef CONFIG_ISA
10268 if (asc_dvc->bus_type & ASC_IS_ISA) {
10269 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
10270 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
10271 }
10272 #endif /* CONFIG_ISA */
10273
10274 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
10275 return warn_code;
10276 }
10277
10278 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
10279 {
10280 ushort warn_code;
10281 PortAddr iop_base;
10282
10283 iop_base = asc_dvc->iop_base;
10284 warn_code = 0;
10285 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
10286 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
10287 AscResetChipAndScsiBus(asc_dvc);
10288 DvcSleepMilliSecond((ASC_DCNT)
10289 ((ushort)asc_dvc->scsi_reset_wait * 1000));
10290 }
10291 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
10292 if (asc_dvc->err_code != 0)
10293 return (UW_ERR);
10294 if (!AscFindSignature(asc_dvc->iop_base)) {
10295 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10296 return (warn_code);
10297 }
10298 AscDisableInterrupt(iop_base);
10299 warn_code |= AscInitLram(asc_dvc);
10300 if (asc_dvc->err_code != 0)
10301 return (UW_ERR);
10302 ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
10303 (ulong)_asc_mcode_chksum);
10304 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
10305 _asc_mcode_size) != _asc_mcode_chksum) {
10306 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
10307 return (warn_code);
10308 }
10309 warn_code |= AscInitMicroCodeVar(asc_dvc);
10310 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
10311 AscEnableInterrupt(iop_base);
10312 return (warn_code);
10313 }
10314
10315 static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
10316 {
10317 int i;
10318 PortAddr iop_base;
10319 ushort warn_code;
10320 uchar chip_version;
10321
10322 iop_base = asc_dvc->iop_base;
10323 warn_code = 0;
10324 asc_dvc->err_code = 0;
10325 if ((asc_dvc->bus_type &
10326 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
10327 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
10328 }
10329 AscSetChipControl(iop_base, CC_HALT);
10330 AscSetChipStatus(iop_base, 0);
10331 asc_dvc->bug_fix_cntl = 0;
10332 asc_dvc->pci_fix_asyn_xfer = 0;
10333 asc_dvc->pci_fix_asyn_xfer_always = 0;
10334 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
10335 asc_dvc->sdtr_done = 0;
10336 asc_dvc->cur_total_qng = 0;
10337 asc_dvc->is_in_int = 0;
10338 asc_dvc->in_critical_cnt = 0;
10339 asc_dvc->last_q_shortage = 0;
10340 asc_dvc->use_tagged_qng = 0;
10341 asc_dvc->no_scam = 0;
10342 asc_dvc->unit_not_ready = 0;
10343 asc_dvc->queue_full_or_busy = 0;
10344 asc_dvc->redo_scam = 0;
10345 asc_dvc->res2 = 0;
10346 asc_dvc->host_init_sdtr_index = 0;
10347 asc_dvc->cfg->can_tagged_qng = 0;
10348 asc_dvc->cfg->cmd_qng_enabled = 0;
10349 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
10350 asc_dvc->init_sdtr = 0;
10351 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
10352 asc_dvc->scsi_reset_wait = 3;
10353 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
10354 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
10355 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
10356 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
10357 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
10358 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
10359 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
10360 ASC_LIB_VERSION_MINOR;
10361 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
10362 asc_dvc->cfg->chip_version = chip_version;
10363 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
10364 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
10365 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
10366 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
10367 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
10368 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
10369 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
10370 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
10371 asc_dvc->max_sdtr_index = 7;
10372 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
10373 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
10374 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
10375 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
10376 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
10377 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
10378 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
10379 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
10380 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
10381 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
10382 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
10383 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
10384 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
10385 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
10386 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
10387 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
10388 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
10389 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
10390 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
10391 asc_dvc->max_sdtr_index = 15;
10392 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
10393 AscSetExtraControl(iop_base,
10394 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10395 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
10396 AscSetExtraControl(iop_base,
10397 (SEC_ACTIVE_NEGATE |
10398 SEC_ENABLE_FILTER));
10399 }
10400 }
10401 if (asc_dvc->bus_type == ASC_IS_PCI) {
10402 AscSetExtraControl(iop_base,
10403 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10404 }
10405
10406 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
10407 #ifdef CONFIG_ISA
10408 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
10409 if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) {
10410 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
10411 asc_dvc->bus_type = ASC_IS_ISAPNP;
10412 }
10413 asc_dvc->cfg->isa_dma_channel =
10414 (uchar)AscGetIsaDmaChannel(iop_base);
10415 }
10416 #endif /* CONFIG_ISA */
10417 for (i = 0; i <= ASC_MAX_TID; i++) {
10418 asc_dvc->cur_dvc_qng[i] = 0;
10419 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
10420 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
10421 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
10422 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
10423 }
10424 return (warn_code);
10425 }
10426
10427 static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
10428 {
10429 ASCEEP_CONFIG eep_config_buf;
10430 ASCEEP_CONFIG *eep_config;
10431 PortAddr iop_base;
10432 ushort chksum;
10433 ushort warn_code;
10434 ushort cfg_msw, cfg_lsw;
10435 int i;
10436 int write_eep = 0;
10437
10438 iop_base = asc_dvc->iop_base;
10439 warn_code = 0;
10440 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
10441 AscStopQueueExe(iop_base);
10442 if ((AscStopChip(iop_base) == FALSE) ||
10443 (AscGetChipScsiCtrl(iop_base) != 0)) {
10444 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
10445 AscResetChipAndScsiBus(asc_dvc);
10446 DvcSleepMilliSecond((ASC_DCNT)
10447 ((ushort)asc_dvc->scsi_reset_wait * 1000));
10448 }
10449 if (AscIsChipHalted(iop_base) == FALSE) {
10450 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10451 return (warn_code);
10452 }
10453 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10454 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10455 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10456 return (warn_code);
10457 }
10458 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
10459 cfg_msw = AscGetChipCfgMsw(iop_base);
10460 cfg_lsw = AscGetChipCfgLsw(iop_base);
10461 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10462 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10463 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10464 AscSetChipCfgMsw(iop_base, cfg_msw);
10465 }
10466 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
10467 ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
10468 if (chksum == 0) {
10469 chksum = 0xaa55;
10470 }
10471 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10472 warn_code |= ASC_WARN_AUTO_CONFIG;
10473 if (asc_dvc->cfg->chip_version == 3) {
10474 if (eep_config->cfg_lsw != cfg_lsw) {
10475 warn_code |= ASC_WARN_EEPROM_RECOVER;
10476 eep_config->cfg_lsw =
10477 AscGetChipCfgLsw(iop_base);
10478 }
10479 if (eep_config->cfg_msw != cfg_msw) {
10480 warn_code |= ASC_WARN_EEPROM_RECOVER;
10481 eep_config->cfg_msw =
10482 AscGetChipCfgMsw(iop_base);
10483 }
10484 }
10485 }
10486 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
10487 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
10488 ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
10489 eep_config->chksum);
10490 if (chksum != eep_config->chksum) {
10491 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
10492 ASC_CHIP_VER_PCI_ULTRA_3050) {
10493 ASC_DBG(1,
10494 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
10495 eep_config->init_sdtr = 0xFF;
10496 eep_config->disc_enable = 0xFF;
10497 eep_config->start_motor = 0xFF;
10498 eep_config->use_cmd_qng = 0;
10499 eep_config->max_total_qng = 0xF0;
10500 eep_config->max_tag_qng = 0x20;
10501 eep_config->cntl = 0xBFFF;
10502 ASC_EEP_SET_CHIP_ID(eep_config, 7);
10503 eep_config->no_scam = 0;
10504 eep_config->adapter_info[0] = 0;
10505 eep_config->adapter_info[1] = 0;
10506 eep_config->adapter_info[2] = 0;
10507 eep_config->adapter_info[3] = 0;
10508 eep_config->adapter_info[4] = 0;
10509 /* Indicate EEPROM-less board. */
10510 eep_config->adapter_info[5] = 0xBB;
10511 } else {
10512 ASC_PRINT
10513 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
10514 write_eep = 1;
10515 warn_code |= ASC_WARN_EEPROM_CHKSUM;
10516 }
10517 }
10518 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
10519 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
10520 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
10521 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
10522 asc_dvc->start_motor = eep_config->start_motor;
10523 asc_dvc->dvc_cntl = eep_config->cntl;
10524 asc_dvc->no_scam = eep_config->no_scam;
10525 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
10526 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
10527 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
10528 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
10529 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
10530 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
10531 if (!AscTestExternalLram(asc_dvc)) {
10532 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
10533 ASC_IS_PCI_ULTRA)) {
10534 eep_config->max_total_qng =
10535 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
10536 eep_config->max_tag_qng =
10537 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
10538 } else {
10539 eep_config->cfg_msw |= 0x0800;
10540 cfg_msw |= 0x0800;
10541 AscSetChipCfgMsw(iop_base, cfg_msw);
10542 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
10543 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
10544 }
10545 } else {
10546 }
10547 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
10548 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
10549 }
10550 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
10551 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
10552 }
10553 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
10554 eep_config->max_tag_qng = eep_config->max_total_qng;
10555 }
10556 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
10557 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
10558 }
10559 asc_dvc->max_total_qng = eep_config->max_total_qng;
10560 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
10561 eep_config->use_cmd_qng) {
10562 eep_config->disc_enable = eep_config->use_cmd_qng;
10563 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10564 }
10565 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
10566 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
10567 }
10568 ASC_EEP_SET_CHIP_ID(eep_config,
10569 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
10570 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
10571 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
10572 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
10573 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
10574 }
10575
10576 for (i = 0; i <= ASC_MAX_TID; i++) {
10577 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
10578 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
10579 asc_dvc->cfg->sdtr_period_offset[i] =
10580 (uchar)(ASC_DEF_SDTR_OFFSET |
10581 (asc_dvc->host_init_sdtr_index << 4));
10582 }
10583 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
10584 if (write_eep) {
10585 if ((i =
10586 AscSetEEPConfig(iop_base, eep_config,
10587 asc_dvc->bus_type)) != 0) {
10588 ASC_PRINT1
10589 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
10590 i);
10591 } else {
10592 ASC_PRINT
10593 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
10594 }
10595 }
10596 return (warn_code);
10597 }
10598
10599 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
10600 {
10601 int i;
10602 ushort warn_code;
10603 PortAddr iop_base;
10604 ASC_PADDR phy_addr;
10605 ASC_DCNT phy_size;
10606
10607 iop_base = asc_dvc->iop_base;
10608 warn_code = 0;
10609 for (i = 0; i <= ASC_MAX_TID; i++) {
10610 AscPutMCodeInitSDTRAtID(iop_base, i,
10611 asc_dvc->cfg->sdtr_period_offset[i]
10612 );
10613 }
10614
10615 AscInitQLinkVar(asc_dvc);
10616 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
10617 asc_dvc->cfg->disc_enable);
10618 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
10619 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
10620
10621 /* Align overrun buffer on an 8 byte boundary. */
10622 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
10623 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
10624 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
10625 (uchar *)&phy_addr, 1);
10626 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
10627 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
10628 (uchar *)&phy_size, 1);
10629
10630 asc_dvc->cfg->mcode_date =
10631 AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
10632 asc_dvc->cfg->mcode_version =
10633 AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
10634
10635 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10636 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10637 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10638 return (warn_code);
10639 }
10640 if (AscStartChip(iop_base) != 1) {
10641 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10642 return (warn_code);
10643 }
10644
10645 return (warn_code);
10646 }
10647
10648 static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
10649 {
10650 PortAddr iop_base;
10651 ushort q_addr;
10652 ushort saved_word;
10653 int sta;
10654
10655 iop_base = asc_dvc->iop_base;
10656 sta = 0;
10657 q_addr = ASC_QNO_TO_QADDR(241);
10658 saved_word = AscReadLramWord(iop_base, q_addr);
10659 AscSetChipLramAddr(iop_base, q_addr);
10660 AscSetChipLramData(iop_base, 0x55AA);
10661 DvcSleepMilliSecond(10);
10662 AscSetChipLramAddr(iop_base, q_addr);
10663 if (AscGetChipLramData(iop_base) == 0x55AA) {
10664 sta = 1;
10665 AscWriteLramWord(iop_base, q_addr, saved_word);
10666 }
10667 return (sta);
10668 }
10669
10670 static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
10671 {
10672 uchar read_back;
10673 int retry;
10674
10675 retry = 0;
10676 while (TRUE) {
10677 AscSetChipEEPCmd(iop_base, cmd_reg);
10678 DvcSleepMilliSecond(1);
10679 read_back = AscGetChipEEPCmd(iop_base);
10680 if (read_back == cmd_reg) {
10681 return (1);
10682 }
10683 if (retry++ > ASC_EEP_MAX_RETRY) {
10684 return (0);
10685 }
10686 }
10687 }
10688
10689 static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
10690 {
10691 ushort read_back;
10692 int retry;
10693
10694 retry = 0;
10695 while (TRUE) {
10696 AscSetChipEEPData(iop_base, data_reg);
10697 DvcSleepMilliSecond(1);
10698 read_back = AscGetChipEEPData(iop_base);
10699 if (read_back == data_reg) {
10700 return (1);
10701 }
10702 if (retry++ > ASC_EEP_MAX_RETRY) {
10703 return (0);
10704 }
10705 }
10706 }
10707
10708 static void __devinit AscWaitEEPRead(void)
10709 {
10710 DvcSleepMilliSecond(1);
10711 return;
10712 }
10713
10714 static void __devinit AscWaitEEPWrite(void)
10715 {
10716 DvcSleepMilliSecond(20);
10717 return;
10718 }
10719
10720 static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
10721 {
10722 ushort read_wval;
10723 uchar cmd_reg;
10724
10725 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
10726 AscWaitEEPRead();
10727 cmd_reg = addr | ASC_EEP_CMD_READ;
10728 AscWriteEEPCmdReg(iop_base, cmd_reg);
10729 AscWaitEEPRead();
10730 read_wval = AscGetChipEEPData(iop_base);
10731 AscWaitEEPRead();
10732 return (read_wval);
10733 }
10734
10735 static ushort __devinit
10736 AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
10737 {
10738 ushort read_wval;
10739
10740 read_wval = AscReadEEPWord(iop_base, addr);
10741 if (read_wval != word_val) {
10742 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
10743 AscWaitEEPRead();
10744 AscWriteEEPDataReg(iop_base, word_val);
10745 AscWaitEEPRead();
10746 AscWriteEEPCmdReg(iop_base,
10747 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
10748 AscWaitEEPWrite();
10749 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
10750 AscWaitEEPRead();
10751 return (AscReadEEPWord(iop_base, addr));
10752 }
10753 return (read_wval);
10754 }
10755
10756 static ushort __devinit
10757 AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
10758 {
10759 ushort wval;
10760 ushort sum;
10761 ushort *wbuf;
10762 int cfg_beg;
10763 int cfg_end;
10764 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
10765 int s_addr;
10766
10767 wbuf = (ushort *)cfg_buf;
10768 sum = 0;
10769 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
10770 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10771 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
10772 sum += *wbuf;
10773 }
10774 if (bus_type & ASC_IS_VL) {
10775 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10776 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10777 } else {
10778 cfg_beg = ASC_EEP_DVC_CFG_BEG;
10779 cfg_end = ASC_EEP_MAX_DVC_ADDR;
10780 }
10781 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
10782 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
10783 if (s_addr <= uchar_end_in_config) {
10784 /*
10785 * Swap all char fields - must unswap bytes already swapped
10786 * by AscReadEEPWord().
10787 */
10788 *wbuf = le16_to_cpu(wval);
10789 } else {
10790 /* Don't swap word field at the end - cntl field. */
10791 *wbuf = wval;
10792 }
10793 sum += wval; /* Checksum treats all EEPROM data as words. */
10794 }
10795 /*
10796 * Read the checksum word which will be compared against 'sum'
10797 * by the caller. Word field already swapped.
10798 */
10799 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
10800 return (sum);
10801 }
10802
10803 static int __devinit
10804 AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
10805 {
10806 int n_error;
10807 ushort *wbuf;
10808 ushort word;
10809 ushort sum;
10810 int s_addr;
10811 int cfg_beg;
10812 int cfg_end;
10813 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
10814
10815 wbuf = (ushort *)cfg_buf;
10816 n_error = 0;
10817 sum = 0;
10818 /* Write two config words; AscWriteEEPWord() will swap bytes. */
10819 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10820 sum += *wbuf;
10821 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
10822 n_error++;
10823 }
10824 }
10825 if (bus_type & ASC_IS_VL) {
10826 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10827 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10828 } else {
10829 cfg_beg = ASC_EEP_DVC_CFG_BEG;
10830 cfg_end = ASC_EEP_MAX_DVC_ADDR;
10831 }
10832 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
10833 if (s_addr <= uchar_end_in_config) {
10834 /*
10835 * This is a char field. Swap char fields before they are
10836 * swapped again by AscWriteEEPWord().
10837 */
10838 word = cpu_to_le16(*wbuf);
10839 if (word !=
10840 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
10841 n_error++;
10842 }
10843 } else {
10844 /* Don't swap word field at the end - cntl field. */
10845 if (*wbuf !=
10846 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
10847 n_error++;
10848 }
10849 }
10850 sum += *wbuf; /* Checksum calculated from word values. */
10851 }
10852 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
10853 *wbuf = sum;
10854 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
10855 n_error++;
10856 }
10857
10858 /* Read EEPROM back again. */
10859 wbuf = (ushort *)cfg_buf;
10860 /*
10861 * Read two config words; Byte-swapping done by AscReadEEPWord().
10862 */
10863 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10864 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
10865 n_error++;
10866 }
10867 }
10868 if (bus_type & ASC_IS_VL) {
10869 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10870 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10871 } else {
10872 cfg_beg = ASC_EEP_DVC_CFG_BEG;
10873 cfg_end = ASC_EEP_MAX_DVC_ADDR;
10874 }
10875 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
10876 if (s_addr <= uchar_end_in_config) {
10877 /*
10878 * Swap all char fields. Must unswap bytes already swapped
10879 * by AscReadEEPWord().
10880 */
10881 word =
10882 le16_to_cpu(AscReadEEPWord
10883 (iop_base, (uchar)s_addr));
10884 } else {
10885 /* Don't swap word field at the end - cntl field. */
10886 word = AscReadEEPWord(iop_base, (uchar)s_addr);
10887 }
10888 if (*wbuf != word) {
10889 n_error++;
10890 }
10891 }
10892 /* Read checksum; Byte swapping not needed. */
10893 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
10894 n_error++;
10895 }
10896 return (n_error);
10897 }
10898
10899 static int __devinit
10900 AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
10901 {
10902 int retry;
10903 int n_error;
10904
10905 retry = 0;
10906 while (TRUE) {
10907 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
10908 bus_type)) == 0) {
10909 break;
10910 }
10911 if (++retry > ASC_EEP_MAX_RETRY) {
10912 break;
10913 }
10914 }
10915 return (n_error);
10916 }
10917
10918 static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
10919 {
10920 char type = sdev->type;
10921 ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
10922
10923 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
10924 if (!(asc_dvc->init_sdtr & tid_bits)) {
10925 if ((type == TYPE_ROM) &&
10926 (strncmp(sdev->vendor, "HP ", 3) == 0)) {
10927 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
10928 }
10929 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
10930 if ((type == TYPE_PROCESSOR) ||
10931 (type == TYPE_SCANNER) || (type == TYPE_ROM) ||
10932 (type == TYPE_TAPE)) {
10933 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
10934 }
10935
10936 if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
10937 AscSetRunChipSynRegAtID(asc_dvc->iop_base,
10938 sdev->id,
10939 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
10940 }
10941 }
10942 }
10943 }
10944
10945 static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
10946 {
10947 uchar byte_data;
10948 ushort word_data;
10949
10950 if (isodd_word(addr)) {
10951 AscSetChipLramAddr(iop_base, addr - 1);
10952 word_data = AscGetChipLramData(iop_base);
10953 byte_data = (uchar)((word_data >> 8) & 0xFF);
10954 } else {
10955 AscSetChipLramAddr(iop_base, addr);
10956 word_data = AscGetChipLramData(iop_base);
10957 byte_data = (uchar)(word_data & 0xFF);
10958 }
10959 return (byte_data);
10960 }
10961
10962 static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
10963 {
10964 ushort word_data;
10965
10966 AscSetChipLramAddr(iop_base, addr);
10967 word_data = AscGetChipLramData(iop_base);
10968 return (word_data);
10969 }
10970
10971 #if CC_VERY_LONG_SG_LIST
10972 static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
10973 {
10974 ushort val_low, val_high;
10975 ASC_DCNT dword_data;
10976
10977 AscSetChipLramAddr(iop_base, addr);
10978 val_low = AscGetChipLramData(iop_base);
10979 val_high = AscGetChipLramData(iop_base);
10980 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
10981 return (dword_data);
10982 }
10983 #endif /* CC_VERY_LONG_SG_LIST */
10984
10985 static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
10986 {
10987 AscSetChipLramAddr(iop_base, addr);
10988 AscSetChipLramData(iop_base, word_val);
10989 return;
10990 }
10991
10992 static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
10993 {
10994 ushort word_data;
10995
10996 if (isodd_word(addr)) {
10997 addr--;
10998 word_data = AscReadLramWord(iop_base, addr);
10999 word_data &= 0x00FF;
11000 word_data |= (((ushort)byte_val << 8) & 0xFF00);
11001 } else {
11002 word_data = AscReadLramWord(iop_base, addr);
11003 word_data &= 0xFF00;
11004 word_data |= ((ushort)byte_val & 0x00FF);
11005 }
11006 AscWriteLramWord(iop_base, addr, word_data);
11007 return;
11008 }
11009
11010 /*
11011 * Copy 2 bytes to LRAM.
11012 *
11013 * The source data is assumed to be in little-endian order in memory
11014 * and is maintained in little-endian order when written to LRAM.
11015 */
11016 static void
11017 AscMemWordCopyPtrToLram(PortAddr iop_base,
11018 ushort s_addr, uchar *s_buffer, int words)
11019 {
11020 int i;
11021
11022 AscSetChipLramAddr(iop_base, s_addr);
11023 for (i = 0; i < 2 * words; i += 2) {
11024 /*
11025 * On a little-endian system the second argument below
11026 * produces a little-endian ushort which is written to
11027 * LRAM in little-endian order. On a big-endian system
11028 * the second argument produces a big-endian ushort which
11029 * is "transparently" byte-swapped by outpw() and written
11030 * in little-endian order to LRAM.
11031 */
11032 outpw(iop_base + IOP_RAM_DATA,
11033 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
11034 }
11035 return;
11036 }
11037
11038 /*
11039 * Copy 4 bytes to LRAM.
11040 *
11041 * The source data is assumed to be in little-endian order in memory
11042 * and is maintained in little-endian order when writen to LRAM.
11043 */
11044 static void
11045 AscMemDWordCopyPtrToLram(PortAddr iop_base,
11046 ushort s_addr, uchar *s_buffer, int dwords)
11047 {
11048 int i;
11049
11050 AscSetChipLramAddr(iop_base, s_addr);
11051 for (i = 0; i < 4 * dwords; i += 4) {
11052 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
11053 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
11054 }
11055 return;
11056 }
11057
11058 /*
11059 * Copy 2 bytes from LRAM.
11060 *
11061 * The source data is assumed to be in little-endian order in LRAM
11062 * and is maintained in little-endian order when written to memory.
11063 */
11064 static void
11065 AscMemWordCopyPtrFromLram(PortAddr iop_base,
11066 ushort s_addr, uchar *d_buffer, int words)
11067 {
11068 int i;
11069 ushort word;
11070
11071 AscSetChipLramAddr(iop_base, s_addr);
11072 for (i = 0; i < 2 * words; i += 2) {
11073 word = inpw(iop_base + IOP_RAM_DATA);
11074 d_buffer[i] = word & 0xff;
11075 d_buffer[i + 1] = (word >> 8) & 0xff;
11076 }
11077 return;
11078 }
11079
11080 static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
11081 {
11082 ASC_DCNT sum;
11083 int i;
11084
11085 sum = 0L;
11086 for (i = 0; i < words; i++, s_addr += 2) {
11087 sum += AscReadLramWord(iop_base, s_addr);
11088 }
11089 return (sum);
11090 }
11091
11092 static void
11093 AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
11094 {
11095 int i;
11096
11097 AscSetChipLramAddr(iop_base, s_addr);
11098 for (i = 0; i < words; i++) {
11099 AscSetChipLramData(iop_base, set_wval);
11100 }
11101 return;
11102 }
11103
11104 /*
11105 * --- Adv Library Functions
11106 */
11107
11108 /* a_mcode.h */
11109
11110 /* Microcode buffer is kept after initialization for error recovery. */
11111 static unsigned char _adv_asc3550_buf[] = {
11112 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
11113 0x01, 0x00, 0x48, 0xe4,
11114 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff,
11115 0x28, 0x0e, 0x9e, 0xe7,
11116 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7,
11117 0x55, 0xf0, 0x01, 0xf6,
11118 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
11119 0x00, 0xec, 0x85, 0xf0,
11120 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0,
11121 0x86, 0xf0, 0xb4, 0x00,
11122 0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00,
11123 0xaa, 0x18, 0x02, 0x80,
11124 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
11125 0x00, 0x57, 0x01, 0xea,
11126 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80,
11127 0x03, 0xe6, 0xb6, 0x00,
11128 0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12,
11129 0x02, 0x4a, 0xb9, 0x54,
11130 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
11131 0x3e, 0x00, 0x80, 0x00,
11132 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
11133 0x74, 0x01, 0x76, 0x01,
11134 0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13,
11135 0x4c, 0x1c, 0xbb, 0x55,
11136 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
11137 0x03, 0xf7, 0x06, 0xf7,
11138 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08,
11139 0x30, 0x13, 0x64, 0x15,
11140 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c,
11141 0x04, 0xea, 0x5d, 0xf0,
11142 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
11143 0xcc, 0x00, 0x20, 0x01,
11144 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13,
11145 0x40, 0x13, 0x30, 0x1c,
11146 0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
11147 0x59, 0xf0, 0xa7, 0xf0,
11148 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
11149 0xa4, 0x00, 0xb5, 0x00,
11150 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a,
11151 0x14, 0x0e, 0x02, 0x10,
11152 0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13,
11153 0x10, 0x15, 0x14, 0x15,
11154 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
11155 0x91, 0x44, 0x0a, 0x45,
11156 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58,
11157 0x83, 0x59, 0x05, 0xe6,
11158 0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8,
11159 0x02, 0xfa, 0x03, 0xfa,
11160 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
11161 0x9e, 0x00, 0xa8, 0x00,
11162 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01,
11163 0x7a, 0x01, 0xc0, 0x01,
11164 0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08,
11165 0x69, 0x08, 0xba, 0x08,
11166 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
11167 0xf1, 0x10, 0x06, 0x12,
11168 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14,
11169 0x8a, 0x15, 0xc6, 0x17,
11170 0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
11171 0x0e, 0x47, 0x48, 0x47,
11172 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
11173 0x14, 0x56, 0x77, 0x57,
11174 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c,
11175 0xf0, 0x29, 0x02, 0xfe,
11176 0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf,
11177 0xfe, 0x80, 0x01, 0xff,
11178 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
11179 0x00, 0xfe, 0x57, 0x24,
11180 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09,
11181 0x00, 0x00, 0xff, 0x08,
11182 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
11183 0xff, 0xff, 0xff, 0x0f,
11184 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
11185 0xfe, 0x04, 0xf7, 0xcf,
11186 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67,
11187 0x0b, 0x3c, 0x2a, 0xfe,
11188 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0,
11189 0xfe, 0xf0, 0x01, 0xfe,
11190 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
11191 0x02, 0xfe, 0xd4, 0x0c,
11192 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
11193 0x1c, 0x05, 0xfe, 0xa6,
11194 0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48,
11195 0xf0, 0xfe, 0x86, 0x02,
11196 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
11197 0xfe, 0x46, 0xf0, 0xfe,
11198 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
11199 0x44, 0x02, 0xfe, 0x44,
11200 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b,
11201 0xa0, 0x17, 0x06, 0x18,
11202 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
11203 0x1e, 0x1c, 0xfe, 0xe9,
11204 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7,
11205 0x0a, 0x6b, 0x01, 0x9e,
11206 0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b,
11207 0x01, 0x82, 0xfe, 0xbd,
11208 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
11209 0x58, 0x1c, 0x17, 0x06,
11210 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21,
11211 0xfe, 0x94, 0x02, 0xfe,
11212 0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97,
11213 0x01, 0xfe, 0x54, 0x0f,
11214 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
11215 0x69, 0x10, 0x17, 0x06,
11216 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05,
11217 0xf6, 0xc7, 0x01, 0xfe,
11218 0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6,
11219 0x02, 0x29, 0x0a, 0x40,
11220 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
11221 0x58, 0x0a, 0x99, 0x01,
11222 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29,
11223 0x2a, 0x46, 0xfe, 0x02,
11224 0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc,
11225 0x01, 0xfe, 0x07, 0x4b,
11226 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
11227 0xfe, 0x56, 0x03, 0xfe,
11228 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10,
11229 0xfe, 0x9f, 0xf0, 0xfe,
11230 0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48,
11231 0x1c, 0xeb, 0x09, 0x04,
11232 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
11233 0x01, 0x0e, 0xac, 0x75,
11234 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2,
11235 0xfe, 0x82, 0xf0, 0xfe,
11236 0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25,
11237 0x32, 0x1f, 0xfe, 0xb4,
11238 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
11239 0x0a, 0xf0, 0xfe, 0x7a,
11240 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c,
11241 0x01, 0x33, 0x8f, 0xfe,
11242 0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8,
11243 0xf7, 0xfe, 0x48, 0x1c,
11244 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
11245 0x0a, 0xca, 0x01, 0x0e,
11246 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14,
11247 0x2c, 0x01, 0x33, 0x8f,
11248 0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65,
11249 0xfe, 0x3c, 0x04, 0x1f,
11250 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
11251 0x12, 0x2b, 0xff, 0x02,
11252 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f,
11253 0x22, 0x30, 0x2e, 0xd5,
11254 0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c,
11255 0xfe, 0x4c, 0x54, 0x64,
11256 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
11257 0xfe, 0x2a, 0x13, 0x2f,
11258 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
11259 0xd3, 0xfa, 0xef, 0x86,
11260 0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04,
11261 0x1d, 0xfe, 0x1c, 0x12,
11262 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
11263 0x70, 0x0c, 0x02, 0x22,
11264 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92,
11265 0x01, 0x33, 0x02, 0x29,
11266 0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87,
11267 0x80, 0xfe, 0x31, 0xe4,
11268 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
11269 0xfe, 0x70, 0x12, 0x49,
11270 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe,
11271 0x80, 0x05, 0xfe, 0x31,
11272 0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00,
11273 0x28, 0xfe, 0x42, 0x12,
11274 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
11275 0x11, 0xfe, 0xe3, 0x00,
11276 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
11277 0x64, 0x05, 0x83, 0x24,
11278 0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe,
11279 0x09, 0x48, 0x01, 0x08,
11280 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
11281 0x86, 0x24, 0x06, 0x12,
11282 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47,
11283 0x01, 0xa7, 0x14, 0x92,
11284 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c,
11285 0x02, 0x22, 0x05, 0xfe,
11286 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
11287 0x47, 0x01, 0xa7, 0x26,
11288 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f,
11289 0x01, 0xfe, 0xaa, 0x14,
11290 0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00,
11291 0x05, 0x50, 0xb4, 0x0c,
11292 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
11293 0x13, 0x01, 0xfe, 0x14,
11294 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c,
11295 0xff, 0x02, 0x00, 0x57,
11296 0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe,
11297 0x72, 0x06, 0x49, 0x04,
11298 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
11299 0x06, 0x11, 0x9a, 0x01,
11300 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06,
11301 0x01, 0xa7, 0xec, 0x72,
11302 0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32,
11303 0xfe, 0x0a, 0xf0, 0xfe,
11304 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
11305 0x8d, 0x81, 0x02, 0x22,
11306 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00,
11307 0x01, 0x08, 0x15, 0x00,
11308 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15,
11309 0x00, 0x02, 0xfe, 0x32,
11310 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
11311 0xfe, 0x1b, 0x00, 0x01,
11312 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
11313 0x08, 0x15, 0x06, 0x01,
11314 0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe,
11315 0x9a, 0x81, 0x4b, 0x1d,
11316 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
11317 0x45, 0xfe, 0x32, 0x12,
11318 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0,
11319 0xfe, 0x32, 0x07, 0x8d,
11320 0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a,
11321 0x06, 0x15, 0x19, 0x02,
11322 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
11323 0x90, 0x77, 0xfe, 0xca,
11324 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07,
11325 0x10, 0xfe, 0x0e, 0x12,
11326 0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe,
11327 0x83, 0xe7, 0xc4, 0xa1,
11328 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
11329 0x40, 0x12, 0x58, 0x01,
11330 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6,
11331 0x51, 0x83, 0xfb, 0xfe,
11332 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90,
11333 0xfe, 0x40, 0x50, 0xfe,
11334 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
11335 0xfe, 0x2a, 0x12, 0xfe,
11336 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f,
11337 0x85, 0x01, 0xa8, 0xfe,
11338 0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56,
11339 0x18, 0x57, 0xfb, 0xfe,
11340 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
11341 0x0c, 0x39, 0x18, 0x3a,
11342 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e,
11343 0x11, 0x65, 0xfe, 0x48,
11344 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73,
11345 0xdd, 0xb8, 0xfe, 0x80,
11346 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
11347 0xfe, 0x7a, 0x08, 0x8d,
11348 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9,
11349 0x10, 0x61, 0x04, 0x06,
11350 0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68,
11351 0x12, 0xfe, 0x2e, 0x1c,
11352 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
11353 0x52, 0x12, 0xfe, 0x2c,
11354 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe,
11355 0x08, 0xfe, 0x8a, 0x10,
11356 0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe,
11357 0x24, 0x0a, 0xab, 0xfe,
11358 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
11359 0x1c, 0x12, 0xb5, 0xfe,
11360 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb,
11361 0x1c, 0x06, 0x16, 0x9d,
11362 0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b,
11363 0x14, 0x92, 0x01, 0x33,
11364 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
11365 0xfe, 0x74, 0x18, 0x1c,
11366 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b,
11367 0x01, 0xe6, 0x1e, 0x27,
11368 0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a,
11369 0x09, 0x04, 0x6a, 0xfe,
11370 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
11371 0xfe, 0x83, 0x80, 0xfe,
11372 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63,
11373 0x27, 0xfe, 0x40, 0x59,
11374 0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18,
11375 0x7c, 0xbe, 0x54, 0xbf,
11376 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
11377 0x79, 0x56, 0x68, 0x57,
11378 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5,
11379 0xa2, 0x23, 0x0c, 0x7b,
11380 0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19,
11381 0x16, 0xd7, 0x79, 0x39,
11382 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
11383 0xfe, 0x10, 0x58, 0xfe,
11384 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04,
11385 0x19, 0x16, 0xd7, 0x09,
11386 0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f,
11387 0xfe, 0x10, 0x90, 0xfe,
11388 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
11389 0x11, 0x9b, 0x09, 0x04,
11390 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08,
11391 0xfe, 0x0c, 0x58, 0xfe,
11392 0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04,
11393 0x0b, 0xfe, 0x1a, 0x12,
11394 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
11395 0x14, 0x7a, 0x01, 0x33,
11396 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39,
11397 0xfe, 0xed, 0x19, 0xbf,
11398 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff,
11399 0x34, 0xfe, 0x74, 0x10,
11400 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
11401 0x84, 0x05, 0xcb, 0x1c,
11402 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1,
11403 0xf0, 0xfe, 0xc4, 0x0a,
11404 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe,
11405 0xce, 0xf0, 0xfe, 0xca,
11406 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
11407 0x22, 0x00, 0x02, 0x5a,
11408 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a,
11409 0xfe, 0xd0, 0xf0, 0xfe,
11410 0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f,
11411 0x4c, 0xfe, 0x10, 0x10,
11412 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
11413 0x2a, 0x13, 0xfe, 0x4e,
11414 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1,
11415 0x16, 0x32, 0x2a, 0x73,
11416 0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25,
11417 0x32, 0x8c, 0xfe, 0x48,
11418 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
11419 0xdb, 0x10, 0x11, 0xfe,
11420 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0,
11421 0x22, 0x30, 0x2e, 0xd8,
11422 0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1,
11423 0x45, 0x0f, 0xfe, 0x42,
11424 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
11425 0x09, 0x04, 0x0b, 0xfe,
11426 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28,
11427 0x00, 0x21, 0xfe, 0xa6,
11428 0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00,
11429 0xfe, 0xe2, 0x10, 0x01,
11430 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
11431 0x01, 0x6f, 0x02, 0x29,
11432 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10,
11433 0x01, 0x86, 0x3e, 0x0b,
11434 0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3,
11435 0x3e, 0x0b, 0x0f, 0xfe,
11436 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
11437 0xe8, 0x59, 0x11, 0x2d,
11438 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09,
11439 0x04, 0x0b, 0x84, 0x3e,
11440 0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12,
11441 0x09, 0x04, 0x1b, 0xfe,
11442 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
11443 0x1c, 0x1c, 0xfe, 0x9d,
11444 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f,
11445 0xfe, 0x15, 0x00, 0xfe,
11446 0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10,
11447 0x0f, 0xfe, 0x47, 0x00,
11448 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
11449 0xab, 0x70, 0x05, 0x6b,
11450 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe,
11451 0x1c, 0x42, 0x59, 0x01,
11452 0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31,
11453 0x00, 0x37, 0x97, 0x01,
11454 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
11455 0x1d, 0xfe, 0xce, 0x45,
11456 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75,
11457 0x57, 0x05, 0x51, 0xfe,
11458 0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48,
11459 0x46, 0x09, 0x04, 0x1d,
11460 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
11461 0x99, 0x01, 0x0e, 0xfe,
11462 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51,
11463 0xfe, 0xee, 0x14, 0xee,
11464 0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad,
11465 0x13, 0x02, 0x29, 0x1e,
11466 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
11467 0xce, 0x1e, 0x2d, 0x47,
11468 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06,
11469 0x12, 0x4d, 0x01, 0xfe,
11470 0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe,
11471 0xf0, 0x0d, 0xfe, 0x02,
11472 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
11473 0xf6, 0xfe, 0x34, 0x01,
11474 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13,
11475 0xaf, 0xfe, 0x02, 0xea,
11476 0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c,
11477 0x05, 0xfe, 0x38, 0x01,
11478 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
11479 0x0c, 0xfe, 0x62, 0x01,
11480 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06,
11481 0x03, 0x23, 0x03, 0x1e,
11482 0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe,
11483 0x71, 0x13, 0xfe, 0x24,
11484 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
11485 0xdc, 0xfe, 0x73, 0x57,
11486 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe,
11487 0x80, 0x5d, 0x03, 0xfe,
11488 0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6,
11489 0x75, 0x03, 0x09, 0x04,
11490 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
11491 0xfe, 0x1e, 0x80, 0xe1,
11492 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e,
11493 0x90, 0xa3, 0xfe, 0x3c,
11494 0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82,
11495 0x16, 0x2f, 0x07, 0x2d,
11496 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
11497 0xe8, 0x11, 0xfe, 0xe9,
11498 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe,
11499 0x1e, 0x1c, 0xfe, 0x14,
11500 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01,
11501 0x09, 0x04, 0x4f, 0xfe,
11502 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
11503 0x40, 0x12, 0x20, 0x63,
11504 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08,
11505 0x1c, 0x05, 0xfe, 0xac,
11506 0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05,
11507 0xfe, 0xb0, 0x00, 0xfe,
11508 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
11509 0x24, 0x69, 0x12, 0xc9,
11510 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe,
11511 0x90, 0x4d, 0xfe, 0x91,
11512 0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c,
11513 0xfe, 0x90, 0x4d, 0xfe,
11514 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
11515 0x46, 0x1e, 0x20, 0xed,
11516 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea,
11517 0x70, 0xfe, 0x14, 0x1c,
11518 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee,
11519 0xfe, 0x07, 0xe6, 0x1d,
11520 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
11521 0xfa, 0xef, 0xfe, 0x42,
11522 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0,
11523 0xfe, 0x36, 0x12, 0xf0,
11524 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
11525 0x3d, 0x75, 0x07, 0x10,
11526 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
11527 0x10, 0x07, 0x7e, 0x45,
11528 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74,
11529 0xfe, 0x01, 0xec, 0x97,
11530 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76,
11531 0x27, 0x01, 0xda, 0xfe,
11532 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
11533 0xfe, 0x48, 0x12, 0x07,
11534 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16,
11535 0xfe, 0x3e, 0x11, 0x07,
11536 0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8,
11537 0x11, 0x07, 0x19, 0xfe,
11538 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
11539 0x01, 0x08, 0x8c, 0x43,
11540 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11,
11541 0x7e, 0x02, 0x29, 0x2b,
11542 0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe,
11543 0xfc, 0x10, 0x09, 0x04,
11544 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
11545 0xc6, 0x10, 0x1e, 0x58,
11546 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c,
11547 0x54, 0x18, 0x55, 0x23,
11548 0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01,
11549 0xa5, 0xc0, 0x38, 0xc1,
11550 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
11551 0x05, 0xfa, 0x4e, 0xfe,
11552 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56,
11553 0x0c, 0x56, 0x18, 0x57,
11554 0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe,
11555 0x00, 0x56, 0xfe, 0xa1,
11556 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
11557 0x58, 0xfe, 0x1f, 0x40,
11558 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56,
11559 0x31, 0x57, 0xfe, 0x44,
11560 0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe,
11561 0x8a, 0x50, 0x05, 0x39,
11562 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
11563 0x12, 0xcd, 0x02, 0x5b,
11564 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44,
11565 0x2f, 0x07, 0x9b, 0x21,
11566 0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79,
11567 0x39, 0x68, 0x3a, 0xfe,
11568 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
11569 0x51, 0xfe, 0x8e, 0x51,
11570 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b,
11571 0x01, 0x08, 0x25, 0x32,
11572 0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b,
11573 0x3b, 0x02, 0x44, 0x01,
11574 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
11575 0x01, 0x08, 0x1f, 0xa2,
11576 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c,
11577 0x00, 0x28, 0x84, 0x49,
11578 0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06,
11579 0x78, 0x3d, 0xfe, 0xda,
11580 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
11581 0x05, 0xc6, 0x28, 0x84,
11582 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8,
11583 0x14, 0xfe, 0x03, 0x17,
11584 0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01,
11585 0xfe, 0xaa, 0x14, 0x02,
11586 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
11587 0x21, 0x44, 0x01, 0xfe,
11588 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87,
11589 0xfe, 0x4a, 0xf4, 0x0b,
11590 0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a,
11591 0x85, 0x02, 0x5b, 0x05,
11592 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
11593 0xd8, 0x14, 0x02, 0x5c,
11594 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1,
11595 0x01, 0x08, 0x23, 0x72,
11596 0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca,
11597 0x12, 0x5e, 0x2b, 0x01,
11598 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
11599 0x1c, 0xfe, 0xff, 0x7f,
11600 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00,
11601 0x57, 0x48, 0x8b, 0x1c,
11602 0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02,
11603 0x00, 0x57, 0x48, 0x8b,
11604 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
11605 0x03, 0x0a, 0x50, 0x01,
11606 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00,
11607 0x54, 0xfe, 0x00, 0xf4,
11608 0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe,
11609 0x03, 0x7c, 0x63, 0x27,
11610 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
11611 0xfe, 0x82, 0x4a, 0xfe,
11612 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe,
11613 0x42, 0x48, 0x5f, 0x60,
11614 0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08,
11615 0x1f, 0xfe, 0xa2, 0x14,
11616 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
11617 0xcc, 0x12, 0x49, 0x04,
11618 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe,
11619 0xe8, 0x13, 0x3b, 0x13,
11620 0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55,
11621 0xa1, 0xff, 0x02, 0x83,
11622 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
11623 0x13, 0x06, 0xfe, 0x56,
11624 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe,
11625 0x64, 0x00, 0x17, 0x93,
11626 0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe,
11627 0xc8, 0x00, 0x8e, 0xe4,
11628 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
11629 0x01, 0xba, 0xfe, 0x4e,
11630 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0,
11631 0xfe, 0x60, 0x14, 0xfe,
11632 0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01,
11633 0xfe, 0x22, 0x13, 0x1c,
11634 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
11635 0xfe, 0x9c, 0x14, 0xb7,
11636 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba,
11637 0xfe, 0x9c, 0x14, 0xb7,
11638 0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06,
11639 0xfe, 0xb4, 0x56, 0xfe,
11640 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
11641 0xe5, 0x15, 0x0b, 0x01,
11642 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89,
11643 0x49, 0x01, 0x08, 0x03,
11644 0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6,
11645 0x15, 0x06, 0x01, 0x08,
11646 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
11647 0x4a, 0x01, 0x08, 0x03,
11648 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc,
11649 0xfe, 0x49, 0xf4, 0x00,
11650 0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01,
11651 0x08, 0x2f, 0x07, 0xfe,
11652 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
11653 0x01, 0x43, 0x1e, 0xcd,
11654 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e,
11655 0xed, 0x88, 0x07, 0x10,
11656 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a,
11657 0x80, 0x01, 0x0e, 0x88,
11658 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
11659 0x88, 0x03, 0x0a, 0x42,
11660 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e,
11661 0xfe, 0x80, 0x80, 0xf2,
11662 0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51,
11663 0x01, 0x82, 0x03, 0x17,
11664 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
11665 0xfe, 0x24, 0x1c, 0xfe,
11666 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0,
11667 0x91, 0x1d, 0x66, 0xfe,
11668 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe,
11669 0xda, 0x10, 0x17, 0x10,
11670 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
11671 0x05, 0xfe, 0x66, 0x01,
11672 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06,
11673 0xfe, 0x3c, 0x50, 0x66,
11674 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe,
11675 0x40, 0x16, 0xfe, 0xb6,
11676 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
11677 0x10, 0x71, 0xfe, 0x83,
11678 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90,
11679 0xfe, 0x62, 0x16, 0xfe,
11680 0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19,
11681 0xfe, 0x98, 0xe7, 0x00,
11682 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
11683 0xfe, 0x30, 0xbc, 0xfe,
11684 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
11685 0xc5, 0x90, 0xfe, 0x9a,
11686 0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe,
11687 0x42, 0x10, 0xfe, 0x02,
11688 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
11689 0xfe, 0x1d, 0xf7, 0x4f,
11690 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f,
11691 0x47, 0xfe, 0x83, 0x58,
11692 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11,
11693 0xfe, 0xdd, 0x00, 0x63,
11694 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
11695 0x06, 0x37, 0x95, 0xa9,
11696 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e,
11697 0x18, 0x1c, 0x1a, 0x5d,
11698 0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe,
11699 0xe1, 0x10, 0x78, 0x2c,
11700 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
11701 0x13, 0x3c, 0x8a, 0x0a,
11702 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
11703 0xe3, 0xfe, 0x00, 0xcc,
11704 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01,
11705 0x0e, 0xf2, 0x01, 0x6f,
11706 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
11707 0xf6, 0xfe, 0xd6, 0xf0,
11708 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe,
11709 0x15, 0x00, 0x59, 0x76,
11710 0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35,
11711 0x11, 0x2d, 0x01, 0x6f,
11712 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
11713 0xc8, 0xfe, 0x48, 0x55,
11714 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a,
11715 0x99, 0x01, 0x0e, 0xf0,
11716 0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73,
11717 0x75, 0x03, 0x0a, 0x42,
11718 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
11719 0x0e, 0x73, 0x75, 0x03,
11720 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00,
11721 0xfe, 0x3a, 0x45, 0x5b,
11722 0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00,
11723 0xfe, 0x02, 0xe6, 0x1b,
11724 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
11725 0xfe, 0x94, 0x00, 0xfe,
11726 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02,
11727 0xe6, 0x2c, 0xfe, 0x4e,
11728 0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69,
11729 0x03, 0x07, 0x7a, 0xfe,
11730 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
11731 0x07, 0x1b, 0xfe, 0x5a,
11732 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d,
11733 0x24, 0x2c, 0xdc, 0x07,
11734 0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d,
11735 0x9f, 0xad, 0x03, 0x14,
11736 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
11737 0x03, 0x25, 0xfe, 0xca,
11738 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a,
11739 0x00, 0x00,
11740 };
11741
11742 static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
11743 static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
11744
11745 /* Microcode buffer is kept after initialization for error recovery. */
11746 static unsigned char _adv_asc38C0800_buf[] = {
11747 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
11748 0x01, 0x00, 0x48, 0xe4,
11749 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff,
11750 0x1c, 0x0f, 0x00, 0xf6,
11751 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6,
11752 0x09, 0xe7, 0x55, 0xf0,
11753 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
11754 0x18, 0xf4, 0x08, 0x00,
11755 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6,
11756 0x86, 0xf0, 0xb1, 0xf0,
11757 0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c,
11758 0x3c, 0x00, 0xbb, 0x00,
11759 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
11760 0xba, 0x13, 0x18, 0x40,
11761 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01,
11762 0x6e, 0x01, 0x74, 0x01,
11763 0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00,
11764 0xc0, 0x00, 0x01, 0x01,
11765 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
11766 0x08, 0x12, 0x02, 0x4a,
11767 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4,
11768 0x5d, 0xf0, 0x02, 0xfa,
11769 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01,
11770 0x68, 0x01, 0x6a, 0x01,
11771 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
11772 0x06, 0x13, 0x4c, 0x1c,
11773 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00,
11774 0x0f, 0x00, 0x47, 0x00,
11775 0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c,
11776 0x4e, 0x1c, 0x10, 0x44,
11777 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
11778 0x05, 0x00, 0x34, 0x00,
11779 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b,
11780 0x42, 0x0c, 0x12, 0x0f,
11781 0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48,
11782 0x00, 0x4e, 0x42, 0x54,
11783 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
11784 0x59, 0xf0, 0xb8, 0xf0,
11785 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00,
11786 0x19, 0x00, 0x33, 0x00,
11787 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00,
11788 0xe7, 0x00, 0xe2, 0x03,
11789 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
11790 0x12, 0x13, 0x24, 0x14,
11791 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c,
11792 0x36, 0x1c, 0x08, 0x44,
11793 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54,
11794 0x3a, 0x55, 0x83, 0x55,
11795 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
11796 0x0c, 0xf0, 0x04, 0xf8,
11797 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00,
11798 0xa8, 0x00, 0xaa, 0x00,
11799 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01,
11800 0xc4, 0x01, 0xc6, 0x01,
11801 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
11802 0x68, 0x08, 0x69, 0x08,
11803 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10,
11804 0xed, 0x10, 0xf1, 0x10,
11805 0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13,
11806 0x1e, 0x13, 0x46, 0x14,
11807 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
11808 0xca, 0x18, 0xe6, 0x19,
11809 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c,
11810 0xf0, 0x2b, 0x02, 0xfe,
11811 0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6,
11812 0xfe, 0x84, 0x01, 0xff,
11813 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
11814 0x00, 0xfe, 0x57, 0x24,
11815 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09,
11816 0x00, 0x00, 0xff, 0x08,
11817 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
11818 0xff, 0xff, 0xff, 0x11,
11819 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
11820 0xfe, 0x04, 0xf7, 0xd6,
11821 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99,
11822 0x0a, 0x42, 0x2c, 0xfe,
11823 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0,
11824 0xfe, 0xf4, 0x01, 0xfe,
11825 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
11826 0x02, 0xfe, 0xc8, 0x0d,
11827 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
11828 0x1c, 0x03, 0xfe, 0xa6,
11829 0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48,
11830 0xf0, 0xfe, 0x8a, 0x02,
11831 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
11832 0xfe, 0x46, 0xf0, 0xfe,
11833 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
11834 0x48, 0x02, 0xfe, 0x44,
11835 0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a,
11836 0xaa, 0x18, 0x06, 0x14,
11837 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
11838 0x1e, 0x1c, 0xfe, 0xe9,
11839 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce,
11840 0x09, 0x70, 0x01, 0xa8,
11841 0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70,
11842 0x01, 0x87, 0xfe, 0xbd,
11843 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
11844 0x58, 0x1c, 0x18, 0x06,
11845 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23,
11846 0xfe, 0x98, 0x02, 0xfe,
11847 0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2,
11848 0x01, 0xfe, 0x48, 0x10,
11849 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
11850 0x69, 0x10, 0x18, 0x06,
11851 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05,
11852 0xf6, 0xce, 0x01, 0xfe,
11853 0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe,
11854 0x82, 0x16, 0x02, 0x2b,
11855 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
11856 0xfe, 0x41, 0x58, 0x09,
11857 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe,
11858 0x82, 0x16, 0x02, 0x2b,
11859 0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43,
11860 0xfe, 0x77, 0x57, 0xfe,
11861 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
11862 0xfe, 0x40, 0x1c, 0x1c,
11863 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48,
11864 0x03, 0xfe, 0x11, 0xf0,
11865 0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10,
11866 0xfe, 0x11, 0x00, 0x02,
11867 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
11868 0x21, 0x22, 0xa3, 0xb7,
11869 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16,
11870 0x12, 0xd1, 0x1c, 0xd9,
11871 0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12,
11872 0xfe, 0xe4, 0x00, 0x27,
11873 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
11874 0x06, 0xf0, 0xfe, 0xc8,
11875 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03,
11876 0x70, 0x28, 0x17, 0xfe,
11877 0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8,
11878 0xf9, 0x2c, 0x99, 0x19,
11879 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
11880 0x74, 0x01, 0xaf, 0x8c,
11881 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e,
11882 0x8d, 0x51, 0x64, 0x79,
11883 0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b,
11884 0xfe, 0x6a, 0x02, 0x02,
11885 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
11886 0xfe, 0x3c, 0x04, 0x3b,
11887 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02,
11888 0x00, 0x10, 0x01, 0x0b,
11889 0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde,
11890 0xfe, 0x4c, 0x44, 0xfe,
11891 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
11892 0xda, 0x4f, 0x79, 0x2a,
11893 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b,
11894 0xfe, 0x2a, 0x13, 0x32,
11895 0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c,
11896 0x54, 0x6b, 0xda, 0xfe,
11897 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
11898 0x08, 0x13, 0x32, 0x07,
11899 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d,
11900 0x08, 0x05, 0x06, 0x4d,
11901 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24,
11902 0x2d, 0x12, 0xfe, 0xe6,
11903 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
11904 0x02, 0x2b, 0xfe, 0x42,
11905 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
11906 0xfe, 0x87, 0x80, 0xfe,
11907 0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80,
11908 0x07, 0x19, 0xfe, 0x7c,
11909 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
11910 0x17, 0xfe, 0x90, 0x05,
11911 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe,
11912 0xa0, 0x00, 0x28, 0xfe,
11913 0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c,
11914 0x34, 0xfe, 0x89, 0x48,
11915 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
11916 0x12, 0xfe, 0xe3, 0x00,
11917 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
11918 0x70, 0x05, 0x88, 0x25,
11919 0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe,
11920 0x09, 0x48, 0xff, 0x02,
11921 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
11922 0x08, 0x53, 0x05, 0xcb,
11923 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08,
11924 0x05, 0x1b, 0xfe, 0x22,
11925 0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe,
11926 0x0d, 0x00, 0x01, 0x36,
11927 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
11928 0x03, 0x5c, 0x28, 0xfe,
11929 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53,
11930 0x05, 0x1f, 0xfe, 0x02,
11931 0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5,
11932 0x01, 0x4b, 0x12, 0xfe,
11933 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
11934 0x12, 0x03, 0x45, 0x28,
11935 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe,
11936 0x43, 0x48, 0xc4, 0xcc,
11937 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4,
11938 0x6e, 0x41, 0x01, 0xb2,
11939 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
11940 0xfe, 0xcc, 0x15, 0x1d,
11941 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03,
11942 0x45, 0xc1, 0x0c, 0x45,
11943 0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe,
11944 0xe2, 0x00, 0x27, 0xdb,
11945 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
11946 0xfe, 0x06, 0xf0, 0xfe,
11947 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12,
11948 0x16, 0x19, 0x01, 0x0b,
11949 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
11950 0xfe, 0x99, 0xa4, 0x01,
11951 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
11952 0x12, 0x08, 0x05, 0x1a,
11953 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
11954 0x0b, 0x16, 0x00, 0x01,
11955 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02,
11956 0xe2, 0x6c, 0x58, 0xbe,
11957 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
11958 0xfe, 0x09, 0x6f, 0xba,
11959 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27,
11960 0xfe, 0x54, 0x07, 0x1c,
11961 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c,
11962 0x07, 0x02, 0x24, 0x01,
11963 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
11964 0x2c, 0x90, 0xfe, 0xae,
11965 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a,
11966 0x37, 0x22, 0x20, 0x07,
11967 0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a,
11968 0xfe, 0x06, 0x10, 0xfe,
11969 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
11970 0x37, 0x01, 0xb3, 0xb8,
11971 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a,
11972 0x50, 0xfe, 0x44, 0x51,
11973 0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e,
11974 0x14, 0x5f, 0xfe, 0x0c,
11975 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
11976 0x14, 0x3e, 0xfe, 0x4a,
11977 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
11978 0x90, 0x0c, 0x60, 0x14,
11979 0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62,
11980 0xfe, 0x44, 0x90, 0xfe,
11981 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
11982 0x0c, 0x5e, 0x14, 0x5f,
11983 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e,
11984 0x14, 0x3c, 0x21, 0x0c,
11985 0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11,
11986 0x27, 0xdd, 0xfe, 0x9e,
11987 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
11988 0x9a, 0x08, 0xc6, 0xfe,
11989 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08,
11990 0x95, 0x86, 0x02, 0x24,
11991 0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05,
11992 0x06, 0xfe, 0x10, 0x12,
11993 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
11994 0x1c, 0x02, 0xfe, 0x18,
11995 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe,
11996 0x2c, 0x1c, 0xfe, 0xaa,
11997 0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe,
11998 0xde, 0x09, 0xfe, 0xb7,
11999 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
12000 0xfe, 0xf1, 0x18, 0xfe,
12001 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe,
12002 0x14, 0x59, 0xfe, 0x95,
12003 0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0,
12004 0xfe, 0xf0, 0x08, 0xb5,
12005 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
12006 0x0b, 0xb6, 0xfe, 0xbf,
12007 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c,
12008 0x12, 0xc2, 0xfe, 0xd2,
12009 0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e,
12010 0x06, 0x17, 0x85, 0xc5,
12011 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
12012 0x9d, 0x01, 0x36, 0x10,
12013 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe,
12014 0x98, 0x80, 0xfe, 0x19,
12015 0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18,
12016 0xfe, 0x44, 0x54, 0xbe,
12017 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
12018 0x02, 0x4a, 0x08, 0x05,
12019 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e,
12020 0x9c, 0x3c, 0xfe, 0x6c,
12021 0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f,
12022 0x3b, 0x40, 0x03, 0x49,
12023 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
12024 0x8f, 0xfe, 0xe3, 0x54,
12025 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe,
12026 0xda, 0x09, 0xfe, 0x8b,
12027 0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa,
12028 0x0a, 0x3a, 0x49, 0x3b,
12029 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
12030 0xad, 0xfe, 0x01, 0x59,
12031 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a,
12032 0x49, 0x8f, 0xfe, 0xe3,
12033 0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02,
12034 0x4a, 0x3a, 0x49, 0x3b,
12035 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
12036 0x02, 0x4a, 0x08, 0x05,
12037 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62,
12038 0xb7, 0xfe, 0x03, 0xa1,
12039 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
12040 0xfe, 0x86, 0x91, 0x6a,
12041 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
12042 0x61, 0x0c, 0x7f, 0x14,
12043 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62,
12044 0x9b, 0x2e, 0x9c, 0x3c,
12045 0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05,
12046 0xfa, 0x3c, 0x01, 0xef,
12047 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
12048 0xe4, 0x08, 0x05, 0x1f,
12049 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37,
12050 0x03, 0x5e, 0x29, 0x5f,
12051 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe,
12052 0xf4, 0x09, 0x08, 0x05,
12053 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
12054 0x81, 0x50, 0xfe, 0x10,
12055 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe,
12056 0x08, 0x09, 0x12, 0xa6,
12057 0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe,
12058 0x08, 0x09, 0xfe, 0x0c,
12059 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
12060 0x08, 0x05, 0x0a, 0xfe,
12061 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1,
12062 0xf0, 0xe2, 0x15, 0x7e,
12063 0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19,
12064 0x57, 0x3d, 0xfe, 0xed,
12065 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
12066 0x00, 0xff, 0x35, 0xfe,
12067 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18,
12068 0x1e, 0x19, 0x8a, 0x03,
12069 0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65,
12070 0xfe, 0xd1, 0xf0, 0xfe,
12071 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
12072 0x10, 0xfe, 0xce, 0xf0,
12073 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b,
12074 0x10, 0xfe, 0x22, 0x00,
12075 0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00,
12076 0x02, 0x65, 0xfe, 0xd0,
12077 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
12078 0x0b, 0x10, 0x58, 0xfe,
12079 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe,
12080 0x12, 0x00, 0x2c, 0x0f,
12081 0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14,
12082 0x0c, 0xbc, 0x17, 0x34,
12083 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
12084 0x0c, 0x1c, 0x34, 0x94,
12085 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01,
12086 0x4b, 0xfe, 0xdb, 0x10,
12087 0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe,
12088 0x89, 0xf0, 0x24, 0x33,
12089 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
12090 0x33, 0x31, 0xdf, 0xbc,
12091 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49,
12092 0x17, 0xfe, 0x2c, 0x0d,
12093 0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54,
12094 0x12, 0x55, 0xfe, 0x28,
12095 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
12096 0x44, 0xfe, 0x28, 0x00,
12097 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26,
12098 0x0f, 0x64, 0x12, 0x2f,
12099 0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44,
12100 0x0a, 0xfe, 0xb4, 0x10,
12101 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
12102 0xfe, 0x34, 0x46, 0xac,
12103 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a,
12104 0x37, 0x01, 0xf5, 0x01,
12105 0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02,
12106 0xfe, 0x2e, 0x03, 0x08,
12107 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
12108 0x1a, 0xfe, 0x58, 0x12,
12109 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
12110 0xfe, 0x50, 0x0d, 0xfe,
12111 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37,
12112 0xfe, 0xa9, 0x10, 0x10,
12113 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
12114 0xfe, 0x13, 0x00, 0xfe,
12115 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe,
12116 0x24, 0x00, 0x8c, 0xb5,
12117 0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a,
12118 0xfe, 0x9d, 0x41, 0xfe,
12119 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
12120 0xb4, 0x15, 0xfe, 0x31,
12121 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06,
12122 0xec, 0xd0, 0xfc, 0x44,
12123 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47,
12124 0x4b, 0x91, 0xfe, 0x75,
12125 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
12126 0x0e, 0xfe, 0x44, 0x48,
12127 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41,
12128 0xfe, 0x41, 0x58, 0x09,
12129 0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe,
12130 0x2e, 0x03, 0x09, 0x5d,
12131 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
12132 0xce, 0x47, 0xfe, 0xad,
12133 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13,
12134 0x59, 0x13, 0x9f, 0x13,
12135 0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe,
12136 0xe0, 0x0e, 0x0f, 0x06,
12137 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
12138 0x3a, 0x01, 0x56, 0xfe,
12139 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec,
12140 0x20, 0x4f, 0xfe, 0x05,
12141 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe,
12142 0x48, 0xf4, 0x0d, 0xfe,
12143 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
12144 0x15, 0x1a, 0x39, 0xa0,
12145 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff,
12146 0x0c, 0xfe, 0x60, 0x01,
12147 0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25,
12148 0x06, 0x13, 0x2f, 0x12,
12149 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
12150 0x22, 0x9f, 0xb7, 0x13,
12151 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39,
12152 0xa0, 0xb4, 0xfe, 0xd9,
12153 0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04,
12154 0xc3, 0xfe, 0x03, 0xdc,
12155 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
12156 0xfe, 0x00, 0xcc, 0x04,
12157 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13,
12158 0xfe, 0x1c, 0x80, 0x07,
12159 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae,
12160 0xfe, 0x0c, 0x90, 0xfe,
12161 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
12162 0x0a, 0xfe, 0x3c, 0x50,
12163 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4,
12164 0x16, 0x08, 0x05, 0x1b,
12165 0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58,
12166 0xfe, 0x2c, 0x13, 0x01,
12167 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
12168 0x0c, 0xfe, 0x64, 0x01,
12169 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03,
12170 0x80, 0x8d, 0xfe, 0x01,
12171 0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64,
12172 0x22, 0x20, 0xfb, 0x79,
12173 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
12174 0x03, 0xfe, 0xae, 0x00,
12175
12176 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe,
12177 0xb2, 0x00, 0xfe, 0x09,
12178 0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c,
12179 0x45, 0x0f, 0x46, 0x52,
12180 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
12181 0x0f, 0x44, 0x11, 0x0f,
12182 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4,
12183 0x25, 0x11, 0x13, 0x20,
12184 0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14,
12185 0x56, 0xfe, 0xd6, 0xf0,
12186 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
12187 0x18, 0x1c, 0x04, 0x42,
12188 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe,
12189 0xf5, 0x13, 0x04, 0x01,
12190 0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
12191 0x13, 0x32, 0x07, 0x2f,
12192 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
12193 0x41, 0x48, 0xfe, 0x45,
12194 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78,
12195 0x07, 0x11, 0xac, 0x09,
12196 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07,
12197 0x82, 0x4e, 0xfe, 0x14,
12198 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
12199 0xfe, 0x01, 0xec, 0xa2,
12200 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79,
12201 0x2a, 0x01, 0xe3, 0xfe,
12202 0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a,
12203 0xfe, 0x48, 0x12, 0x07,
12204 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
12205 0xfe, 0x32, 0x12, 0x07,
12206 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07,
12207 0x1f, 0xfe, 0x12, 0x12,
12208 0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b,
12209 0x94, 0x4b, 0x04, 0x2d,
12210 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
12211 0x32, 0x07, 0xa6, 0xfe,
12212 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05,
12213 0x5a, 0xfe, 0x72, 0x12,
12214 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62,
12215 0xfe, 0x26, 0x13, 0x03,
12216 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
12217 0x0c, 0x7f, 0x0c, 0x80,
12218 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c,
12219 0x3c, 0xfe, 0x04, 0x55,
12220 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe,
12221 0x91, 0x10, 0x03, 0x3f,
12222 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
12223 0x88, 0x9b, 0x2e, 0x9c,
12224 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
12225 0x56, 0x0c, 0x5e, 0x14,
12226 0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40,
12227 0x03, 0x60, 0x29, 0x61,
12228 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
12229 0x50, 0xfe, 0xc6, 0x50,
12230 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d,
12231 0x29, 0x3e, 0xfe, 0x40,
12232 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72,
12233 0x2d, 0x01, 0x0b, 0x1d,
12234 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
12235 0x72, 0x01, 0xaf, 0x1e,
12236 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe,
12237 0x0a, 0x55, 0x35, 0xfe,
12238 0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51,
12239 0x02, 0x72, 0xfe, 0x19,
12240 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
12241 0x1d, 0xe8, 0x33, 0x31,
12242 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01,
12243 0x0b, 0x1c, 0x34, 0x1d,
12244 0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8,
12245 0x33, 0x31, 0xfe, 0xe8,
12246 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
12247 0x05, 0x1f, 0x35, 0xa9,
12248 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda,
12249 0x14, 0x01, 0xaf, 0x8c,
12250 0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a,
12251 0x03, 0x45, 0x28, 0x35,
12252 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
12253 0x03, 0x5c, 0xc1, 0x0c,
12254 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02,
12255 0x89, 0x01, 0x0b, 0x1c,
12256 0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1,
12257 0xfe, 0x42, 0x58, 0xf1,
12258 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
12259 0xf4, 0x06, 0xea, 0x32,
12260 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d,
12261 0x01, 0x0b, 0x26, 0x89,
12262 0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13,
12263 0x26, 0xfe, 0xd4, 0x13,
12264 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
12265 0x13, 0x1c, 0xfe, 0xd0,
12266 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10,
12267 0x0f, 0x71, 0xff, 0x02,
12268 0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe,
12269 0x00, 0x5c, 0x04, 0x0f,
12270 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
12271 0xfe, 0x00, 0x5c, 0x04,
12272 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff,
12273 0x02, 0x00, 0x57, 0x52,
12274 0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01,
12275 0x87, 0x04, 0xfe, 0x03,
12276 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
12277 0xfe, 0x00, 0x7d, 0xfe,
12278 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e,
12279 0x14, 0x5f, 0x57, 0x3f,
12280 0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83,
12281 0x5a, 0x8d, 0x04, 0x01,
12282 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
12283 0xfe, 0x96, 0x15, 0x33,
12284 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8,
12285 0x0a, 0xfe, 0xc1, 0x59,
12286 0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13,
12287 0x21, 0x69, 0x1a, 0xee,
12288 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
12289 0x30, 0xfe, 0x78, 0x10,
12290 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae,
12291 0x98, 0xfe, 0x30, 0x00,
12292 0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed,
12293 0x98, 0xfe, 0x64, 0x00,
12294 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
12295 0x10, 0x69, 0x06, 0xfe,
12296 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00,
12297 0x18, 0x59, 0x0f, 0x06,
12298 0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe,
12299 0x43, 0xf4, 0x9f, 0xfe,
12300 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
12301 0x9e, 0xfe, 0xf3, 0x10,
12302 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00,
12303 0x17, 0xfe, 0x4d, 0xe4,
12304 0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00,
12305 0x17, 0xfe, 0x4d, 0xe4,
12306 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
12307 0xf4, 0x00, 0xe9, 0x91,
12308 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a,
12309 0x04, 0x16, 0x06, 0x01,
12310 0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01,
12311 0x0b, 0x26, 0xf3, 0x76,
12312 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
12313 0x16, 0x19, 0x01, 0x0b,
12314 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01,
12315 0x0b, 0x26, 0xb1, 0x76,
12316 0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06,
12317 0xfe, 0x48, 0x13, 0xb8,
12318 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
12319 0xec, 0xfe, 0x27, 0x01,
12320 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32,
12321 0x07, 0xfe, 0xe3, 0x00,
12322 0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b,
12323 0x22, 0xd4, 0x07, 0x06,
12324 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
12325 0x07, 0x11, 0xae, 0x09,
12326 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01,
12327 0x0e, 0x8e, 0xfe, 0x80,
12328 0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04,
12329 0x09, 0x48, 0x01, 0x0e,
12330 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
12331 0x80, 0xfe, 0x80, 0x4c,
12332 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c,
12333 0x09, 0x5d, 0x01, 0x87,
12334 0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe,
12335 0x19, 0xde, 0xfe, 0x24,
12336 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
12337 0x17, 0xad, 0x9a, 0x1b,
12338 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde,
12339 0x16, 0xfe, 0xda, 0x10,
12340 0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe,
12341 0x18, 0x58, 0x03, 0xfe,
12342 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
12343 0xf4, 0x06, 0xfe, 0x3c,
12344 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f,
12345 0x97, 0xfe, 0x38, 0x17,
12346 0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c,
12347 0x10, 0x18, 0x11, 0x75,
12348 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
12349 0x2e, 0x97, 0xfe, 0x5a,
12350 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19,
12351 0xfe, 0x98, 0xe7, 0x00,
12352 0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75,
12353 0xfe, 0x30, 0xbc, 0xfe,
12354 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
12355 0xcb, 0x97, 0xfe, 0x92,
12356 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe,
12357 0x42, 0x10, 0xfe, 0x02,
12358 0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe,
12359 0x03, 0xa1, 0xfe, 0x1d,
12360 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
12361 0x9a, 0x5b, 0x41, 0xfe,
12362 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7,
12363 0x11, 0x12, 0xfe, 0xdd,
12364 0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8,
12365 0x17, 0x15, 0x06, 0x39,
12366 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
12367 0xfe, 0x7e, 0x18, 0x1e,
12368 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef,
12369 0x12, 0xfe, 0xe1, 0x10,
12370 0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42,
12371 0x13, 0x42, 0x92, 0x09,
12372 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
12373 0xf0, 0xfe, 0x00, 0xcc,
12374 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01,
12375 0x0e, 0xfe, 0x80, 0x4c,
12376 0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe,
12377 0x24, 0x12, 0xfe, 0x14,
12378 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
12379 0xe7, 0x0a, 0x10, 0xfe,
12380 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92,
12381 0x08, 0x54, 0x1b, 0x37,
12382 0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba,
12383 0x90, 0x3a, 0xce, 0x3b,
12384 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
12385 0x13, 0xa3, 0x04, 0x09,
12386 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49,
12387 0x44, 0x17, 0xfe, 0xe8,
12388 0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09,
12389 0x5d, 0x01, 0xa8, 0x09,
12390 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
12391 0x1c, 0x19, 0x03, 0xfe,
12392 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9,
12393 0x6b, 0xfe, 0x2e, 0x19,
12394 0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4,
12395 0xfe, 0x0b, 0x00, 0x6b,
12396 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
12397 0x08, 0x10, 0x03, 0xfe,
12398 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff,
12399 0x04, 0x68, 0x54, 0xe7,
12400 0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe,
12401 0x1a, 0xf4, 0xfe, 0x00,
12402 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
12403 0x04, 0x07, 0x7e, 0xfe,
12404 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
12405 0x07, 0x1a, 0xfe, 0x5a,
12406 0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66,
12407 0x25, 0x6d, 0xe5, 0x07,
12408 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
12409 0xa9, 0xb8, 0x04, 0x15,
12410 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe,
12411 0x40, 0x5c, 0x04, 0x1c,
12412 0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b,
12413 0xf7, 0xfe, 0x82, 0xf0,
12414 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
12415 };
12416
12417 static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
12418 static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
12419
12420 /* Microcode buffer is kept after initialization for error recovery. */
12421 static unsigned char _adv_asc38C1600_buf[] = {
12422 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
12423 0x18, 0xe4, 0x01, 0x00,
12424 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00,
12425 0x07, 0x17, 0xc0, 0x5f,
12426 0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7,
12427 0x85, 0xf0, 0x86, 0xf0,
12428 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
12429 0x98, 0x57, 0x01, 0xe6,
12430 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d,
12431 0x38, 0x54, 0x32, 0xf0,
12432 0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4,
12433 0x00, 0xe6, 0xb1, 0xf0,
12434 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
12435 0x06, 0x13, 0x0c, 0x1c,
12436 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12,
12437 0xb9, 0x54, 0x00, 0x80,
12438 0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56,
12439 0x03, 0xe6, 0x01, 0xea,
12440 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
12441 0x04, 0x13, 0xbb, 0x55,
12442 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00,
12443 0xbb, 0x00, 0xc0, 0x00,
12444 0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12,
12445 0x4c, 0x1c, 0x4e, 0x1c,
12446 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
12447 0x24, 0x01, 0x3c, 0x01,
12448 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01,
12449 0x78, 0x01, 0x7c, 0x01,
12450 0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c,
12451 0x6e, 0x1e, 0x02, 0x48,
12452 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
12453 0x03, 0xfc, 0x06, 0x00,
12454 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a,
12455 0x30, 0x1c, 0x38, 0x1c,
12456 0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea,
12457 0x5d, 0xf0, 0xa7, 0xf0,
12458 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
12459 0x33, 0x00, 0x34, 0x00,
12460 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01,
12461 0x79, 0x01, 0x3c, 0x09,
12462 0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13,
12463 0x40, 0x16, 0x50, 0x16,
12464 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
12465 0x05, 0xf0, 0x09, 0xf0,
12466 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00,
12467 0x9c, 0x00, 0xa4, 0x00,
12468 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08,
12469 0xe9, 0x09, 0x5c, 0x0c,
12470 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
12471 0x42, 0x1d, 0x08, 0x44,
12472 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54,
12473 0x83, 0x55, 0x83, 0x59,
12474 0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0,
12475 0x4b, 0xf4, 0x04, 0xf8,
12476 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
12477 0xa8, 0x00, 0xaa, 0x00,
12478 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01,
12479 0x7a, 0x01, 0x82, 0x01,
12480 0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07,
12481 0x68, 0x08, 0x10, 0x0d,
12482 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
12483 0xf3, 0x10, 0x06, 0x12,
12484 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c,
12485 0xf0, 0x35, 0x05, 0xfe,
12486 0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8,
12487 0xfe, 0x88, 0x01, 0xff,
12488 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
12489 0x00, 0xfe, 0x57, 0x24,
12490 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09,
12491 0x00, 0x00, 0xff, 0x08,
12492 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
12493 0xff, 0xff, 0xff, 0x13,
12494 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
12495 0xfe, 0x04, 0xf7, 0xe8,
12496 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d,
12497 0x0d, 0x51, 0x37, 0xfe,
12498 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0,
12499 0xfe, 0xf8, 0x01, 0xfe,
12500 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
12501 0x05, 0xfe, 0x08, 0x0f,
12502 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe,
12503 0x28, 0x1c, 0x03, 0xfe,
12504 0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe,
12505 0x48, 0xf0, 0xfe, 0x90,
12506 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
12507 0x02, 0xfe, 0x46, 0xf0,
12508 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0,
12509 0xfe, 0x4e, 0x02, 0xfe,
12510 0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c,
12511 0x0d, 0xa2, 0x1c, 0x07,
12512 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
12513 0x1c, 0xf5, 0xfe, 0x1e,
12514 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc,
12515 0xde, 0x0a, 0x81, 0x01,
12516 0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a,
12517 0x81, 0x01, 0x5c, 0xfe,
12518 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
12519 0xfe, 0x58, 0x1c, 0x1c,
12520 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02,
12521 0x2b, 0xfe, 0x9e, 0x02,
12522 0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30,
12523 0x00, 0x47, 0xb8, 0x01,
12524 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
12525 0x1a, 0x31, 0xfe, 0x69,
12526 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe,
12527 0x1e, 0x1e, 0x20, 0x2c,
12528 0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a,
12529 0x44, 0x15, 0x56, 0x51,
12530 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
12531 0x01, 0x18, 0x09, 0x00,
12532 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01,
12533 0x18, 0xfe, 0xc8, 0x54,
12534 0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60,
12535 0xfe, 0x02, 0xe8, 0x30,
12536 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
12537 0xfe, 0xe4, 0x01, 0xfe,
12538 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe,
12539 0x26, 0xf0, 0xfe, 0x66,
12540 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe,
12541 0xef, 0x10, 0xfe, 0x9f,
12542 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
12543 0x70, 0x37, 0xfe, 0x48,
12544 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26,
12545 0x21, 0xb9, 0xc7, 0x20,
12546 0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15,
12547 0xe1, 0x2a, 0xeb, 0xfe,
12548 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
12549 0x15, 0xfe, 0xe4, 0x00,
12550 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41,
12551 0xfe, 0x06, 0xf0, 0xfe,
12552 0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29,
12553 0x03, 0x81, 0x1e, 0x1b,
12554 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
12555 0xea, 0xfe, 0x46, 0x1c,
12556 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
12557 0xfe, 0x48, 0x1c, 0x75,
12558 0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a,
12559 0xe1, 0x01, 0x18, 0x77,
12560 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
12561 0x8f, 0xfe, 0x70, 0x02,
12562 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04,
12563 0x16, 0xfe, 0x4a, 0x04,
12564 0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff,
12565 0x02, 0x00, 0x10, 0x01,
12566 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
12567 0xee, 0xfe, 0x4c, 0x44,
12568 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54,
12569 0x7b, 0xec, 0x60, 0x8d,
12570 0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01,
12571 0x0c, 0x06, 0x28, 0xfe,
12572 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
12573 0x13, 0x34, 0xfe, 0x4c,
12574 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54,
12575 0x13, 0x01, 0x0c, 0x06,
12576 0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06,
12577 0x28, 0xf9, 0x1f, 0x7f,
12578 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
12579 0xfe, 0xa4, 0x0e, 0x05,
12580 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe,
12581 0x9c, 0x93, 0x3a, 0x0b,
12582 0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b,
12583 0x7d, 0x1d, 0xfe, 0x46,
12584 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
12585 0xfe, 0x87, 0x83, 0xfe,
12586 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98,
12587 0x13, 0x0f, 0xfe, 0x20,
12588 0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84,
12589 0x12, 0x01, 0x38, 0x06,
12590 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
12591 0x05, 0xd0, 0x54, 0x01,
12592 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe,
12593 0x50, 0x12, 0x5e, 0xff,
12594 0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02,
12595 0x00, 0x10, 0x2f, 0xfe,
12596 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
12597 0x38, 0xfe, 0x4a, 0xf0,
12598 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe,
12599 0x21, 0x00, 0xf1, 0x2e,
12600 0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00,
12601 0x10, 0x2f, 0xfe, 0xd0,
12602 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
12603 0x1c, 0x00, 0x4d, 0x01,
12604 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06,
12605 0x28, 0xfe, 0x24, 0x12,
12606 0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe,
12607 0x0d, 0x00, 0x01, 0x42,
12608 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
12609 0x03, 0xb6, 0x1e, 0xfe,
12610 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17,
12611 0xfe, 0x72, 0x06, 0x0a,
12612 0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56,
12613 0x19, 0x16, 0xfe, 0x68,
12614 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
12615 0x03, 0x9a, 0x1e, 0xfe,
12616 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12,
12617 0x48, 0xfe, 0x92, 0x06,
12618 0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13,
12619 0x58, 0xff, 0x02, 0x00,
12620 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
12621 0xfe, 0xea, 0x06, 0x01,
12622 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16,
12623 0xfe, 0xe0, 0x06, 0x15,
12624 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07,
12625 0x01, 0x84, 0xfe, 0xae,
12626 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
12627 0x1e, 0xfe, 0x1a, 0x12,
12628 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
12629 0x43, 0x48, 0x62, 0x80,
12630 0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24,
12631 0x36, 0xfe, 0x02, 0xf6,
12632 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
12633 0xd0, 0x0d, 0x17, 0xfe,
12634 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20,
12635 0x9e, 0x15, 0x82, 0x01,
12636 0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58,
12637 0x57, 0x10, 0xe6, 0x05,
12638 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
12639 0xfe, 0x9c, 0x32, 0x5f,
12640 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c,
12641 0xfe, 0x0a, 0xf0, 0xfe,
12642 0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08,
12643 0xaf, 0xa0, 0x05, 0x29,
12644 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
12645 0x00, 0x01, 0x08, 0x14,
12646 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08,
12647 0x14, 0x00, 0x05, 0xfe,
12648 0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06,
12649 0x12, 0xfe, 0x30, 0x13,
12650 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
12651 0x01, 0x08, 0x14, 0x00,
12652 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a,
12653 0x78, 0x4f, 0x0f, 0xfe,
12654 0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d,
12655 0x28, 0x48, 0xfe, 0x6c,
12656 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
12657 0x12, 0x53, 0x63, 0x4e,
12658 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe,
12659 0x6c, 0x08, 0xaf, 0xa0,
12660 0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24,
12661 0x05, 0xed, 0xfe, 0x9c,
12662 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
12663 0x1e, 0xfe, 0x99, 0x58,
12664 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a,
12665 0x22, 0x6b, 0x01, 0x0c,
12666 0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e,
12667 0x1e, 0x47, 0x2c, 0x7a,
12668 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
12669 0x01, 0x0c, 0x61, 0x65,
12670 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a,
12671 0x16, 0xfe, 0x08, 0x50,
12672 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10,
12673 0x01, 0xfe, 0xce, 0x1e,
12674 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
12675 0x01, 0xfe, 0xfe, 0x1e,
12676 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a,
12677 0x10, 0x01, 0x0c, 0x06,
12678 0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e,
12679 0x10, 0x6a, 0x22, 0x6b,
12680 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
12681 0xfe, 0x9f, 0x83, 0x33,
12682 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93,
12683 0x3a, 0x0b, 0xfe, 0xc6,
12684 0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d,
12685 0x01, 0xfe, 0xce, 0x1e,
12686 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
12687 0x04, 0xfe, 0xc0, 0x93,
12688 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e,
12689 0x10, 0x4b, 0x22, 0x4c,
12690 0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe,
12691 0x4e, 0x11, 0x2f, 0xfe,
12692 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
12693 0x3c, 0x37, 0x88, 0xf5,
12694 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a,
12695 0xd3, 0xfe, 0x42, 0x0a,
12696 0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0,
12697 0x05, 0x29, 0x01, 0x41,
12698 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
12699 0xfe, 0x14, 0x12, 0x01,
12700 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe,
12701 0x2e, 0x1c, 0x05, 0xfe,
12702 0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41,
12703 0xfe, 0x2c, 0x1c, 0xfe,
12704 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
12705 0x92, 0x10, 0xc4, 0xf6,
12706 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe,
12707 0xe7, 0x10, 0xfe, 0x2b,
12708 0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12,
12709 0xac, 0xfe, 0xd2, 0xf0,
12710 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
12711 0x1b, 0xbf, 0xd4, 0x5b,
12712 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75,
12713 0x5e, 0x32, 0x1f, 0x7f,
12714 0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98,
12715 0x05, 0x70, 0xfe, 0x74,
12716 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
12717 0x0f, 0x4d, 0x01, 0xfe,
12718 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06,
12719 0x0d, 0x2b, 0xfe, 0xe2,
12720 0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24,
12721 0xfe, 0x88, 0x13, 0x21,
12722 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
12723 0x83, 0x83, 0xfe, 0xc9,
12724 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04,
12725 0x91, 0x04, 0xfe, 0x84,
12726 0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93,
12727 0xfe, 0xcb, 0x57, 0x0b,
12728 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
12729 0x6a, 0x3b, 0x6b, 0x10,
12730 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30,
12731 0x20, 0x6e, 0xdb, 0x64,
12732 0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55,
12733 0xfe, 0x04, 0xfa, 0x64,
12734 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
12735 0x10, 0x98, 0x91, 0x6c,
12736 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91,
12737 0x4b, 0x7e, 0x4c, 0x01,
12738 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10,
12739 0x58, 0xfe, 0x91, 0x58,
12740 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
12741 0x1b, 0x40, 0x01, 0x0c,
12742 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f,
12743 0xfe, 0x10, 0x90, 0x04,
12744 0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93,
12745 0x79, 0x0b, 0x0e, 0xfe,
12746 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
12747 0x01, 0x0c, 0x06, 0x0d,
12748 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe,
12749 0x0c, 0x58, 0xfe, 0x8d,
12750 0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99,
12751 0x83, 0x33, 0x0b, 0x0e,
12752 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
12753 0x19, 0xfe, 0x19, 0x41,
12754 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42,
12755 0x19, 0xfe, 0x44, 0x00,
12756 0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda,
12757 0x4c, 0xfe, 0x0c, 0x51,
12758 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
12759 0x76, 0x10, 0xac, 0xfe,
12760 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03,
12761 0xe3, 0x23, 0x07, 0xfe,
12762 0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe,
12763 0xcc, 0x0c, 0x1f, 0x92,
12764 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
12765 0x0c, 0xfe, 0x3e, 0x10,
12766 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70,
12767 0xfe, 0xcb, 0xf0, 0xfe,
12768 0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe,
12769 0xf4, 0x0c, 0x19, 0x94,
12770 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
12771 0xfe, 0xcc, 0xf0, 0xef,
12772 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe,
12773 0x4e, 0x11, 0x2f, 0xfe,
12774 0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b,
12775 0x3c, 0x37, 0x88, 0xf5,
12776 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
12777 0x2f, 0xfe, 0x3e, 0x0d,
12778 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f,
12779 0xd2, 0x9f, 0xd3, 0x9f,
12780 0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4,
12781 0xc5, 0x75, 0xd7, 0x99,
12782 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
12783 0x9c, 0x2f, 0xfe, 0x8c,
12784 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe,
12785 0x42, 0x00, 0x05, 0x70,
12786 0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06,
12787 0x0d, 0xfe, 0x44, 0x13,
12788 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
12789 0xfe, 0xda, 0x0e, 0x0a,
12790 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa,
12791 0x10, 0x01, 0xfe, 0xf4,
12792 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40,
12793 0x15, 0x56, 0x01, 0x85,
12794 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
12795 0xcc, 0x10, 0x01, 0xa7,
12796 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04,
12797 0xfe, 0x99, 0x83, 0xfe,
12798 0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe,
12799 0x43, 0x00, 0xfe, 0xa2,
12800 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
12801 0x00, 0x1d, 0x40, 0x15,
12802 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05,
12803 0xfe, 0x3a, 0x03, 0x01,
12804 0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01,
12805 0x76, 0x06, 0x12, 0xfe,
12806 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
12807 0xfe, 0x9d, 0xf0, 0xfe,
12808 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01,
12809 0x0c, 0x61, 0x12, 0x44,
12810 0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f,
12811 0xfe, 0x2e, 0x10, 0x19,
12812 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
12813 0xfe, 0x41, 0x00, 0xa2,
12814 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b,
12815 0xea, 0x4f, 0xfe, 0x04,
12816 0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05,
12817 0x35, 0xfe, 0x12, 0x1c,
12818 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
12819 0xfe, 0xd4, 0x11, 0x05,
12820 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe,
12821 0xce, 0x45, 0x31, 0x51,
12822 0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03,
12823 0x67, 0xfe, 0x98, 0x56,
12824 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
12825 0x0c, 0x06, 0x28, 0xfe,
12826 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba,
12827 0xfe, 0xfa, 0x14, 0xfe,
12828 0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67,
12829 0xfe, 0xe0, 0x14, 0xfe,
12830 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
12831 0xfe, 0xad, 0x13, 0x05,
12832 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20,
12833 0xe7, 0xfe, 0x08, 0x1c,
12834 0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe,
12835 0x48, 0x55, 0xa5, 0x3b,
12836 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
12837 0xf0, 0x1a, 0x03, 0xfe,
12838 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02,
12839 0xec, 0xe7, 0x53, 0x00,
12840 0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
12841 0x01, 0xfe, 0x62, 0x1b,
12842 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
12843 0xea, 0xe7, 0x53, 0x92,
12844 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03,
12845 0xfe, 0x38, 0x01, 0x23,
12846 0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62,
12847 0x01, 0x01, 0xfe, 0x1e,
12848 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
12849 0x26, 0x02, 0x21, 0x96,
12850 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5,
12851 0xc3, 0xfe, 0xe1, 0x10,
12852 0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf,
12853 0xfe, 0x03, 0xdc, 0xfe,
12854 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
12855 0x00, 0xcc, 0x02, 0xfe,
12856 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13,
12857 0x0f, 0xfe, 0x1c, 0x80,
12858 0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13,
12859 0x0f, 0xfe, 0x1e, 0x80,
12860 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
12861 0x1d, 0x80, 0x04, 0xfe,
12862 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee,
12863 0x1e, 0xac, 0xfe, 0x14,
12864 0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e,
12865 0x1f, 0xfe, 0x30, 0xf4,
12866 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
12867 0x56, 0xfb, 0x01, 0xfe,
12868 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01,
12869 0xfe, 0x00, 0x1d, 0x15,
12870 0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe,
12871 0x22, 0x1b, 0xfe, 0x1e,
12872 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
12873 0x96, 0x90, 0x04, 0xfe,
12874 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66,
12875 0x01, 0x01, 0x0c, 0x06,
12876 0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b,
12877 0x0e, 0x77, 0xfe, 0x01,
12878 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
12879 0x21, 0x2c, 0xfe, 0x00,
12880 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe,
12881 0x06, 0x58, 0x03, 0xfe,
12882 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58,
12883 0x03, 0xfe, 0xb2, 0x00,
12884 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
12885 0x66, 0x10, 0x55, 0x10,
12886 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91,
12887 0x54, 0x2b, 0xfe, 0x88,
12888 0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe,
12889 0x91, 0x54, 0x2b, 0xfe,
12890 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
12891 0x00, 0x40, 0x8d, 0x2c,
12892 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe,
12893 0x12, 0x1c, 0x75, 0xfe,
12894 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c,
12895 0x14, 0xfe, 0x0e, 0x47,
12896 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
12897 0xa7, 0x90, 0x34, 0x60,
12898 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80,
12899 0x09, 0x56, 0xfe, 0x34,
12900 0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48,
12901 0xfe, 0x45, 0x48, 0x01,
12902 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
12903 0x09, 0x1a, 0xa5, 0x0a,
12904 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4,
12905 0xfe, 0x14, 0x56, 0xfe,
12906 0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01,
12907 0xec, 0xb8, 0xfe, 0x9e,
12908 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
12909 0xf4, 0xfe, 0xdd, 0x10,
12910 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48,
12911 0x12, 0x09, 0x0d, 0xfe,
12912 0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4,
12913 0x13, 0x09, 0xfe, 0x23,
12914 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
12915 0x24, 0xfe, 0x12, 0x12,
12916 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08,
12917 0xae, 0x41, 0x02, 0x32,
12918 0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05,
12919 0x35, 0x32, 0x01, 0x43,
12920 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
12921 0x13, 0x01, 0x0c, 0x06,
12922 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe,
12923 0xe5, 0x55, 0xb0, 0xfe,
12924 0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e,
12925 0xfe, 0xb6, 0x0e, 0x10,
12926 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
12927 0x88, 0x20, 0x6e, 0x01,
12928 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5,
12929 0x55, 0xfe, 0x04, 0xfa,
12930 0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d,
12931 0xfe, 0x40, 0x56, 0xfe,
12932 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
12933 0x44, 0x55, 0xfe, 0xe5,
12934 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10,
12935 0x68, 0x22, 0x69, 0x01,
12936 0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b,
12937 0x6b, 0xfe, 0x2c, 0x50,
12938 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
12939 0x50, 0x03, 0x68, 0x3b,
12940 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe,
12941 0x40, 0x50, 0xfe, 0xc2,
12942 0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08,
12943 0x16, 0x3d, 0x27, 0x25,
12944 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
12945 0xa6, 0x23, 0x3f, 0x1b,
12946 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c,
12947 0xfe, 0x0a, 0x55, 0x31,
12948 0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e,
12949 0x51, 0x05, 0x72, 0x01,
12950 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
12951 0x2a, 0x3c, 0x16, 0xc0,
12952 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b,
12953 0xfe, 0x66, 0x15, 0x05,
12954 0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d,
12955 0x2b, 0x3d, 0x01, 0x08,
12956 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
12957 0xb6, 0x1e, 0x83, 0x01,
12958 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46,
12959 0x07, 0x90, 0x3f, 0x01,
12960 0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13,
12961 0x01, 0x43, 0x09, 0x82,
12962 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
12963 0x05, 0x72, 0xfe, 0xc0,
12964 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e,
12965 0x32, 0x01, 0x08, 0x17,
12966 0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16,
12967 0x3d, 0x27, 0x25, 0xbd,
12968 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
12969 0xe8, 0x14, 0x01, 0xa6,
12970 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe,
12971 0x0e, 0x12, 0x01, 0x43,
12972 0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32,
12973 0x01, 0x08, 0x17, 0x73,
12974 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
12975 0x27, 0x25, 0xbd, 0x09,
12976 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe,
12977 0xb6, 0x14, 0x86, 0xa8,
12978 0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09,
12979 0x82, 0x4e, 0x05, 0x72,
12980 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
12981 0xfe, 0xc0, 0x19, 0x05,
12982 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f,
12983 0xcc, 0x01, 0x08, 0x26,
12984 0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe,
12985 0xcc, 0x15, 0x5e, 0x32,
12986 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
12987 0xad, 0x23, 0xfe, 0xff,
12988 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02,
12989 0x00, 0x57, 0x52, 0xad,
12990 0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff,
12991 0x02, 0x00, 0x57, 0x52,
12992 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
12993 0x02, 0x13, 0x58, 0xff,
12994 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01,
12995 0x5c, 0x0a, 0x55, 0x01,
12996 0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a,
12997 0xff, 0x03, 0x00, 0x54,
12998 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
12999 0x7c, 0x3a, 0x0b, 0x0e,
13000 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19,
13001 0xfe, 0x1a, 0xf7, 0x00,
13002 0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c,
13003 0xda, 0x6d, 0x02, 0xfe,
13004 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
13005 0x02, 0x01, 0xc6, 0xfe,
13006 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27,
13007 0x25, 0xbe, 0x01, 0x08,
13008 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59,
13009 0x03, 0x9a, 0x1e, 0xfe,
13010 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
13011 0x48, 0xfe, 0x08, 0x17,
13012 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26,
13013 0x17, 0x4d, 0x13, 0x07,
13014 0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1,
13015 0xff, 0x02, 0x83, 0x55,
13016 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
13017 0x17, 0x1c, 0x63, 0x13,
13018 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64,
13019 0x00, 0xb0, 0xfe, 0x80,
13020 0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10,
13021 0x53, 0x07, 0xfe, 0x60,
13022 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
13023 0x00, 0x1c, 0x95, 0x13,
13024 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3,
13025 0xfe, 0x43, 0xf4, 0x96,
13026 0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43,
13027 0xf4, 0x94, 0xf6, 0x8b,
13028 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
13029 0xda, 0x17, 0x62, 0x49,
13030 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80,
13031 0x71, 0x50, 0x26, 0xfe,
13032 0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3,
13033 0x58, 0x02, 0x50, 0x13,
13034 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
13035 0x25, 0xbe, 0xfe, 0x03,
13036 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9,
13037 0x0a, 0x01, 0x08, 0x16,
13038 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01,
13039 0x01, 0x08, 0x16, 0xa9,
13040 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
13041 0x08, 0x16, 0xa9, 0x27,
13042 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83,
13043 0x01, 0x38, 0x06, 0x24,
13044 0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1,
13045 0x78, 0x03, 0x9a, 0x1e,
13046 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
13047 0xfe, 0x40, 0x5a, 0x23,
13048 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c,
13049 0x80, 0x48, 0xfe, 0xaa,
13050 0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01,
13051 0xfe, 0xac, 0x1d, 0xfe,
13052 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
13053 0x43, 0x48, 0x2d, 0x93,
13054 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4,
13055 0x36, 0xfe, 0x34, 0xf4,
13056 0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe,
13057 0x28, 0x10, 0xfe, 0xc0,
13058 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
13059 0x18, 0x45, 0xfe, 0x1c,
13060 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c,
13061 0x19, 0xfe, 0x04, 0xf4,
13062 0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d,
13063 0x21, 0xfe, 0x7f, 0x01,
13064 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
13065 0x7e, 0x01, 0xfe, 0xc8,
13066 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa,
13067 0x21, 0xfe, 0x81, 0x01,
13068 0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50,
13069 0x13, 0x0d, 0x02, 0x14,
13070 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
13071 0xfe, 0x82, 0x19, 0x14,
13072 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01,
13073 0x08, 0x02, 0x14, 0x07,
13074 0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07,
13075 0x01, 0x08, 0x17, 0xc1,
13076 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
13077 0x08, 0x02, 0x50, 0x02,
13078 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74,
13079 0x14, 0x12, 0x01, 0x08,
13080 0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01,
13081 0x08, 0x17, 0x74, 0xfe,
13082 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
13083 0x74, 0x5f, 0xcc, 0x01,
13084 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4,
13085 0xfe, 0x49, 0xf4, 0x00,
13086 0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff,
13087 0x02, 0x00, 0x10, 0x2f,
13088 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
13089 0x16, 0xfe, 0x64, 0x1a,
13090 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c,
13091 0x61, 0x07, 0x44, 0x02,
13092 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12,
13093 0x13, 0x0a, 0x9d, 0x01,
13094 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
13095 0xfe, 0x80, 0xe7, 0x1a,
13096 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02,
13097 0x0a, 0x5a, 0x01, 0x18,
13098 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe,
13099 0x7e, 0x1e, 0xfe, 0x80,
13100 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
13101 0xfe, 0x80, 0x4c, 0x0a,
13102 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf,
13103 0xfe, 0x19, 0xde, 0xfe,
13104 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe,
13105 0x2a, 0x1c, 0xfa, 0xb3,
13106 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
13107 0xf4, 0x1a, 0xfe, 0xfa,
13108 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24,
13109 0xfe, 0x18, 0x58, 0x03,
13110 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f,
13111 0xfe, 0x30, 0xf4, 0x07,
13112 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
13113 0xf7, 0x24, 0xb1, 0xfe,
13114 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b,
13115 0xfe, 0xba, 0x10, 0x1c,
13116 0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
13117 0x1d, 0xf7, 0x54, 0xb1,
13118 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
13119 0xaf, 0x19, 0xfe, 0x98,
13120 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c,
13121 0x1a, 0x87, 0x8b, 0x0f,
13122 0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58,
13123 0xfe, 0x32, 0x90, 0x04,
13124 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
13125 0x7c, 0x12, 0xfe, 0x0f,
13126 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14,
13127 0x31, 0x02, 0xc9, 0x2b,
13128 0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe,
13129 0x6a, 0xfe, 0x19, 0xfe,
13130 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
13131 0x1b, 0xfe, 0x36, 0x14,
13132 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19,
13133 0xfe, 0x80, 0xe7, 0x1a,
13134 0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a,
13135 0x30, 0xfe, 0x12, 0x45,
13136 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
13137 0x39, 0xf0, 0x75, 0x26,
13138 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03,
13139 0xe3, 0x23, 0x07, 0xfe,
13140 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09,
13141 0x56, 0xfe, 0x3c, 0x13,
13142 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
13143 0x01, 0x18, 0xcb, 0xfe,
13144 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16,
13145 0xfe, 0x00, 0xcc, 0xcb,
13146 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18,
13147 0xfe, 0x80, 0x4c, 0x01,
13148 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
13149 0x12, 0xfe, 0x14, 0x56,
13150 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7,
13151 0x0d, 0x19, 0xfe, 0x15,
13152 0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06,
13153 0x83, 0xfe, 0x18, 0x80,
13154 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
13155 0x90, 0xfe, 0xba, 0x90,
13156 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02,
13157 0x21, 0xb9, 0x88, 0x20,
13158 0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01,
13159 0x18, 0xfe, 0x49, 0x44,
13160 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
13161 0x1a, 0xa4, 0x0a, 0x67,
13162 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4,
13163 0x1d, 0x7b, 0xfe, 0x52,
13164 0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe,
13165 0x4e, 0xe4, 0xdd, 0x7b,
13166 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
13167 0xfe, 0x4e, 0xe4, 0xfe,
13168 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24,
13169 0xfe, 0x08, 0x10, 0x03,
13170 0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04,
13171 0x68, 0x54, 0xfe, 0xf1,
13172 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
13173 0xfe, 0x1a, 0xf4, 0xfe,
13174 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02,
13175 0x09, 0x92, 0xfe, 0x5a,
13176 0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe,
13177 0x5a, 0xf0, 0xfe, 0xc8,
13178 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
13179 0x1a, 0x10, 0x09, 0x0d,
13180 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02,
13181 0x1f, 0x93, 0x01, 0x42,
13182 0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e,
13183 0xfe, 0x14, 0xf0, 0x08,
13184 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
13185 0xfe, 0x82, 0xf0, 0xfe,
13186 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e,
13187 0x02, 0x0f, 0xfe, 0x18,
13188 0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02,
13189 0x80, 0x04, 0xfe, 0x82,
13190 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
13191 0x83, 0x33, 0x0b, 0x0e,
13192 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e,
13193 0x02, 0x0f, 0xfe, 0x04,
13194 0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80,
13195 0x80, 0x04, 0xfe, 0x80,
13196 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
13197 0xfe, 0x99, 0x83, 0xfe,
13198 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86,
13199 0x83, 0xfe, 0xce, 0x47,
13200 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a,
13201 0x0b, 0x0e, 0x02, 0x0f,
13202 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13203 0xfe, 0x08, 0x90, 0x04,
13204 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04,
13205 0xfe, 0x8a, 0x93, 0x79,
13206 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a,
13207 0x0b, 0x0e, 0x02, 0x0f,
13208 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13209 0xfe, 0x3c, 0x90, 0x04,
13210 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80,
13211 0x04, 0xfe, 0x83, 0x83,
13212 0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
13213 };
13214
13215 static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
13216 static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
13217
13218 /* a_init.c */
13219 /*
13220 * EEPROM Configuration.
13221 *
13222 * All drivers should use this structure to set the default EEPROM
13223 * configuration. The BIOS now uses this structure when it is built.
13224 * Additional structure information can be found in a_condor.h where
13225 * the structure is defined.
13226 *
13227 * The *_Field_IsChar structs are needed to correct for endianness.
13228 * These values are read from the board 16 bits at a time directly
13229 * into the structs. Because some fields are char, the values will be
13230 * in the wrong order. The *_Field_IsChar tells when to flip the
13231 * bytes. Data read and written to PCI memory is automatically swapped
13232 * on big-endian platforms so char fields read as words are actually being
13233 * unswapped on big-endian platforms.
13234 */
13235 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
13236 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
13237 0x0000, /* cfg_msw */
13238 0xFFFF, /* disc_enable */
13239 0xFFFF, /* wdtr_able */
13240 0xFFFF, /* sdtr_able */
13241 0xFFFF, /* start_motor */
13242 0xFFFF, /* tagqng_able */
13243 0xFFFF, /* bios_scan */
13244 0, /* scam_tolerant */
13245 7, /* adapter_scsi_id */
13246 0, /* bios_boot_delay */
13247 3, /* scsi_reset_delay */
13248 0, /* bios_id_lun */
13249 0, /* termination */
13250 0, /* reserved1 */
13251 0xFFE7, /* bios_ctrl */
13252 0xFFFF, /* ultra_able */
13253 0, /* reserved2 */
13254 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
13255 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13256 0, /* dvc_cntl */
13257 0, /* bug_fix */
13258 0, /* serial_number_word1 */
13259 0, /* serial_number_word2 */
13260 0, /* serial_number_word3 */
13261 0, /* check_sum */
13262 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13263 , /* oem_name[16] */
13264 0, /* dvc_err_code */
13265 0, /* adv_err_code */
13266 0, /* adv_err_addr */
13267 0, /* saved_dvc_err_code */
13268 0, /* saved_adv_err_code */
13269 0, /* saved_adv_err_addr */
13270 0 /* num_of_err */
13271 };
13272
13273 static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
13274 0, /* cfg_lsw */
13275 0, /* cfg_msw */
13276 0, /* -disc_enable */
13277 0, /* wdtr_able */
13278 0, /* sdtr_able */
13279 0, /* start_motor */
13280 0, /* tagqng_able */
13281 0, /* bios_scan */
13282 0, /* scam_tolerant */
13283 1, /* adapter_scsi_id */
13284 1, /* bios_boot_delay */
13285 1, /* scsi_reset_delay */
13286 1, /* bios_id_lun */
13287 1, /* termination */
13288 1, /* reserved1 */
13289 0, /* bios_ctrl */
13290 0, /* ultra_able */
13291 0, /* reserved2 */
13292 1, /* max_host_qng */
13293 1, /* max_dvc_qng */
13294 0, /* dvc_cntl */
13295 0, /* bug_fix */
13296 0, /* serial_number_word1 */
13297 0, /* serial_number_word2 */
13298 0, /* serial_number_word3 */
13299 0, /* check_sum */
13300 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13301 , /* oem_name[16] */
13302 0, /* dvc_err_code */
13303 0, /* adv_err_code */
13304 0, /* adv_err_addr */
13305 0, /* saved_dvc_err_code */
13306 0, /* saved_adv_err_code */
13307 0, /* saved_adv_err_addr */
13308 0 /* num_of_err */
13309 };
13310
13311 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
13312 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13313 0x0000, /* 01 cfg_msw */
13314 0xFFFF, /* 02 disc_enable */
13315 0xFFFF, /* 03 wdtr_able */
13316 0x4444, /* 04 sdtr_speed1 */
13317 0xFFFF, /* 05 start_motor */
13318 0xFFFF, /* 06 tagqng_able */
13319 0xFFFF, /* 07 bios_scan */
13320 0, /* 08 scam_tolerant */
13321 7, /* 09 adapter_scsi_id */
13322 0, /* bios_boot_delay */
13323 3, /* 10 scsi_reset_delay */
13324 0, /* bios_id_lun */
13325 0, /* 11 termination_se */
13326 0, /* termination_lvd */
13327 0xFFE7, /* 12 bios_ctrl */
13328 0x4444, /* 13 sdtr_speed2 */
13329 0x4444, /* 14 sdtr_speed3 */
13330 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
13331 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13332 0, /* 16 dvc_cntl */
13333 0x4444, /* 17 sdtr_speed4 */
13334 0, /* 18 serial_number_word1 */
13335 0, /* 19 serial_number_word2 */
13336 0, /* 20 serial_number_word3 */
13337 0, /* 21 check_sum */
13338 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13339 , /* 22-29 oem_name[16] */
13340 0, /* 30 dvc_err_code */
13341 0, /* 31 adv_err_code */
13342 0, /* 32 adv_err_addr */
13343 0, /* 33 saved_dvc_err_code */
13344 0, /* 34 saved_adv_err_code */
13345 0, /* 35 saved_adv_err_addr */
13346 0, /* 36 reserved */
13347 0, /* 37 reserved */
13348 0, /* 38 reserved */
13349 0, /* 39 reserved */
13350 0, /* 40 reserved */
13351 0, /* 41 reserved */
13352 0, /* 42 reserved */
13353 0, /* 43 reserved */
13354 0, /* 44 reserved */
13355 0, /* 45 reserved */
13356 0, /* 46 reserved */
13357 0, /* 47 reserved */
13358 0, /* 48 reserved */
13359 0, /* 49 reserved */
13360 0, /* 50 reserved */
13361 0, /* 51 reserved */
13362 0, /* 52 reserved */
13363 0, /* 53 reserved */
13364 0, /* 54 reserved */
13365 0, /* 55 reserved */
13366 0, /* 56 cisptr_lsw */
13367 0, /* 57 cisprt_msw */
13368 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
13369 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
13370 0, /* 60 reserved */
13371 0, /* 61 reserved */
13372 0, /* 62 reserved */
13373 0 /* 63 reserved */
13374 };
13375
13376 static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
13377 0, /* 00 cfg_lsw */
13378 0, /* 01 cfg_msw */
13379 0, /* 02 disc_enable */
13380 0, /* 03 wdtr_able */
13381 0, /* 04 sdtr_speed1 */
13382 0, /* 05 start_motor */
13383 0, /* 06 tagqng_able */
13384 0, /* 07 bios_scan */
13385 0, /* 08 scam_tolerant */
13386 1, /* 09 adapter_scsi_id */
13387 1, /* bios_boot_delay */
13388 1, /* 10 scsi_reset_delay */
13389 1, /* bios_id_lun */
13390 1, /* 11 termination_se */
13391 1, /* termination_lvd */
13392 0, /* 12 bios_ctrl */
13393 0, /* 13 sdtr_speed2 */
13394 0, /* 14 sdtr_speed3 */
13395 1, /* 15 max_host_qng */
13396 1, /* max_dvc_qng */
13397 0, /* 16 dvc_cntl */
13398 0, /* 17 sdtr_speed4 */
13399 0, /* 18 serial_number_word1 */
13400 0, /* 19 serial_number_word2 */
13401 0, /* 20 serial_number_word3 */
13402 0, /* 21 check_sum */
13403 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13404 , /* 22-29 oem_name[16] */
13405 0, /* 30 dvc_err_code */
13406 0, /* 31 adv_err_code */
13407 0, /* 32 adv_err_addr */
13408 0, /* 33 saved_dvc_err_code */
13409 0, /* 34 saved_adv_err_code */
13410 0, /* 35 saved_adv_err_addr */
13411 0, /* 36 reserved */
13412 0, /* 37 reserved */
13413 0, /* 38 reserved */
13414 0, /* 39 reserved */
13415 0, /* 40 reserved */
13416 0, /* 41 reserved */
13417 0, /* 42 reserved */
13418 0, /* 43 reserved */
13419 0, /* 44 reserved */
13420 0, /* 45 reserved */
13421 0, /* 46 reserved */
13422 0, /* 47 reserved */
13423 0, /* 48 reserved */
13424 0, /* 49 reserved */
13425 0, /* 50 reserved */
13426 0, /* 51 reserved */
13427 0, /* 52 reserved */
13428 0, /* 53 reserved */
13429 0, /* 54 reserved */
13430 0, /* 55 reserved */
13431 0, /* 56 cisptr_lsw */
13432 0, /* 57 cisprt_msw */
13433 0, /* 58 subsysvid */
13434 0, /* 59 subsysid */
13435 0, /* 60 reserved */
13436 0, /* 61 reserved */
13437 0, /* 62 reserved */
13438 0 /* 63 reserved */
13439 };
13440
13441 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
13442 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13443 0x0000, /* 01 cfg_msw */
13444 0xFFFF, /* 02 disc_enable */
13445 0xFFFF, /* 03 wdtr_able */
13446 0x5555, /* 04 sdtr_speed1 */
13447 0xFFFF, /* 05 start_motor */
13448 0xFFFF, /* 06 tagqng_able */
13449 0xFFFF, /* 07 bios_scan */
13450 0, /* 08 scam_tolerant */
13451 7, /* 09 adapter_scsi_id */
13452 0, /* bios_boot_delay */
13453 3, /* 10 scsi_reset_delay */
13454 0, /* bios_id_lun */
13455 0, /* 11 termination_se */
13456 0, /* termination_lvd */
13457 0xFFE7, /* 12 bios_ctrl */
13458 0x5555, /* 13 sdtr_speed2 */
13459 0x5555, /* 14 sdtr_speed3 */
13460 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
13461 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13462 0, /* 16 dvc_cntl */
13463 0x5555, /* 17 sdtr_speed4 */
13464 0, /* 18 serial_number_word1 */
13465 0, /* 19 serial_number_word2 */
13466 0, /* 20 serial_number_word3 */
13467 0, /* 21 check_sum */
13468 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13469 , /* 22-29 oem_name[16] */
13470 0, /* 30 dvc_err_code */
13471 0, /* 31 adv_err_code */
13472 0, /* 32 adv_err_addr */
13473 0, /* 33 saved_dvc_err_code */
13474 0, /* 34 saved_adv_err_code */
13475 0, /* 35 saved_adv_err_addr */
13476 0, /* 36 reserved */
13477 0, /* 37 reserved */
13478 0, /* 38 reserved */
13479 0, /* 39 reserved */
13480 0, /* 40 reserved */
13481 0, /* 41 reserved */
13482 0, /* 42 reserved */
13483 0, /* 43 reserved */
13484 0, /* 44 reserved */
13485 0, /* 45 reserved */
13486 0, /* 46 reserved */
13487 0, /* 47 reserved */
13488 0, /* 48 reserved */
13489 0, /* 49 reserved */
13490 0, /* 50 reserved */
13491 0, /* 51 reserved */
13492 0, /* 52 reserved */
13493 0, /* 53 reserved */
13494 0, /* 54 reserved */
13495 0, /* 55 reserved */
13496 0, /* 56 cisptr_lsw */
13497 0, /* 57 cisprt_msw */
13498 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
13499 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
13500 0, /* 60 reserved */
13501 0, /* 61 reserved */
13502 0, /* 62 reserved */
13503 0 /* 63 reserved */
13504 };
13505
13506 static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
13507 0, /* 00 cfg_lsw */
13508 0, /* 01 cfg_msw */
13509 0, /* 02 disc_enable */
13510 0, /* 03 wdtr_able */
13511 0, /* 04 sdtr_speed1 */
13512 0, /* 05 start_motor */
13513 0, /* 06 tagqng_able */
13514 0, /* 07 bios_scan */
13515 0, /* 08 scam_tolerant */
13516 1, /* 09 adapter_scsi_id */
13517 1, /* bios_boot_delay */
13518 1, /* 10 scsi_reset_delay */
13519 1, /* bios_id_lun */
13520 1, /* 11 termination_se */
13521 1, /* termination_lvd */
13522 0, /* 12 bios_ctrl */
13523 0, /* 13 sdtr_speed2 */
13524 0, /* 14 sdtr_speed3 */
13525 1, /* 15 max_host_qng */
13526 1, /* max_dvc_qng */
13527 0, /* 16 dvc_cntl */
13528 0, /* 17 sdtr_speed4 */
13529 0, /* 18 serial_number_word1 */
13530 0, /* 19 serial_number_word2 */
13531 0, /* 20 serial_number_word3 */
13532 0, /* 21 check_sum */
13533 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13534 , /* 22-29 oem_name[16] */
13535 0, /* 30 dvc_err_code */
13536 0, /* 31 adv_err_code */
13537 0, /* 32 adv_err_addr */
13538 0, /* 33 saved_dvc_err_code */
13539 0, /* 34 saved_adv_err_code */
13540 0, /* 35 saved_adv_err_addr */
13541 0, /* 36 reserved */
13542 0, /* 37 reserved */
13543 0, /* 38 reserved */
13544 0, /* 39 reserved */
13545 0, /* 40 reserved */
13546 0, /* 41 reserved */
13547 0, /* 42 reserved */
13548 0, /* 43 reserved */
13549 0, /* 44 reserved */
13550 0, /* 45 reserved */
13551 0, /* 46 reserved */
13552 0, /* 47 reserved */
13553 0, /* 48 reserved */
13554 0, /* 49 reserved */
13555 0, /* 50 reserved */
13556 0, /* 51 reserved */
13557 0, /* 52 reserved */
13558 0, /* 53 reserved */
13559 0, /* 54 reserved */
13560 0, /* 55 reserved */
13561 0, /* 56 cisptr_lsw */
13562 0, /* 57 cisprt_msw */
13563 0, /* 58 subsysvid */
13564 0, /* 59 subsysid */
13565 0, /* 60 reserved */
13566 0, /* 61 reserved */
13567 0, /* 62 reserved */
13568 0 /* 63 reserved */
13569 };
13570
13571 /*
13572 * Initialize the ADV_DVC_VAR structure.
13573 *
13574 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13575 *
13576 * For a non-fatal error return a warning code. If there are no warnings
13577 * then 0 is returned.
13578 */
13579 static int __devinit
13580 AdvInitGetConfig(struct pci_dev *pdev, ADV_DVC_VAR *asc_dvc)
13581 {
13582 unsigned short warn_code = 0;
13583 AdvPortAddr iop_base = asc_dvc->iop_base;
13584 u16 cmd;
13585 int status;
13586
13587 asc_dvc->err_code = 0;
13588
13589 /*
13590 * Save the state of the PCI Configuration Command Register
13591 * "Parity Error Response Control" Bit. If the bit is clear (0),
13592 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
13593 * DMA parity errors.
13594 */
13595 asc_dvc->cfg->control_flag = 0;
13596 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
13597 if ((cmd & PCI_COMMAND_PARITY) == 0)
13598 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
13599
13600 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
13601 ADV_LIB_VERSION_MINOR;
13602 asc_dvc->cfg->chip_version =
13603 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
13604
13605 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
13606 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
13607 (ushort)ADV_CHIP_ID_BYTE);
13608
13609 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
13610 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
13611 (ushort)ADV_CHIP_ID_WORD);
13612
13613 /*
13614 * Reset the chip to start and allow register writes.
13615 */
13616 if (AdvFindSignature(iop_base) == 0) {
13617 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
13618 return ADV_ERROR;
13619 } else {
13620 /*
13621 * The caller must set 'chip_type' to a valid setting.
13622 */
13623 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
13624 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
13625 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
13626 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
13627 return ADV_ERROR;
13628 }
13629
13630 /*
13631 * Reset Chip.
13632 */
13633 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13634 ADV_CTRL_REG_CMD_RESET);
13635 DvcSleepMilliSecond(100);
13636 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13637 ADV_CTRL_REG_CMD_WR_IO_REG);
13638
13639 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13640 status = AdvInitFrom38C1600EEP(asc_dvc);
13641 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13642 status = AdvInitFrom38C0800EEP(asc_dvc);
13643 } else {
13644 status = AdvInitFrom3550EEP(asc_dvc);
13645 }
13646 warn_code |= status;
13647 }
13648
13649 return warn_code;
13650 }
13651
13652 /*
13653 * Initialize the ASC-3550.
13654 *
13655 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13656 *
13657 * For a non-fatal error return a warning code. If there are no warnings
13658 * then 0 is returned.
13659 *
13660 * Needed after initialization for error recovery.
13661 */
13662 static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
13663 {
13664 AdvPortAddr iop_base;
13665 ushort warn_code;
13666 ADV_DCNT sum;
13667 int begin_addr;
13668 int end_addr;
13669 ushort code_sum;
13670 int word;
13671 int j;
13672 int adv_asc3550_expanded_size;
13673 ADV_CARR_T *carrp;
13674 ADV_DCNT contig_len;
13675 ADV_SDCNT buf_size;
13676 ADV_PADDR carr_paddr;
13677 int i;
13678 ushort scsi_cfg1;
13679 uchar tid;
13680 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
13681 ushort wdtr_able = 0, sdtr_able, tagqng_able;
13682 uchar max_cmd[ADV_MAX_TID + 1];
13683
13684 /* If there is already an error, don't continue. */
13685 if (asc_dvc->err_code != 0) {
13686 return ADV_ERROR;
13687 }
13688
13689 /*
13690 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
13691 */
13692 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
13693 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
13694 return ADV_ERROR;
13695 }
13696
13697 warn_code = 0;
13698 iop_base = asc_dvc->iop_base;
13699
13700 /*
13701 * Save the RISC memory BIOS region before writing the microcode.
13702 * The BIOS may already be loaded and using its RISC LRAM region
13703 * so its region must be saved and restored.
13704 *
13705 * Note: This code makes the assumption, which is currently true,
13706 * that a chip reset does not clear RISC LRAM.
13707 */
13708 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
13709 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
13710 bios_mem[i]);
13711 }
13712
13713 /*
13714 * Save current per TID negotiated values.
13715 */
13716 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
13717 ushort bios_version, major, minor;
13718
13719 bios_version =
13720 bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
13721 major = (bios_version >> 12) & 0xF;
13722 minor = (bios_version >> 8) & 0xF;
13723 if (major < 3 || (major == 3 && minor == 1)) {
13724 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
13725 AdvReadWordLram(iop_base, 0x120, wdtr_able);
13726 } else {
13727 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
13728 }
13729 }
13730 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
13731 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
13732 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13733 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
13734 max_cmd[tid]);
13735 }
13736
13737 /*
13738 * Load the Microcode
13739 *
13740 * Write the microcode image to RISC memory starting at address 0.
13741 */
13742 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
13743 /* Assume the following compressed format of the microcode buffer:
13744 *
13745 * 254 word (508 byte) table indexed by byte code followed
13746 * by the following byte codes:
13747 *
13748 * 1-Byte Code:
13749 * 00: Emit word 0 in table.
13750 * 01: Emit word 1 in table.
13751 * .
13752 * FD: Emit word 253 in table.
13753 *
13754 * Multi-Byte Code:
13755 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
13756 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
13757 */
13758 word = 0;
13759 for (i = 253 * 2; i < _adv_asc3550_size; i++) {
13760 if (_adv_asc3550_buf[i] == 0xff) {
13761 for (j = 0; j < _adv_asc3550_buf[i + 1]; j++) {
13762 AdvWriteWordAutoIncLram(iop_base, (((ushort)
13763 _adv_asc3550_buf
13764 [i +
13765 3] << 8) |
13766 _adv_asc3550_buf
13767 [i + 2]));
13768 word++;
13769 }
13770 i += 3;
13771 } else if (_adv_asc3550_buf[i] == 0xfe) {
13772 AdvWriteWordAutoIncLram(iop_base, (((ushort)
13773 _adv_asc3550_buf[i +
13774 2]
13775 << 8) |
13776 _adv_asc3550_buf[i +
13777 1]));
13778 i += 2;
13779 word++;
13780 } else {
13781 AdvWriteWordAutoIncLram(iop_base, (((ushort)
13782 _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) | _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
13783 word++;
13784 }
13785 }
13786
13787 /*
13788 * Set 'word' for later use to clear the rest of memory and save
13789 * the expanded mcode size.
13790 */
13791 word *= 2;
13792 adv_asc3550_expanded_size = word;
13793
13794 /*
13795 * Clear the rest of ASC-3550 Internal RAM (8KB).
13796 */
13797 for (; word < ADV_3550_MEMSIZE; word += 2) {
13798 AdvWriteWordAutoIncLram(iop_base, 0);
13799 }
13800
13801 /*
13802 * Verify the microcode checksum.
13803 */
13804 sum = 0;
13805 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
13806
13807 for (word = 0; word < adv_asc3550_expanded_size; word += 2) {
13808 sum += AdvReadWordAutoIncLram(iop_base);
13809 }
13810
13811 if (sum != _adv_asc3550_chksum) {
13812 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
13813 return ADV_ERROR;
13814 }
13815
13816 /*
13817 * Restore the RISC memory BIOS region.
13818 */
13819 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
13820 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
13821 bios_mem[i]);
13822 }
13823
13824 /*
13825 * Calculate and write the microcode code checksum to the microcode
13826 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
13827 */
13828 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
13829 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
13830 code_sum = 0;
13831 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
13832 for (word = begin_addr; word < end_addr; word += 2) {
13833 code_sum += AdvReadWordAutoIncLram(iop_base);
13834 }
13835 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
13836
13837 /*
13838 * Read and save microcode version and date.
13839 */
13840 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
13841 asc_dvc->cfg->mcode_date);
13842 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
13843 asc_dvc->cfg->mcode_version);
13844
13845 /*
13846 * Set the chip type to indicate the ASC3550.
13847 */
13848 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
13849
13850 /*
13851 * If the PCI Configuration Command Register "Parity Error Response
13852 * Control" Bit was clear (0), then set the microcode variable
13853 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
13854 * to ignore DMA parity errors.
13855 */
13856 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
13857 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
13858 word |= CONTROL_FLAG_IGNORE_PERR;
13859 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
13860 }
13861
13862 /*
13863 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
13864 * threshold of 128 bytes. This register is only accessible to the host.
13865 */
13866 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
13867 START_CTL_EMFU | READ_CMD_MRM);
13868
13869 /*
13870 * Microcode operating variables for WDTR, SDTR, and command tag
13871 * queuing will be set in slave_configure() based on what a
13872 * device reports it is capable of in Inquiry byte 7.
13873 *
13874 * If SCSI Bus Resets have been disabled, then directly set
13875 * SDTR and WDTR from the EEPROM configuration. This will allow
13876 * the BIOS and warm boot to work without a SCSI bus hang on
13877 * the Inquiry caused by host and target mismatched DTR values.
13878 * Without the SCSI Bus Reset, before an Inquiry a device can't
13879 * be assumed to be in Asynchronous, Narrow mode.
13880 */
13881 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
13882 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
13883 asc_dvc->wdtr_able);
13884 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
13885 asc_dvc->sdtr_able);
13886 }
13887
13888 /*
13889 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
13890 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
13891 * bitmask. These values determine the maximum SDTR speed negotiated
13892 * with a device.
13893 *
13894 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
13895 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
13896 * without determining here whether the device supports SDTR.
13897 *
13898 * 4-bit speed SDTR speed name
13899 * =========== ===============
13900 * 0000b (0x0) SDTR disabled
13901 * 0001b (0x1) 5 Mhz
13902 * 0010b (0x2) 10 Mhz
13903 * 0011b (0x3) 20 Mhz (Ultra)
13904 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
13905 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
13906 * 0110b (0x6) Undefined
13907 * .
13908 * 1111b (0xF) Undefined
13909 */
13910 word = 0;
13911 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13912 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
13913 /* Set Ultra speed for TID 'tid'. */
13914 word |= (0x3 << (4 * (tid % 4)));
13915 } else {
13916 /* Set Fast speed for TID 'tid'. */
13917 word |= (0x2 << (4 * (tid % 4)));
13918 }
13919 if (tid == 3) { /* Check if done with sdtr_speed1. */
13920 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
13921 word = 0;
13922 } else if (tid == 7) { /* Check if done with sdtr_speed2. */
13923 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
13924 word = 0;
13925 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
13926 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
13927 word = 0;
13928 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
13929 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
13930 /* End of loop. */
13931 }
13932 }
13933
13934 /*
13935 * Set microcode operating variable for the disconnect per TID bitmask.
13936 */
13937 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
13938 asc_dvc->cfg->disc_enable);
13939
13940 /*
13941 * Set SCSI_CFG0 Microcode Default Value.
13942 *
13943 * The microcode will set the SCSI_CFG0 register using this value
13944 * after it is started below.
13945 */
13946 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
13947 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
13948 asc_dvc->chip_scsi_id);
13949
13950 /*
13951 * Determine SCSI_CFG1 Microcode Default Value.
13952 *
13953 * The microcode will set the SCSI_CFG1 register using this value
13954 * after it is started below.
13955 */
13956
13957 /* Read current SCSI_CFG1 Register value. */
13958 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
13959
13960 /*
13961 * If all three connectors are in use, return an error.
13962 */
13963 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
13964 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
13965 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
13966 return ADV_ERROR;
13967 }
13968
13969 /*
13970 * If the internal narrow cable is reversed all of the SCSI_CTRL
13971 * register signals will be set. Check for and return an error if
13972 * this condition is found.
13973 */
13974 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
13975 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
13976 return ADV_ERROR;
13977 }
13978
13979 /*
13980 * If this is a differential board and a single-ended device
13981 * is attached to one of the connectors, return an error.
13982 */
13983 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
13984 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
13985 return ADV_ERROR;
13986 }
13987
13988 /*
13989 * If automatic termination control is enabled, then set the
13990 * termination value based on a table listed in a_condor.h.
13991 *
13992 * If manual termination was specified with an EEPROM setting
13993 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
13994 * is ready to be 'ored' into SCSI_CFG1.
13995 */
13996 if (asc_dvc->cfg->termination == 0) {
13997 /*
13998 * The software always controls termination by setting TERM_CTL_SEL.
13999 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
14000 */
14001 asc_dvc->cfg->termination |= TERM_CTL_SEL;
14002
14003 switch (scsi_cfg1 & CABLE_DETECT) {
14004 /* TERM_CTL_H: on, TERM_CTL_L: on */
14005 case 0x3:
14006 case 0x7:
14007 case 0xB:
14008 case 0xD:
14009 case 0xE:
14010 case 0xF:
14011 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
14012 break;
14013
14014 /* TERM_CTL_H: on, TERM_CTL_L: off */
14015 case 0x1:
14016 case 0x5:
14017 case 0x9:
14018 case 0xA:
14019 case 0xC:
14020 asc_dvc->cfg->termination |= TERM_CTL_H;
14021 break;
14022
14023 /* TERM_CTL_H: off, TERM_CTL_L: off */
14024 case 0x2:
14025 case 0x6:
14026 break;
14027 }
14028 }
14029
14030 /*
14031 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
14032 */
14033 scsi_cfg1 &= ~TERM_CTL;
14034
14035 /*
14036 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
14037 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
14038 * referenced, because the hardware internally inverts
14039 * the Termination High and Low bits if TERM_POL is set.
14040 */
14041 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
14042
14043 /*
14044 * Set SCSI_CFG1 Microcode Default Value
14045 *
14046 * Set filter value and possibly modified termination control
14047 * bits in the Microcode SCSI_CFG1 Register Value.
14048 *
14049 * The microcode will set the SCSI_CFG1 register using this value
14050 * after it is started below.
14051 */
14052 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
14053 FLTR_DISABLE | scsi_cfg1);
14054
14055 /*
14056 * Set MEM_CFG Microcode Default Value
14057 *
14058 * The microcode will set the MEM_CFG register using this value
14059 * after it is started below.
14060 *
14061 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
14062 * are defined.
14063 *
14064 * ASC-3550 has 8KB internal memory.
14065 */
14066 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
14067 BIOS_EN | RAM_SZ_8KB);
14068
14069 /*
14070 * Set SEL_MASK Microcode Default Value
14071 *
14072 * The microcode will set the SEL_MASK register using this value
14073 * after it is started below.
14074 */
14075 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
14076 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
14077
14078 /*
14079 * Build carrier freelist.
14080 *
14081 * Driver must have already allocated memory and set 'carrier_buf'.
14082 */
14083 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
14084
14085 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
14086 asc_dvc->carr_freelist = NULL;
14087 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
14088 buf_size = ADV_CARRIER_BUFSIZE;
14089 } else {
14090 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
14091 }
14092
14093 do {
14094 /*
14095 * Get physical address of the carrier 'carrp'.
14096 */
14097 contig_len = sizeof(ADV_CARR_T);
14098 carr_paddr =
14099 cpu_to_le32(DvcGetPhyAddr
14100 (asc_dvc, NULL, (uchar *)carrp,
14101 (ADV_SDCNT *)&contig_len,
14102 ADV_IS_CARRIER_FLAG));
14103
14104 buf_size -= sizeof(ADV_CARR_T);
14105
14106 /*
14107 * If the current carrier is not physically contiguous, then
14108 * maybe there was a page crossing. Try the next carrier aligned
14109 * start address.
14110 */
14111 if (contig_len < sizeof(ADV_CARR_T)) {
14112 carrp++;
14113 continue;
14114 }
14115
14116 carrp->carr_pa = carr_paddr;
14117 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
14118
14119 /*
14120 * Insert the carrier at the beginning of the freelist.
14121 */
14122 carrp->next_vpa =
14123 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
14124 asc_dvc->carr_freelist = carrp;
14125
14126 carrp++;
14127 }
14128 while (buf_size > 0);
14129
14130 /*
14131 * Set-up the Host->RISC Initiator Command Queue (ICQ).
14132 */
14133
14134 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
14135 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14136 return ADV_ERROR;
14137 }
14138 asc_dvc->carr_freelist = (ADV_CARR_T *)
14139 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
14140
14141 /*
14142 * The first command issued will be placed in the stopper carrier.
14143 */
14144 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14145
14146 /*
14147 * Set RISC ICQ physical address start value.
14148 */
14149 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
14150
14151 /*
14152 * Set-up the RISC->Host Initiator Response Queue (IRQ).
14153 */
14154 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
14155 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14156 return ADV_ERROR;
14157 }
14158 asc_dvc->carr_freelist = (ADV_CARR_T *)
14159 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
14160
14161 /*
14162 * The first command completed by the RISC will be placed in
14163 * the stopper.
14164 *
14165 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
14166 * completed the RISC will set the ASC_RQ_STOPPER bit.
14167 */
14168 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14169
14170 /*
14171 * Set RISC IRQ physical address start value.
14172 */
14173 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
14174 asc_dvc->carr_pending_cnt = 0;
14175
14176 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
14177 (ADV_INTR_ENABLE_HOST_INTR |
14178 ADV_INTR_ENABLE_GLOBAL_INTR));
14179
14180 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
14181 AdvWriteWordRegister(iop_base, IOPW_PC, word);
14182
14183 /* finally, finally, gentlemen, start your engine */
14184 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
14185
14186 /*
14187 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
14188 * Resets should be performed. The RISC has to be running
14189 * to issue a SCSI Bus Reset.
14190 */
14191 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
14192 /*
14193 * If the BIOS Signature is present in memory, restore the
14194 * BIOS Handshake Configuration Table and do not perform
14195 * a SCSI Bus Reset.
14196 */
14197 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
14198 0x55AA) {
14199 /*
14200 * Restore per TID negotiated values.
14201 */
14202 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14203 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14204 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
14205 tagqng_able);
14206 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14207 AdvWriteByteLram(iop_base,
14208 ASC_MC_NUMBER_OF_MAX_CMD + tid,
14209 max_cmd[tid]);
14210 }
14211 } else {
14212 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
14213 warn_code = ASC_WARN_BUSRESET_ERROR;
14214 }
14215 }
14216 }
14217
14218 return warn_code;
14219 }
14220
14221 /*
14222 * Initialize the ASC-38C0800.
14223 *
14224 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14225 *
14226 * For a non-fatal error return a warning code. If there are no warnings
14227 * then 0 is returned.
14228 *
14229 * Needed after initialization for error recovery.
14230 */
14231 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
14232 {
14233 AdvPortAddr iop_base;
14234 ushort warn_code;
14235 ADV_DCNT sum;
14236 int begin_addr;
14237 int end_addr;
14238 ushort code_sum;
14239 int word;
14240 int j;
14241 int adv_asc38C0800_expanded_size;
14242 ADV_CARR_T *carrp;
14243 ADV_DCNT contig_len;
14244 ADV_SDCNT buf_size;
14245 ADV_PADDR carr_paddr;
14246 int i;
14247 ushort scsi_cfg1;
14248 uchar byte;
14249 uchar tid;
14250 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
14251 ushort wdtr_able, sdtr_able, tagqng_able;
14252 uchar max_cmd[ADV_MAX_TID + 1];
14253
14254 /* If there is already an error, don't continue. */
14255 if (asc_dvc->err_code != 0) {
14256 return ADV_ERROR;
14257 }
14258
14259 /*
14260 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
14261 */
14262 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
14263 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
14264 return ADV_ERROR;
14265 }
14266
14267 warn_code = 0;
14268 iop_base = asc_dvc->iop_base;
14269
14270 /*
14271 * Save the RISC memory BIOS region before writing the microcode.
14272 * The BIOS may already be loaded and using its RISC LRAM region
14273 * so its region must be saved and restored.
14274 *
14275 * Note: This code makes the assumption, which is currently true,
14276 * that a chip reset does not clear RISC LRAM.
14277 */
14278 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14279 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14280 bios_mem[i]);
14281 }
14282
14283 /*
14284 * Save current per TID negotiated values.
14285 */
14286 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14287 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14288 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14289 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14290 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14291 max_cmd[tid]);
14292 }
14293
14294 /*
14295 * RAM BIST (RAM Built-In Self Test)
14296 *
14297 * Address : I/O base + offset 0x38h register (byte).
14298 * Function: Bit 7-6(RW) : RAM mode
14299 * Normal Mode : 0x00
14300 * Pre-test Mode : 0x40
14301 * RAM Test Mode : 0x80
14302 * Bit 5 : unused
14303 * Bit 4(RO) : Done bit
14304 * Bit 3-0(RO) : Status
14305 * Host Error : 0x08
14306 * Int_RAM Error : 0x04
14307 * RISC Error : 0x02
14308 * SCSI Error : 0x01
14309 * No Error : 0x00
14310 *
14311 * Note: RAM BIST code should be put right here, before loading the
14312 * microcode and after saving the RISC memory BIOS region.
14313 */
14314
14315 /*
14316 * LRAM Pre-test
14317 *
14318 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
14319 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
14320 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
14321 * to NORMAL_MODE, return an error too.
14322 */
14323 for (i = 0; i < 2; i++) {
14324 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
14325 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14326 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14327 if ((byte & RAM_TEST_DONE) == 0
14328 || (byte & 0x0F) != PRE_TEST_VALUE) {
14329 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14330 return ADV_ERROR;
14331 }
14332
14333 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14334 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14335 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
14336 != NORMAL_VALUE) {
14337 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14338 return ADV_ERROR;
14339 }
14340 }
14341
14342 /*
14343 * LRAM Test - It takes about 1.5 ms to run through the test.
14344 *
14345 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
14346 * If Done bit not set or Status not 0, save register byte, set the
14347 * err_code, and return an error.
14348 */
14349 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
14350 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
14351
14352 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14353 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
14354 /* Get here if Done bit not set or Status not 0. */
14355 asc_dvc->bist_err_code = byte; /* for BIOS display message */
14356 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
14357 return ADV_ERROR;
14358 }
14359
14360 /* We need to reset back to normal mode after LRAM test passes. */
14361 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14362
14363 /*
14364 * Load the Microcode
14365 *
14366 * Write the microcode image to RISC memory starting at address 0.
14367 *
14368 */
14369 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14370
14371 /* Assume the following compressed format of the microcode buffer:
14372 *
14373 * 254 word (508 byte) table indexed by byte code followed
14374 * by the following byte codes:
14375 *
14376 * 1-Byte Code:
14377 * 00: Emit word 0 in table.
14378 * 01: Emit word 1 in table.
14379 * .
14380 * FD: Emit word 253 in table.
14381 *
14382 * Multi-Byte Code:
14383 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14384 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14385 */
14386 word = 0;
14387 for (i = 253 * 2; i < _adv_asc38C0800_size; i++) {
14388 if (_adv_asc38C0800_buf[i] == 0xff) {
14389 for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++) {
14390 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14391 _adv_asc38C0800_buf
14392 [i +
14393 3] << 8) |
14394 _adv_asc38C0800_buf
14395 [i + 2]));
14396 word++;
14397 }
14398 i += 3;
14399 } else if (_adv_asc38C0800_buf[i] == 0xfe) {
14400 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14401 _adv_asc38C0800_buf
14402 [i +
14403 2] << 8) |
14404 _adv_asc38C0800_buf[i
14405 +
14406 1]));
14407 i += 2;
14408 word++;
14409 } else {
14410 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14411 _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) | _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
14412 word++;
14413 }
14414 }
14415
14416 /*
14417 * Set 'word' for later use to clear the rest of memory and save
14418 * the expanded mcode size.
14419 */
14420 word *= 2;
14421 adv_asc38C0800_expanded_size = word;
14422
14423 /*
14424 * Clear the rest of ASC-38C0800 Internal RAM (16KB).
14425 */
14426 for (; word < ADV_38C0800_MEMSIZE; word += 2) {
14427 AdvWriteWordAutoIncLram(iop_base, 0);
14428 }
14429
14430 /*
14431 * Verify the microcode checksum.
14432 */
14433 sum = 0;
14434 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14435
14436 for (word = 0; word < adv_asc38C0800_expanded_size; word += 2) {
14437 sum += AdvReadWordAutoIncLram(iop_base);
14438 }
14439 ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
14440
14441 ASC_DBG2(1,
14442 "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
14443 (ulong)sum, (ulong)_adv_asc38C0800_chksum);
14444
14445 if (sum != _adv_asc38C0800_chksum) {
14446 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14447 return ADV_ERROR;
14448 }
14449
14450 /*
14451 * Restore the RISC memory BIOS region.
14452 */
14453 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14454 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14455 bios_mem[i]);
14456 }
14457
14458 /*
14459 * Calculate and write the microcode code checksum to the microcode
14460 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14461 */
14462 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14463 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14464 code_sum = 0;
14465 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14466 for (word = begin_addr; word < end_addr; word += 2) {
14467 code_sum += AdvReadWordAutoIncLram(iop_base);
14468 }
14469 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14470
14471 /*
14472 * Read microcode version and date.
14473 */
14474 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
14475 asc_dvc->cfg->mcode_date);
14476 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
14477 asc_dvc->cfg->mcode_version);
14478
14479 /*
14480 * Set the chip type to indicate the ASC38C0800.
14481 */
14482 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
14483
14484 /*
14485 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
14486 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
14487 * cable detection and then we are able to read C_DET[3:0].
14488 *
14489 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
14490 * Microcode Default Value' section below.
14491 */
14492 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14493 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
14494 scsi_cfg1 | DIS_TERM_DRV);
14495
14496 /*
14497 * If the PCI Configuration Command Register "Parity Error Response
14498 * Control" Bit was clear (0), then set the microcode variable
14499 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14500 * to ignore DMA parity errors.
14501 */
14502 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
14503 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14504 word |= CONTROL_FLAG_IGNORE_PERR;
14505 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14506 }
14507
14508 /*
14509 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
14510 * bits for the default FIFO threshold.
14511 *
14512 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
14513 *
14514 * For DMA Errata #4 set the BC_THRESH_ENB bit.
14515 */
14516 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14517 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
14518 READ_CMD_MRM);
14519
14520 /*
14521 * Microcode operating variables for WDTR, SDTR, and command tag
14522 * queuing will be set in slave_configure() based on what a
14523 * device reports it is capable of in Inquiry byte 7.
14524 *
14525 * If SCSI Bus Resets have been disabled, then directly set
14526 * SDTR and WDTR from the EEPROM configuration. This will allow
14527 * the BIOS and warm boot to work without a SCSI bus hang on
14528 * the Inquiry caused by host and target mismatched DTR values.
14529 * Without the SCSI Bus Reset, before an Inquiry a device can't
14530 * be assumed to be in Asynchronous, Narrow mode.
14531 */
14532 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
14533 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
14534 asc_dvc->wdtr_able);
14535 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
14536 asc_dvc->sdtr_able);
14537 }
14538
14539 /*
14540 * Set microcode operating variables for DISC and SDTR_SPEED1,
14541 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
14542 * configuration values.
14543 *
14544 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14545 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14546 * without determining here whether the device supports SDTR.
14547 */
14548 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
14549 asc_dvc->cfg->disc_enable);
14550 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
14551 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
14552 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
14553 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
14554
14555 /*
14556 * Set SCSI_CFG0 Microcode Default Value.
14557 *
14558 * The microcode will set the SCSI_CFG0 register using this value
14559 * after it is started below.
14560 */
14561 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14562 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14563 asc_dvc->chip_scsi_id);
14564
14565 /*
14566 * Determine SCSI_CFG1 Microcode Default Value.
14567 *
14568 * The microcode will set the SCSI_CFG1 register using this value
14569 * after it is started below.
14570 */
14571
14572 /* Read current SCSI_CFG1 Register value. */
14573 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14574
14575 /*
14576 * If the internal narrow cable is reversed all of the SCSI_CTRL
14577 * register signals will be set. Check for and return an error if
14578 * this condition is found.
14579 */
14580 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
14581 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14582 return ADV_ERROR;
14583 }
14584
14585 /*
14586 * All kind of combinations of devices attached to one of four connectors
14587 * are acceptable except HVD device attached. For example, LVD device can
14588 * be attached to SE connector while SE device attached to LVD connector.
14589 * If LVD device attached to SE connector, it only runs up to Ultra speed.
14590 *
14591 * If an HVD device is attached to one of LVD connectors, return an error.
14592 * However, there is no way to detect HVD device attached to SE connectors.
14593 */
14594 if (scsi_cfg1 & HVD) {
14595 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
14596 return ADV_ERROR;
14597 }
14598
14599 /*
14600 * If either SE or LVD automatic termination control is enabled, then
14601 * set the termination value based on a table listed in a_condor.h.
14602 *
14603 * If manual termination was specified with an EEPROM setting then
14604 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
14605 * be 'ored' into SCSI_CFG1.
14606 */
14607 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
14608 /* SE automatic termination control is enabled. */
14609 switch (scsi_cfg1 & C_DET_SE) {
14610 /* TERM_SE_HI: on, TERM_SE_LO: on */
14611 case 0x1:
14612 case 0x2:
14613 case 0x3:
14614 asc_dvc->cfg->termination |= TERM_SE;
14615 break;
14616
14617 /* TERM_SE_HI: on, TERM_SE_LO: off */
14618 case 0x0:
14619 asc_dvc->cfg->termination |= TERM_SE_HI;
14620 break;
14621 }
14622 }
14623
14624 if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
14625 /* LVD automatic termination control is enabled. */
14626 switch (scsi_cfg1 & C_DET_LVD) {
14627 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
14628 case 0x4:
14629 case 0x8:
14630 case 0xC:
14631 asc_dvc->cfg->termination |= TERM_LVD;
14632 break;
14633
14634 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
14635 case 0x0:
14636 break;
14637 }
14638 }
14639
14640 /*
14641 * Clear any set TERM_SE and TERM_LVD bits.
14642 */
14643 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
14644
14645 /*
14646 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
14647 */
14648 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
14649
14650 /*
14651 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
14652 * and set possibly modified termination control bits in the Microcode
14653 * SCSI_CFG1 Register Value.
14654 */
14655 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
14656
14657 /*
14658 * Set SCSI_CFG1 Microcode Default Value
14659 *
14660 * Set possibly modified termination control and reset DIS_TERM_DRV
14661 * bits in the Microcode SCSI_CFG1 Register Value.
14662 *
14663 * The microcode will set the SCSI_CFG1 register using this value
14664 * after it is started below.
14665 */
14666 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
14667
14668 /*
14669 * Set MEM_CFG Microcode Default Value
14670 *
14671 * The microcode will set the MEM_CFG register using this value
14672 * after it is started below.
14673 *
14674 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
14675 * are defined.
14676 *
14677 * ASC-38C0800 has 16KB internal memory.
14678 */
14679 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
14680 BIOS_EN | RAM_SZ_16KB);
14681
14682 /*
14683 * Set SEL_MASK Microcode Default Value
14684 *
14685 * The microcode will set the SEL_MASK register using this value
14686 * after it is started below.
14687 */
14688 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
14689 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
14690
14691 /*
14692 * Build the carrier freelist.
14693 *
14694 * Driver must have already allocated memory and set 'carrier_buf'.
14695 */
14696 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
14697
14698 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
14699 asc_dvc->carr_freelist = NULL;
14700 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
14701 buf_size = ADV_CARRIER_BUFSIZE;
14702 } else {
14703 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
14704 }
14705
14706 do {
14707 /*
14708 * Get physical address for the carrier 'carrp'.
14709 */
14710 contig_len = sizeof(ADV_CARR_T);
14711 carr_paddr =
14712 cpu_to_le32(DvcGetPhyAddr
14713 (asc_dvc, NULL, (uchar *)carrp,
14714 (ADV_SDCNT *)&contig_len,
14715 ADV_IS_CARRIER_FLAG));
14716
14717 buf_size -= sizeof(ADV_CARR_T);
14718
14719 /*
14720 * If the current carrier is not physically contiguous, then
14721 * maybe there was a page crossing. Try the next carrier aligned
14722 * start address.
14723 */
14724 if (contig_len < sizeof(ADV_CARR_T)) {
14725 carrp++;
14726 continue;
14727 }
14728
14729 carrp->carr_pa = carr_paddr;
14730 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
14731
14732 /*
14733 * Insert the carrier at the beginning of the freelist.
14734 */
14735 carrp->next_vpa =
14736 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
14737 asc_dvc->carr_freelist = carrp;
14738
14739 carrp++;
14740 }
14741 while (buf_size > 0);
14742
14743 /*
14744 * Set-up the Host->RISC Initiator Command Queue (ICQ).
14745 */
14746
14747 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
14748 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14749 return ADV_ERROR;
14750 }
14751 asc_dvc->carr_freelist = (ADV_CARR_T *)
14752 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
14753
14754 /*
14755 * The first command issued will be placed in the stopper carrier.
14756 */
14757 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14758
14759 /*
14760 * Set RISC ICQ physical address start value.
14761 * carr_pa is LE, must be native before write
14762 */
14763 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
14764
14765 /*
14766 * Set-up the RISC->Host Initiator Response Queue (IRQ).
14767 */
14768 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
14769 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14770 return ADV_ERROR;
14771 }
14772 asc_dvc->carr_freelist = (ADV_CARR_T *)
14773 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
14774
14775 /*
14776 * The first command completed by the RISC will be placed in
14777 * the stopper.
14778 *
14779 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
14780 * completed the RISC will set the ASC_RQ_STOPPER bit.
14781 */
14782 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14783
14784 /*
14785 * Set RISC IRQ physical address start value.
14786 *
14787 * carr_pa is LE, must be native before write *
14788 */
14789 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
14790 asc_dvc->carr_pending_cnt = 0;
14791
14792 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
14793 (ADV_INTR_ENABLE_HOST_INTR |
14794 ADV_INTR_ENABLE_GLOBAL_INTR));
14795
14796 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
14797 AdvWriteWordRegister(iop_base, IOPW_PC, word);
14798
14799 /* finally, finally, gentlemen, start your engine */
14800 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
14801
14802 /*
14803 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
14804 * Resets should be performed. The RISC has to be running
14805 * to issue a SCSI Bus Reset.
14806 */
14807 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
14808 /*
14809 * If the BIOS Signature is present in memory, restore the
14810 * BIOS Handshake Configuration Table and do not perform
14811 * a SCSI Bus Reset.
14812 */
14813 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
14814 0x55AA) {
14815 /*
14816 * Restore per TID negotiated values.
14817 */
14818 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14819 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14820 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
14821 tagqng_able);
14822 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14823 AdvWriteByteLram(iop_base,
14824 ASC_MC_NUMBER_OF_MAX_CMD + tid,
14825 max_cmd[tid]);
14826 }
14827 } else {
14828 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
14829 warn_code = ASC_WARN_BUSRESET_ERROR;
14830 }
14831 }
14832 }
14833
14834 return warn_code;
14835 }
14836
14837 /*
14838 * Initialize the ASC-38C1600.
14839 *
14840 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
14841 *
14842 * For a non-fatal error return a warning code. If there are no warnings
14843 * then 0 is returned.
14844 *
14845 * Needed after initialization for error recovery.
14846 */
14847 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
14848 {
14849 AdvPortAddr iop_base;
14850 ushort warn_code;
14851 ADV_DCNT sum;
14852 int begin_addr;
14853 int end_addr;
14854 ushort code_sum;
14855 long word;
14856 int j;
14857 int adv_asc38C1600_expanded_size;
14858 ADV_CARR_T *carrp;
14859 ADV_DCNT contig_len;
14860 ADV_SDCNT buf_size;
14861 ADV_PADDR carr_paddr;
14862 int i;
14863 ushort scsi_cfg1;
14864 uchar byte;
14865 uchar tid;
14866 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
14867 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
14868 uchar max_cmd[ASC_MAX_TID + 1];
14869
14870 /* If there is already an error, don't continue. */
14871 if (asc_dvc->err_code != 0) {
14872 return ADV_ERROR;
14873 }
14874
14875 /*
14876 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
14877 */
14878 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
14879 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
14880 return ADV_ERROR;
14881 }
14882
14883 warn_code = 0;
14884 iop_base = asc_dvc->iop_base;
14885
14886 /*
14887 * Save the RISC memory BIOS region before writing the microcode.
14888 * The BIOS may already be loaded and using its RISC LRAM region
14889 * so its region must be saved and restored.
14890 *
14891 * Note: This code makes the assumption, which is currently true,
14892 * that a chip reset does not clear RISC LRAM.
14893 */
14894 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14895 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14896 bios_mem[i]);
14897 }
14898
14899 /*
14900 * Save current per TID negotiated values.
14901 */
14902 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14903 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14904 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
14905 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14906 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
14907 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14908 max_cmd[tid]);
14909 }
14910
14911 /*
14912 * RAM BIST (Built-In Self Test)
14913 *
14914 * Address : I/O base + offset 0x38h register (byte).
14915 * Function: Bit 7-6(RW) : RAM mode
14916 * Normal Mode : 0x00
14917 * Pre-test Mode : 0x40
14918 * RAM Test Mode : 0x80
14919 * Bit 5 : unused
14920 * Bit 4(RO) : Done bit
14921 * Bit 3-0(RO) : Status
14922 * Host Error : 0x08
14923 * Int_RAM Error : 0x04
14924 * RISC Error : 0x02
14925 * SCSI Error : 0x01
14926 * No Error : 0x00
14927 *
14928 * Note: RAM BIST code should be put right here, before loading the
14929 * microcode and after saving the RISC memory BIOS region.
14930 */
14931
14932 /*
14933 * LRAM Pre-test
14934 *
14935 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
14936 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
14937 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
14938 * to NORMAL_MODE, return an error too.
14939 */
14940 for (i = 0; i < 2; i++) {
14941 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
14942 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14943 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14944 if ((byte & RAM_TEST_DONE) == 0
14945 || (byte & 0x0F) != PRE_TEST_VALUE) {
14946 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14947 return ADV_ERROR;
14948 }
14949
14950 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14951 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14952 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
14953 != NORMAL_VALUE) {
14954 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14955 return ADV_ERROR;
14956 }
14957 }
14958
14959 /*
14960 * LRAM Test - It takes about 1.5 ms to run through the test.
14961 *
14962 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
14963 * If Done bit not set or Status not 0, save register byte, set the
14964 * err_code, and return an error.
14965 */
14966 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
14967 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
14968
14969 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14970 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
14971 /* Get here if Done bit not set or Status not 0. */
14972 asc_dvc->bist_err_code = byte; /* for BIOS display message */
14973 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
14974 return ADV_ERROR;
14975 }
14976
14977 /* We need to reset back to normal mode after LRAM test passes. */
14978 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14979
14980 /*
14981 * Load the Microcode
14982 *
14983 * Write the microcode image to RISC memory starting at address 0.
14984 *
14985 */
14986 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14987
14988 /*
14989 * Assume the following compressed format of the microcode buffer:
14990 *
14991 * 254 word (508 byte) table indexed by byte code followed
14992 * by the following byte codes:
14993 *
14994 * 1-Byte Code:
14995 * 00: Emit word 0 in table.
14996 * 01: Emit word 1 in table.
14997 * .
14998 * FD: Emit word 253 in table.
14999 *
15000 * Multi-Byte Code:
15001 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15002 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15003 */
15004 word = 0;
15005 for (i = 253 * 2; i < _adv_asc38C1600_size; i++) {
15006 if (_adv_asc38C1600_buf[i] == 0xff) {
15007 for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++) {
15008 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15009 _adv_asc38C1600_buf
15010 [i +
15011 3] << 8) |
15012 _adv_asc38C1600_buf
15013 [i + 2]));
15014 word++;
15015 }
15016 i += 3;
15017 } else if (_adv_asc38C1600_buf[i] == 0xfe) {
15018 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15019 _adv_asc38C1600_buf
15020 [i +
15021 2] << 8) |
15022 _adv_asc38C1600_buf[i
15023 +
15024 1]));
15025 i += 2;
15026 word++;
15027 } else {
15028 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15029 _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) | _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
15030 word++;
15031 }
15032 }
15033
15034 /*
15035 * Set 'word' for later use to clear the rest of memory and save
15036 * the expanded mcode size.
15037 */
15038 word *= 2;
15039 adv_asc38C1600_expanded_size = word;
15040
15041 /*
15042 * Clear the rest of ASC-38C1600 Internal RAM (32KB).
15043 */
15044 for (; word < ADV_38C1600_MEMSIZE; word += 2) {
15045 AdvWriteWordAutoIncLram(iop_base, 0);
15046 }
15047
15048 /*
15049 * Verify the microcode checksum.
15050 */
15051 sum = 0;
15052 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15053
15054 for (word = 0; word < adv_asc38C1600_expanded_size; word += 2) {
15055 sum += AdvReadWordAutoIncLram(iop_base);
15056 }
15057
15058 if (sum != _adv_asc38C1600_chksum) {
15059 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15060 return ADV_ERROR;
15061 }
15062
15063 /*
15064 * Restore the RISC memory BIOS region.
15065 */
15066 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15067 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15068 bios_mem[i]);
15069 }
15070
15071 /*
15072 * Calculate and write the microcode code checksum to the microcode
15073 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15074 */
15075 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15076 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15077 code_sum = 0;
15078 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15079 for (word = begin_addr; word < end_addr; word += 2) {
15080 code_sum += AdvReadWordAutoIncLram(iop_base);
15081 }
15082 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15083
15084 /*
15085 * Read microcode version and date.
15086 */
15087 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
15088 asc_dvc->cfg->mcode_date);
15089 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
15090 asc_dvc->cfg->mcode_version);
15091
15092 /*
15093 * Set the chip type to indicate the ASC38C1600.
15094 */
15095 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
15096
15097 /*
15098 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15099 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15100 * cable detection and then we are able to read C_DET[3:0].
15101 *
15102 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15103 * Microcode Default Value' section below.
15104 */
15105 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15106 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
15107 scsi_cfg1 | DIS_TERM_DRV);
15108
15109 /*
15110 * If the PCI Configuration Command Register "Parity Error Response
15111 * Control" Bit was clear (0), then set the microcode variable
15112 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15113 * to ignore DMA parity errors.
15114 */
15115 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
15116 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15117 word |= CONTROL_FLAG_IGNORE_PERR;
15118 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15119 }
15120
15121 /*
15122 * If the BIOS control flag AIPP (Asynchronous Information
15123 * Phase Protection) disable bit is not set, then set the firmware
15124 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
15125 * AIPP checking and encoding.
15126 */
15127 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
15128 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15129 word |= CONTROL_FLAG_ENABLE_AIPP;
15130 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15131 }
15132
15133 /*
15134 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
15135 * and START_CTL_TH [3:2].
15136 */
15137 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15138 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
15139
15140 /*
15141 * Microcode operating variables for WDTR, SDTR, and command tag
15142 * queuing will be set in slave_configure() based on what a
15143 * device reports it is capable of in Inquiry byte 7.
15144 *
15145 * If SCSI Bus Resets have been disabled, then directly set
15146 * SDTR and WDTR from the EEPROM configuration. This will allow
15147 * the BIOS and warm boot to work without a SCSI bus hang on
15148 * the Inquiry caused by host and target mismatched DTR values.
15149 * Without the SCSI Bus Reset, before an Inquiry a device can't
15150 * be assumed to be in Asynchronous, Narrow mode.
15151 */
15152 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
15153 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
15154 asc_dvc->wdtr_able);
15155 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
15156 asc_dvc->sdtr_able);
15157 }
15158
15159 /*
15160 * Set microcode operating variables for DISC and SDTR_SPEED1,
15161 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15162 * configuration values.
15163 *
15164 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15165 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15166 * without determining here whether the device supports SDTR.
15167 */
15168 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
15169 asc_dvc->cfg->disc_enable);
15170 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15171 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15172 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15173 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15174
15175 /*
15176 * Set SCSI_CFG0 Microcode Default Value.
15177 *
15178 * The microcode will set the SCSI_CFG0 register using this value
15179 * after it is started below.
15180 */
15181 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15182 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15183 asc_dvc->chip_scsi_id);
15184
15185 /*
15186 * Calculate SCSI_CFG1 Microcode Default Value.
15187 *
15188 * The microcode will set the SCSI_CFG1 register using this value
15189 * after it is started below.
15190 *
15191 * Each ASC-38C1600 function has only two cable detect bits.
15192 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
15193 */
15194 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15195
15196 /*
15197 * If the cable is reversed all of the SCSI_CTRL register signals
15198 * will be set. Check for and return an error if this condition is
15199 * found.
15200 */
15201 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
15202 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15203 return ADV_ERROR;
15204 }
15205
15206 /*
15207 * Each ASC-38C1600 function has two connectors. Only an HVD device
15208 * can not be connected to either connector. An LVD device or SE device
15209 * may be connected to either connecor. If an SE device is connected,
15210 * then at most Ultra speed (20 Mhz) can be used on both connectors.
15211 *
15212 * If an HVD device is attached, return an error.
15213 */
15214 if (scsi_cfg1 & HVD) {
15215 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15216 return ADV_ERROR;
15217 }
15218
15219 /*
15220 * Each function in the ASC-38C1600 uses only the SE cable detect and
15221 * termination because there are two connectors for each function. Each
15222 * function may use either LVD or SE mode. Corresponding the SE automatic
15223 * termination control EEPROM bits are used for each function. Each
15224 * function has its own EEPROM. If SE automatic control is enabled for
15225 * the function, then set the termination value based on a table listed
15226 * in a_condor.h.
15227 *
15228 * If manual termination is specified in the EEPROM for the function,
15229 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
15230 * ready to be 'ored' into SCSI_CFG1.
15231 */
15232 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
15233 /* SE automatic termination control is enabled. */
15234 switch (scsi_cfg1 & C_DET_SE) {
15235 /* TERM_SE_HI: on, TERM_SE_LO: on */
15236 case 0x1:
15237 case 0x2:
15238 case 0x3:
15239 asc_dvc->cfg->termination |= TERM_SE;
15240 break;
15241
15242 case 0x0:
15243 if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0) {
15244 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
15245 } else {
15246 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
15247 asc_dvc->cfg->termination |= TERM_SE_HI;
15248 }
15249 break;
15250 }
15251 }
15252
15253 /*
15254 * Clear any set TERM_SE bits.
15255 */
15256 scsi_cfg1 &= ~TERM_SE;
15257
15258 /*
15259 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
15260 */
15261 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
15262
15263 /*
15264 * Clear Big Endian and Terminator Polarity bits and set possibly
15265 * modified termination control bits in the Microcode SCSI_CFG1
15266 * Register Value.
15267 *
15268 * Big Endian bit is not used even on big endian machines.
15269 */
15270 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
15271
15272 /*
15273 * Set SCSI_CFG1 Microcode Default Value
15274 *
15275 * Set possibly modified termination control bits in the Microcode
15276 * SCSI_CFG1 Register Value.
15277 *
15278 * The microcode will set the SCSI_CFG1 register using this value
15279 * after it is started below.
15280 */
15281 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15282
15283 /*
15284 * Set MEM_CFG Microcode Default Value
15285 *
15286 * The microcode will set the MEM_CFG register using this value
15287 * after it is started below.
15288 *
15289 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15290 * are defined.
15291 *
15292 * ASC-38C1600 has 32KB internal memory.
15293 *
15294 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
15295 * out a special 16K Adv Library and Microcode version. After the issue
15296 * resolved, we should turn back to the 32K support. Both a_condor.h and
15297 * mcode.sas files also need to be updated.
15298 *
15299 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15300 * BIOS_EN | RAM_SZ_32KB);
15301 */
15302 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15303 BIOS_EN | RAM_SZ_16KB);
15304
15305 /*
15306 * Set SEL_MASK Microcode Default Value
15307 *
15308 * The microcode will set the SEL_MASK register using this value
15309 * after it is started below.
15310 */
15311 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15312 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15313
15314 /*
15315 * Build the carrier freelist.
15316 *
15317 * Driver must have already allocated memory and set 'carrier_buf'.
15318 */
15319
15320 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15321
15322 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15323 asc_dvc->carr_freelist = NULL;
15324 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
15325 buf_size = ADV_CARRIER_BUFSIZE;
15326 } else {
15327 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15328 }
15329
15330 do {
15331 /*
15332 * Get physical address for the carrier 'carrp'.
15333 */
15334 contig_len = sizeof(ADV_CARR_T);
15335 carr_paddr =
15336 cpu_to_le32(DvcGetPhyAddr
15337 (asc_dvc, NULL, (uchar *)carrp,
15338 (ADV_SDCNT *)&contig_len,
15339 ADV_IS_CARRIER_FLAG));
15340
15341 buf_size -= sizeof(ADV_CARR_T);
15342
15343 /*
15344 * If the current carrier is not physically contiguous, then
15345 * maybe there was a page crossing. Try the next carrier aligned
15346 * start address.
15347 */
15348 if (contig_len < sizeof(ADV_CARR_T)) {
15349 carrp++;
15350 continue;
15351 }
15352
15353 carrp->carr_pa = carr_paddr;
15354 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15355
15356 /*
15357 * Insert the carrier at the beginning of the freelist.
15358 */
15359 carrp->next_vpa =
15360 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15361 asc_dvc->carr_freelist = carrp;
15362
15363 carrp++;
15364 }
15365 while (buf_size > 0);
15366
15367 /*
15368 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15369 */
15370 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
15371 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15372 return ADV_ERROR;
15373 }
15374 asc_dvc->carr_freelist = (ADV_CARR_T *)
15375 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15376
15377 /*
15378 * The first command issued will be placed in the stopper carrier.
15379 */
15380 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15381
15382 /*
15383 * Set RISC ICQ physical address start value. Initialize the
15384 * COMMA register to the same value otherwise the RISC will
15385 * prematurely detect a command is available.
15386 */
15387 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15388 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
15389 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
15390
15391 /*
15392 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15393 */
15394 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
15395 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15396 return ADV_ERROR;
15397 }
15398 asc_dvc->carr_freelist = (ADV_CARR_T *)
15399 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15400
15401 /*
15402 * The first command completed by the RISC will be placed in
15403 * the stopper.
15404 *
15405 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15406 * completed the RISC will set the ASC_RQ_STOPPER bit.
15407 */
15408 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15409
15410 /*
15411 * Set RISC IRQ physical address start value.
15412 */
15413 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15414 asc_dvc->carr_pending_cnt = 0;
15415
15416 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15417 (ADV_INTR_ENABLE_HOST_INTR |
15418 ADV_INTR_ENABLE_GLOBAL_INTR));
15419 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15420 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15421
15422 /* finally, finally, gentlemen, start your engine */
15423 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15424
15425 /*
15426 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15427 * Resets should be performed. The RISC has to be running
15428 * to issue a SCSI Bus Reset.
15429 */
15430 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
15431 /*
15432 * If the BIOS Signature is present in memory, restore the
15433 * per TID microcode operating variables.
15434 */
15435 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
15436 0x55AA) {
15437 /*
15438 * Restore per TID negotiated values.
15439 */
15440 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15441 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15442 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15443 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
15444 tagqng_able);
15445 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15446 AdvWriteByteLram(iop_base,
15447 ASC_MC_NUMBER_OF_MAX_CMD + tid,
15448 max_cmd[tid]);
15449 }
15450 } else {
15451 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
15452 warn_code = ASC_WARN_BUSRESET_ERROR;
15453 }
15454 }
15455 }
15456
15457 return warn_code;
15458 }
15459
15460 /*
15461 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
15462 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
15463 * all of this is done.
15464 *
15465 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15466 *
15467 * For a non-fatal error return a warning code. If there are no warnings
15468 * then 0 is returned.
15469 *
15470 * Note: Chip is stopped on entry.
15471 */
15472 static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
15473 {
15474 AdvPortAddr iop_base;
15475 ushort warn_code;
15476 ADVEEP_3550_CONFIG eep_config;
15477 int i;
15478
15479 iop_base = asc_dvc->iop_base;
15480
15481 warn_code = 0;
15482
15483 /*
15484 * Read the board's EEPROM configuration.
15485 *
15486 * Set default values if a bad checksum is found.
15487 */
15488 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
15489 warn_code |= ASC_WARN_EEPROM_CHKSUM;
15490
15491 /*
15492 * Set EEPROM default values.
15493 */
15494 for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++) {
15495 *((uchar *)&eep_config + i) =
15496 *((uchar *)&Default_3550_EEPROM_Config + i);
15497 }
15498
15499 /*
15500 * Assume the 6 byte board serial number that was read
15501 * from EEPROM is correct even if the EEPROM checksum
15502 * failed.
15503 */
15504 eep_config.serial_number_word3 =
15505 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
15506
15507 eep_config.serial_number_word2 =
15508 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
15509
15510 eep_config.serial_number_word1 =
15511 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
15512
15513 AdvSet3550EEPConfig(iop_base, &eep_config);
15514 }
15515 /*
15516 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
15517 * EEPROM configuration that was read.
15518 *
15519 * This is the mapping of EEPROM fields to Adv Library fields.
15520 */
15521 asc_dvc->wdtr_able = eep_config.wdtr_able;
15522 asc_dvc->sdtr_able = eep_config.sdtr_able;
15523 asc_dvc->ultra_able = eep_config.ultra_able;
15524 asc_dvc->tagqng_able = eep_config.tagqng_able;
15525 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
15526 asc_dvc->max_host_qng = eep_config.max_host_qng;
15527 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15528 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
15529 asc_dvc->start_motor = eep_config.start_motor;
15530 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
15531 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
15532 asc_dvc->no_scam = eep_config.scam_tolerant;
15533 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
15534 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
15535 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
15536
15537 /*
15538 * Set the host maximum queuing (max. 253, min. 16) and the per device
15539 * maximum queuing (max. 63, min. 4).
15540 */
15541 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
15542 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15543 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
15544 /* If the value is zero, assume it is uninitialized. */
15545 if (eep_config.max_host_qng == 0) {
15546 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15547 } else {
15548 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
15549 }
15550 }
15551
15552 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
15553 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15554 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
15555 /* If the value is zero, assume it is uninitialized. */
15556 if (eep_config.max_dvc_qng == 0) {
15557 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15558 } else {
15559 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
15560 }
15561 }
15562
15563 /*
15564 * If 'max_dvc_qng' is greater than 'max_host_qng', then
15565 * set 'max_dvc_qng' to 'max_host_qng'.
15566 */
15567 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
15568 eep_config.max_dvc_qng = eep_config.max_host_qng;
15569 }
15570
15571 /*
15572 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
15573 * values based on possibly adjusted EEPROM values.
15574 */
15575 asc_dvc->max_host_qng = eep_config.max_host_qng;
15576 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15577
15578 /*
15579 * If the EEPROM 'termination' field is set to automatic (0), then set
15580 * the ADV_DVC_CFG 'termination' field to automatic also.
15581 *
15582 * If the termination is specified with a non-zero 'termination'
15583 * value check that a legal value is set and set the ADV_DVC_CFG
15584 * 'termination' field appropriately.
15585 */
15586 if (eep_config.termination == 0) {
15587 asc_dvc->cfg->termination = 0; /* auto termination */
15588 } else {
15589 /* Enable manual control with low off / high off. */
15590 if (eep_config.termination == 1) {
15591 asc_dvc->cfg->termination = TERM_CTL_SEL;
15592
15593 /* Enable manual control with low off / high on. */
15594 } else if (eep_config.termination == 2) {
15595 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
15596
15597 /* Enable manual control with low on / high on. */
15598 } else if (eep_config.termination == 3) {
15599 asc_dvc->cfg->termination =
15600 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
15601 } else {
15602 /*
15603 * The EEPROM 'termination' field contains a bad value. Use
15604 * automatic termination instead.
15605 */
15606 asc_dvc->cfg->termination = 0;
15607 warn_code |= ASC_WARN_EEPROM_TERMINATION;
15608 }
15609 }
15610
15611 return warn_code;
15612 }
15613
15614 /*
15615 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
15616 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
15617 * all of this is done.
15618 *
15619 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15620 *
15621 * For a non-fatal error return a warning code. If there are no warnings
15622 * then 0 is returned.
15623 *
15624 * Note: Chip is stopped on entry.
15625 */
15626 static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
15627 {
15628 AdvPortAddr iop_base;
15629 ushort warn_code;
15630 ADVEEP_38C0800_CONFIG eep_config;
15631 int i;
15632 uchar tid, termination;
15633 ushort sdtr_speed = 0;
15634
15635 iop_base = asc_dvc->iop_base;
15636
15637 warn_code = 0;
15638
15639 /*
15640 * Read the board's EEPROM configuration.
15641 *
15642 * Set default values if a bad checksum is found.
15643 */
15644 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
15645 eep_config.check_sum) {
15646 warn_code |= ASC_WARN_EEPROM_CHKSUM;
15647
15648 /*
15649 * Set EEPROM default values.
15650 */
15651 for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++) {
15652 *((uchar *)&eep_config + i) =
15653 *((uchar *)&Default_38C0800_EEPROM_Config + i);
15654 }
15655
15656 /*
15657 * Assume the 6 byte board serial number that was read
15658 * from EEPROM is correct even if the EEPROM checksum
15659 * failed.
15660 */
15661 eep_config.serial_number_word3 =
15662 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
15663
15664 eep_config.serial_number_word2 =
15665 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
15666
15667 eep_config.serial_number_word1 =
15668 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
15669
15670 AdvSet38C0800EEPConfig(iop_base, &eep_config);
15671 }
15672 /*
15673 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
15674 * EEPROM configuration that was read.
15675 *
15676 * This is the mapping of EEPROM fields to Adv Library fields.
15677 */
15678 asc_dvc->wdtr_able = eep_config.wdtr_able;
15679 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
15680 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
15681 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
15682 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
15683 asc_dvc->tagqng_able = eep_config.tagqng_able;
15684 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
15685 asc_dvc->max_host_qng = eep_config.max_host_qng;
15686 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15687 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
15688 asc_dvc->start_motor = eep_config.start_motor;
15689 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
15690 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
15691 asc_dvc->no_scam = eep_config.scam_tolerant;
15692 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
15693 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
15694 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
15695
15696 /*
15697 * For every Target ID if any of its 'sdtr_speed[1234]' bits
15698 * are set, then set an 'sdtr_able' bit for it.
15699 */
15700 asc_dvc->sdtr_able = 0;
15701 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
15702 if (tid == 0) {
15703 sdtr_speed = asc_dvc->sdtr_speed1;
15704 } else if (tid == 4) {
15705 sdtr_speed = asc_dvc->sdtr_speed2;
15706 } else if (tid == 8) {
15707 sdtr_speed = asc_dvc->sdtr_speed3;
15708 } else if (tid == 12) {
15709 sdtr_speed = asc_dvc->sdtr_speed4;
15710 }
15711 if (sdtr_speed & ADV_MAX_TID) {
15712 asc_dvc->sdtr_able |= (1 << tid);
15713 }
15714 sdtr_speed >>= 4;
15715 }
15716
15717 /*
15718 * Set the host maximum queuing (max. 253, min. 16) and the per device
15719 * maximum queuing (max. 63, min. 4).
15720 */
15721 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
15722 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15723 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
15724 /* If the value is zero, assume it is uninitialized. */
15725 if (eep_config.max_host_qng == 0) {
15726 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15727 } else {
15728 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
15729 }
15730 }
15731
15732 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
15733 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15734 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
15735 /* If the value is zero, assume it is uninitialized. */
15736 if (eep_config.max_dvc_qng == 0) {
15737 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15738 } else {
15739 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
15740 }
15741 }
15742
15743 /*
15744 * If 'max_dvc_qng' is greater than 'max_host_qng', then
15745 * set 'max_dvc_qng' to 'max_host_qng'.
15746 */
15747 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
15748 eep_config.max_dvc_qng = eep_config.max_host_qng;
15749 }
15750
15751 /*
15752 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
15753 * values based on possibly adjusted EEPROM values.
15754 */
15755 asc_dvc->max_host_qng = eep_config.max_host_qng;
15756 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15757
15758 /*
15759 * If the EEPROM 'termination' field is set to automatic (0), then set
15760 * the ADV_DVC_CFG 'termination' field to automatic also.
15761 *
15762 * If the termination is specified with a non-zero 'termination'
15763 * value check that a legal value is set and set the ADV_DVC_CFG
15764 * 'termination' field appropriately.
15765 */
15766 if (eep_config.termination_se == 0) {
15767 termination = 0; /* auto termination for SE */
15768 } else {
15769 /* Enable manual control with low off / high off. */
15770 if (eep_config.termination_se == 1) {
15771 termination = 0;
15772
15773 /* Enable manual control with low off / high on. */
15774 } else if (eep_config.termination_se == 2) {
15775 termination = TERM_SE_HI;
15776
15777 /* Enable manual control with low on / high on. */
15778 } else if (eep_config.termination_se == 3) {
15779 termination = TERM_SE;
15780 } else {
15781 /*
15782 * The EEPROM 'termination_se' field contains a bad value.
15783 * Use automatic termination instead.
15784 */
15785 termination = 0;
15786 warn_code |= ASC_WARN_EEPROM_TERMINATION;
15787 }
15788 }
15789
15790 if (eep_config.termination_lvd == 0) {
15791 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
15792 } else {
15793 /* Enable manual control with low off / high off. */
15794 if (eep_config.termination_lvd == 1) {
15795 asc_dvc->cfg->termination = termination;
15796
15797 /* Enable manual control with low off / high on. */
15798 } else if (eep_config.termination_lvd == 2) {
15799 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
15800
15801 /* Enable manual control with low on / high on. */
15802 } else if (eep_config.termination_lvd == 3) {
15803 asc_dvc->cfg->termination = termination | TERM_LVD;
15804 } else {
15805 /*
15806 * The EEPROM 'termination_lvd' field contains a bad value.
15807 * Use automatic termination instead.
15808 */
15809 asc_dvc->cfg->termination = termination;
15810 warn_code |= ASC_WARN_EEPROM_TERMINATION;
15811 }
15812 }
15813
15814 return warn_code;
15815 }
15816
15817 /*
15818 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
15819 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
15820 * all of this is done.
15821 *
15822 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
15823 *
15824 * For a non-fatal error return a warning code. If there are no warnings
15825 * then 0 is returned.
15826 *
15827 * Note: Chip is stopped on entry.
15828 */
15829 static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
15830 {
15831 AdvPortAddr iop_base;
15832 ushort warn_code;
15833 ADVEEP_38C1600_CONFIG eep_config;
15834 int i;
15835 uchar tid, termination;
15836 ushort sdtr_speed = 0;
15837
15838 iop_base = asc_dvc->iop_base;
15839
15840 warn_code = 0;
15841
15842 /*
15843 * Read the board's EEPROM configuration.
15844 *
15845 * Set default values if a bad checksum is found.
15846 */
15847 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
15848 eep_config.check_sum) {
15849 warn_code |= ASC_WARN_EEPROM_CHKSUM;
15850
15851 /*
15852 * Set EEPROM default values.
15853 */
15854 for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++) {
15855 if (i == 1
15856 && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) !=
15857 0) {
15858 /*
15859 * Set Function 1 EEPROM Word 0 MSB
15860 *
15861 * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11)
15862 * EEPROM bits.
15863 *
15864 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and
15865 * old Mac system booting problem. The Expansion ROM must
15866 * be disabled in Function 1 for these systems.
15867 *
15868 */
15869 *((uchar *)&eep_config + i) =
15870 ((*
15871 ((uchar *)&Default_38C1600_EEPROM_Config
15872 +
15873 i)) &
15874 (~
15875 (((ADV_EEPROM_BIOS_ENABLE |
15876 ADV_EEPROM_INTAB) >> 8) & 0xFF)));
15877
15878 /*
15879 * Set the INTAB (bit 11) if the GPIO 0 input indicates
15880 * the Function 1 interrupt line is wired to INTA.
15881 *
15882 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
15883 * 1 - Function 1 interrupt line wired to INT A.
15884 * 0 - Function 1 interrupt line wired to INT B.
15885 *
15886 * Note: Adapter boards always have Function 0 wired to INTA.
15887 * Put all 5 GPIO bits in input mode and then read
15888 * their input values.
15889 */
15890 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL,
15891 0);
15892 if (AdvReadByteRegister
15893 (iop_base, IOPB_GPIO_DATA) & 0x01) {
15894 /* Function 1 interrupt wired to INTA; Set EEPROM bit. */
15895 *((uchar *)&eep_config + i) |=
15896 ((ADV_EEPROM_INTAB >> 8) & 0xFF);
15897 }
15898 } else {
15899 *((uchar *)&eep_config + i) =
15900 *((uchar *)&Default_38C1600_EEPROM_Config
15901 + i);
15902 }
15903 }
15904
15905 /*
15906 * Assume the 6 byte board serial number that was read
15907 * from EEPROM is correct even if the EEPROM checksum
15908 * failed.
15909 */
15910 eep_config.serial_number_word3 =
15911 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
15912
15913 eep_config.serial_number_word2 =
15914 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
15915
15916 eep_config.serial_number_word1 =
15917 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
15918
15919 AdvSet38C1600EEPConfig(iop_base, &eep_config);
15920 }
15921
15922 /*
15923 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
15924 * EEPROM configuration that was read.
15925 *
15926 * This is the mapping of EEPROM fields to Adv Library fields.
15927 */
15928 asc_dvc->wdtr_able = eep_config.wdtr_able;
15929 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
15930 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
15931 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
15932 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
15933 asc_dvc->ppr_able = 0;
15934 asc_dvc->tagqng_able = eep_config.tagqng_able;
15935 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
15936 asc_dvc->max_host_qng = eep_config.max_host_qng;
15937 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15938 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
15939 asc_dvc->start_motor = eep_config.start_motor;
15940 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
15941 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
15942 asc_dvc->no_scam = eep_config.scam_tolerant;
15943
15944 /*
15945 * For every Target ID if any of its 'sdtr_speed[1234]' bits
15946 * are set, then set an 'sdtr_able' bit for it.
15947 */
15948 asc_dvc->sdtr_able = 0;
15949 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15950 if (tid == 0) {
15951 sdtr_speed = asc_dvc->sdtr_speed1;
15952 } else if (tid == 4) {
15953 sdtr_speed = asc_dvc->sdtr_speed2;
15954 } else if (tid == 8) {
15955 sdtr_speed = asc_dvc->sdtr_speed3;
15956 } else if (tid == 12) {
15957 sdtr_speed = asc_dvc->sdtr_speed4;
15958 }
15959 if (sdtr_speed & ASC_MAX_TID) {
15960 asc_dvc->sdtr_able |= (1 << tid);
15961 }
15962 sdtr_speed >>= 4;
15963 }
15964
15965 /*
15966 * Set the host maximum queuing (max. 253, min. 16) and the per device
15967 * maximum queuing (max. 63, min. 4).
15968 */
15969 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
15970 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15971 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
15972 /* If the value is zero, assume it is uninitialized. */
15973 if (eep_config.max_host_qng == 0) {
15974 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15975 } else {
15976 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
15977 }
15978 }
15979
15980 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
15981 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15982 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
15983 /* If the value is zero, assume it is uninitialized. */
15984 if (eep_config.max_dvc_qng == 0) {
15985 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15986 } else {
15987 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
15988 }
15989 }
15990
15991 /*
15992 * If 'max_dvc_qng' is greater than 'max_host_qng', then
15993 * set 'max_dvc_qng' to 'max_host_qng'.
15994 */
15995 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
15996 eep_config.max_dvc_qng = eep_config.max_host_qng;
15997 }
15998
15999 /*
16000 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
16001 * values based on possibly adjusted EEPROM values.
16002 */
16003 asc_dvc->max_host_qng = eep_config.max_host_qng;
16004 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16005
16006 /*
16007 * If the EEPROM 'termination' field is set to automatic (0), then set
16008 * the ASC_DVC_CFG 'termination' field to automatic also.
16009 *
16010 * If the termination is specified with a non-zero 'termination'
16011 * value check that a legal value is set and set the ASC_DVC_CFG
16012 * 'termination' field appropriately.
16013 */
16014 if (eep_config.termination_se == 0) {
16015 termination = 0; /* auto termination for SE */
16016 } else {
16017 /* Enable manual control with low off / high off. */
16018 if (eep_config.termination_se == 1) {
16019 termination = 0;
16020
16021 /* Enable manual control with low off / high on. */
16022 } else if (eep_config.termination_se == 2) {
16023 termination = TERM_SE_HI;
16024
16025 /* Enable manual control with low on / high on. */
16026 } else if (eep_config.termination_se == 3) {
16027 termination = TERM_SE;
16028 } else {
16029 /*
16030 * The EEPROM 'termination_se' field contains a bad value.
16031 * Use automatic termination instead.
16032 */
16033 termination = 0;
16034 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16035 }
16036 }
16037
16038 if (eep_config.termination_lvd == 0) {
16039 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
16040 } else {
16041 /* Enable manual control with low off / high off. */
16042 if (eep_config.termination_lvd == 1) {
16043 asc_dvc->cfg->termination = termination;
16044
16045 /* Enable manual control with low off / high on. */
16046 } else if (eep_config.termination_lvd == 2) {
16047 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16048
16049 /* Enable manual control with low on / high on. */
16050 } else if (eep_config.termination_lvd == 3) {
16051 asc_dvc->cfg->termination = termination | TERM_LVD;
16052 } else {
16053 /*
16054 * The EEPROM 'termination_lvd' field contains a bad value.
16055 * Use automatic termination instead.
16056 */
16057 asc_dvc->cfg->termination = termination;
16058 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16059 }
16060 }
16061
16062 return warn_code;
16063 }
16064
16065 /*
16066 * Read EEPROM configuration into the specified buffer.
16067 *
16068 * Return a checksum based on the EEPROM configuration read.
16069 */
16070 static ushort __devinit
16071 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16072 {
16073 ushort wval, chksum;
16074 ushort *wbuf;
16075 int eep_addr;
16076 ushort *charfields;
16077
16078 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16079 wbuf = (ushort *)cfg_buf;
16080 chksum = 0;
16081
16082 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16083 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16084 wval = AdvReadEEPWord(iop_base, eep_addr);
16085 chksum += wval; /* Checksum is calculated from word values. */
16086 if (*charfields++) {
16087 *wbuf = le16_to_cpu(wval);
16088 } else {
16089 *wbuf = wval;
16090 }
16091 }
16092 /* Read checksum word. */
16093 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16094 wbuf++;
16095 charfields++;
16096
16097 /* Read rest of EEPROM not covered by the checksum. */
16098 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16099 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16100 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16101 if (*charfields++) {
16102 *wbuf = le16_to_cpu(*wbuf);
16103 }
16104 }
16105 return chksum;
16106 }
16107
16108 /*
16109 * Read EEPROM configuration into the specified buffer.
16110 *
16111 * Return a checksum based on the EEPROM configuration read.
16112 */
16113 static ushort __devinit
16114 AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
16115 {
16116 ushort wval, chksum;
16117 ushort *wbuf;
16118 int eep_addr;
16119 ushort *charfields;
16120
16121 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16122 wbuf = (ushort *)cfg_buf;
16123 chksum = 0;
16124
16125 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16126 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16127 wval = AdvReadEEPWord(iop_base, eep_addr);
16128 chksum += wval; /* Checksum is calculated from word values. */
16129 if (*charfields++) {
16130 *wbuf = le16_to_cpu(wval);
16131 } else {
16132 *wbuf = wval;
16133 }
16134 }
16135 /* Read checksum word. */
16136 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16137 wbuf++;
16138 charfields++;
16139
16140 /* Read rest of EEPROM not covered by the checksum. */
16141 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16142 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16143 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16144 if (*charfields++) {
16145 *wbuf = le16_to_cpu(*wbuf);
16146 }
16147 }
16148 return chksum;
16149 }
16150
16151 /*
16152 * Read EEPROM configuration into the specified buffer.
16153 *
16154 * Return a checksum based on the EEPROM configuration read.
16155 */
16156 static ushort __devinit
16157 AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
16158 {
16159 ushort wval, chksum;
16160 ushort *wbuf;
16161 int eep_addr;
16162 ushort *charfields;
16163
16164 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16165 wbuf = (ushort *)cfg_buf;
16166 chksum = 0;
16167
16168 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16169 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16170 wval = AdvReadEEPWord(iop_base, eep_addr);
16171 chksum += wval; /* Checksum is calculated from word values. */
16172 if (*charfields++) {
16173 *wbuf = le16_to_cpu(wval);
16174 } else {
16175 *wbuf = wval;
16176 }
16177 }
16178 /* Read checksum word. */
16179 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16180 wbuf++;
16181 charfields++;
16182
16183 /* Read rest of EEPROM not covered by the checksum. */
16184 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16185 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16186 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16187 if (*charfields++) {
16188 *wbuf = le16_to_cpu(*wbuf);
16189 }
16190 }
16191 return chksum;
16192 }
16193
16194 /*
16195 * Read the EEPROM from specified location
16196 */
16197 static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
16198 {
16199 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16200 ASC_EEP_CMD_READ | eep_word_addr);
16201 AdvWaitEEPCmd(iop_base);
16202 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
16203 }
16204
16205 /*
16206 * Wait for EEPROM command to complete
16207 */
16208 static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
16209 {
16210 int eep_delay_ms;
16211
16212 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
16213 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
16214 ASC_EEP_CMD_DONE) {
16215 break;
16216 }
16217 DvcSleepMilliSecond(1);
16218 }
16219 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
16220 0) {
16221 ASC_ASSERT(0);
16222 }
16223 return;
16224 }
16225
16226 /*
16227 * Write the EEPROM from 'cfg_buf'.
16228 */
16229 void __devinit
16230 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16231 {
16232 ushort *wbuf;
16233 ushort addr, chksum;
16234 ushort *charfields;
16235
16236 wbuf = (ushort *)cfg_buf;
16237 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16238 chksum = 0;
16239
16240 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16241 AdvWaitEEPCmd(iop_base);
16242
16243 /*
16244 * Write EEPROM from word 0 to word 20.
16245 */
16246 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16247 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16248 ushort word;
16249
16250 if (*charfields++) {
16251 word = cpu_to_le16(*wbuf);
16252 } else {
16253 word = *wbuf;
16254 }
16255 chksum += *wbuf; /* Checksum is calculated from word values. */
16256 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16257 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16258 ASC_EEP_CMD_WRITE | addr);
16259 AdvWaitEEPCmd(iop_base);
16260 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16261 }
16262
16263 /*
16264 * Write EEPROM checksum at word 21.
16265 */
16266 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16267 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16268 AdvWaitEEPCmd(iop_base);
16269 wbuf++;
16270 charfields++;
16271
16272 /*
16273 * Write EEPROM OEM name at words 22 to 29.
16274 */
16275 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16276 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16277 ushort word;
16278
16279 if (*charfields++) {
16280 word = cpu_to_le16(*wbuf);
16281 } else {
16282 word = *wbuf;
16283 }
16284 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16285 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16286 ASC_EEP_CMD_WRITE | addr);
16287 AdvWaitEEPCmd(iop_base);
16288 }
16289 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16290 AdvWaitEEPCmd(iop_base);
16291 return;
16292 }
16293
16294 /*
16295 * Write the EEPROM from 'cfg_buf'.
16296 */
16297 void __devinit
16298 AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
16299 {
16300 ushort *wbuf;
16301 ushort *charfields;
16302 ushort addr, chksum;
16303
16304 wbuf = (ushort *)cfg_buf;
16305 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16306 chksum = 0;
16307
16308 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16309 AdvWaitEEPCmd(iop_base);
16310
16311 /*
16312 * Write EEPROM from word 0 to word 20.
16313 */
16314 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16315 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16316 ushort word;
16317
16318 if (*charfields++) {
16319 word = cpu_to_le16(*wbuf);
16320 } else {
16321 word = *wbuf;
16322 }
16323 chksum += *wbuf; /* Checksum is calculated from word values. */
16324 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16325 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16326 ASC_EEP_CMD_WRITE | addr);
16327 AdvWaitEEPCmd(iop_base);
16328 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16329 }
16330
16331 /*
16332 * Write EEPROM checksum at word 21.
16333 */
16334 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16335 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16336 AdvWaitEEPCmd(iop_base);
16337 wbuf++;
16338 charfields++;
16339
16340 /*
16341 * Write EEPROM OEM name at words 22 to 29.
16342 */
16343 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16344 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16345 ushort word;
16346
16347 if (*charfields++) {
16348 word = cpu_to_le16(*wbuf);
16349 } else {
16350 word = *wbuf;
16351 }
16352 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16353 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16354 ASC_EEP_CMD_WRITE | addr);
16355 AdvWaitEEPCmd(iop_base);
16356 }
16357 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16358 AdvWaitEEPCmd(iop_base);
16359 return;
16360 }
16361
16362 /*
16363 * Write the EEPROM from 'cfg_buf'.
16364 */
16365 void __devinit
16366 AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
16367 {
16368 ushort *wbuf;
16369 ushort *charfields;
16370 ushort addr, chksum;
16371
16372 wbuf = (ushort *)cfg_buf;
16373 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16374 chksum = 0;
16375
16376 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16377 AdvWaitEEPCmd(iop_base);
16378
16379 /*
16380 * Write EEPROM from word 0 to word 20.
16381 */
16382 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16383 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16384 ushort word;
16385
16386 if (*charfields++) {
16387 word = cpu_to_le16(*wbuf);
16388 } else {
16389 word = *wbuf;
16390 }
16391 chksum += *wbuf; /* Checksum is calculated from word values. */
16392 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16393 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16394 ASC_EEP_CMD_WRITE | addr);
16395 AdvWaitEEPCmd(iop_base);
16396 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16397 }
16398
16399 /*
16400 * Write EEPROM checksum at word 21.
16401 */
16402 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16403 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16404 AdvWaitEEPCmd(iop_base);
16405 wbuf++;
16406 charfields++;
16407
16408 /*
16409 * Write EEPROM OEM name at words 22 to 29.
16410 */
16411 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16412 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16413 ushort word;
16414
16415 if (*charfields++) {
16416 word = cpu_to_le16(*wbuf);
16417 } else {
16418 word = *wbuf;
16419 }
16420 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16421 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16422 ASC_EEP_CMD_WRITE | addr);
16423 AdvWaitEEPCmd(iop_base);
16424 }
16425 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16426 AdvWaitEEPCmd(iop_base);
16427 return;
16428 }
16429
16430 /* a_advlib.c */
16431 /*
16432 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
16433 *
16434 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
16435 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
16436 * RISC to notify it a new command is ready to be executed.
16437 *
16438 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
16439 * set to SCSI_MAX_RETRY.
16440 *
16441 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
16442 * for DMA addresses or math operations are byte swapped to little-endian
16443 * order.
16444 *
16445 * Return:
16446 * ADV_SUCCESS(1) - The request was successfully queued.
16447 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
16448 * request completes.
16449 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
16450 * host IC error.
16451 */
16452 static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
16453 {
16454 ulong last_int_level;
16455 AdvPortAddr iop_base;
16456 ADV_DCNT req_size;
16457 ADV_PADDR req_paddr;
16458 ADV_CARR_T *new_carrp;
16459
16460 ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
16461
16462 /*
16463 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
16464 */
16465 if (scsiq->target_id > ADV_MAX_TID) {
16466 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
16467 scsiq->done_status = QD_WITH_ERROR;
16468 return ADV_ERROR;
16469 }
16470
16471 iop_base = asc_dvc->iop_base;
16472
16473 last_int_level = DvcEnterCritical();
16474
16475 /*
16476 * Allocate a carrier ensuring at least one carrier always
16477 * remains on the freelist and initialize fields.
16478 */
16479 if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
16480 DvcLeaveCritical(last_int_level);
16481 return ADV_BUSY;
16482 }
16483 asc_dvc->carr_freelist = (ADV_CARR_T *)
16484 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
16485 asc_dvc->carr_pending_cnt++;
16486
16487 /*
16488 * Set the carrier to be a stopper by setting 'next_vpa'
16489 * to the stopper value. The current stopper will be changed
16490 * below to point to the new stopper.
16491 */
16492 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16493
16494 /*
16495 * Clear the ADV_SCSI_REQ_Q done flag.
16496 */
16497 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
16498
16499 req_size = sizeof(ADV_SCSI_REQ_Q);
16500 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
16501 (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
16502
16503 ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
16504 ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
16505
16506 /* Wait for assertion before making little-endian */
16507 req_paddr = cpu_to_le32(req_paddr);
16508
16509 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
16510 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
16511 scsiq->scsiq_rptr = req_paddr;
16512
16513 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
16514 /*
16515 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
16516 * order during initialization.
16517 */
16518 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
16519
16520 /*
16521 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
16522 * the microcode. The newly allocated stopper will become the new
16523 * stopper.
16524 */
16525 asc_dvc->icq_sp->areq_vpa = req_paddr;
16526
16527 /*
16528 * Set the 'next_vpa' pointer for the old stopper to be the
16529 * physical address of the new stopper. The RISC can only
16530 * follow physical addresses.
16531 */
16532 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
16533
16534 /*
16535 * Set the host adapter stopper pointer to point to the new carrier.
16536 */
16537 asc_dvc->icq_sp = new_carrp;
16538
16539 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
16540 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
16541 /*
16542 * Tickle the RISC to tell it to read its Command Queue Head pointer.
16543 */
16544 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
16545 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
16546 /*
16547 * Clear the tickle value. In the ASC-3550 the RISC flag
16548 * command 'clr_tickle_a' does not work unless the host
16549 * value is cleared.
16550 */
16551 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
16552 ADV_TICKLE_NOP);
16553 }
16554 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16555 /*
16556 * Notify the RISC a carrier is ready by writing the physical
16557 * address of the new carrier stopper to the COMMA register.
16558 */
16559 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
16560 le32_to_cpu(new_carrp->carr_pa));
16561 }
16562
16563 DvcLeaveCritical(last_int_level);
16564
16565 return ADV_SUCCESS;
16566 }
16567
16568 /*
16569 * Reset SCSI Bus and purge all outstanding requests.
16570 *
16571 * Return Value:
16572 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
16573 * ADV_FALSE(0) - Microcode command failed.
16574 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
16575 * may be hung which requires driver recovery.
16576 */
16577 static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
16578 {
16579 int status;
16580
16581 /*
16582 * Send the SCSI Bus Reset idle start idle command which asserts
16583 * the SCSI Bus Reset signal.
16584 */
16585 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
16586 if (status != ADV_TRUE) {
16587 return status;
16588 }
16589
16590 /*
16591 * Delay for the specified SCSI Bus Reset hold time.
16592 *
16593 * The hold time delay is done on the host because the RISC has no
16594 * microsecond accurate timer.
16595 */
16596 DvcDelayMicroSecond(asc_dvc, (ushort)ASC_SCSI_RESET_HOLD_TIME_US);
16597
16598 /*
16599 * Send the SCSI Bus Reset end idle command which de-asserts
16600 * the SCSI Bus Reset signal and purges any pending requests.
16601 */
16602 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
16603 if (status != ADV_TRUE) {
16604 return status;
16605 }
16606
16607 DvcSleepMilliSecond((ADV_DCNT)asc_dvc->scsi_reset_wait * 1000);
16608
16609 return status;
16610 }
16611
16612 /*
16613 * Reset chip and SCSI Bus.
16614 *
16615 * Return Value:
16616 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
16617 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
16618 */
16619 static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
16620 {
16621 int status;
16622 ushort wdtr_able, sdtr_able, tagqng_able;
16623 ushort ppr_able = 0;
16624 uchar tid, max_cmd[ADV_MAX_TID + 1];
16625 AdvPortAddr iop_base;
16626 ushort bios_sig;
16627
16628 iop_base = asc_dvc->iop_base;
16629
16630 /*
16631 * Save current per TID negotiated values.
16632 */
16633 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16634 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16635 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16636 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16637 }
16638 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16639 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
16640 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16641 max_cmd[tid]);
16642 }
16643
16644 /*
16645 * Force the AdvInitAsc3550/38C0800Driver() function to
16646 * perform a SCSI Bus Reset by clearing the BIOS signature word.
16647 * The initialization functions assumes a SCSI Bus Reset is not
16648 * needed if the BIOS signature word is present.
16649 */
16650 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
16651 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
16652
16653 /*
16654 * Stop chip and reset it.
16655 */
16656 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
16657 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
16658 DvcSleepMilliSecond(100);
16659 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
16660 ADV_CTRL_REG_CMD_WR_IO_REG);
16661
16662 /*
16663 * Reset Adv Library error code, if any, and try
16664 * re-initializing the chip.
16665 */
16666 asc_dvc->err_code = 0;
16667 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16668 status = AdvInitAsc38C1600Driver(asc_dvc);
16669 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
16670 status = AdvInitAsc38C0800Driver(asc_dvc);
16671 } else {
16672 status = AdvInitAsc3550Driver(asc_dvc);
16673 }
16674
16675 /* Translate initialization return value to status value. */
16676 if (status == 0) {
16677 status = ADV_TRUE;
16678 } else {
16679 status = ADV_FALSE;
16680 }
16681
16682 /*
16683 * Restore the BIOS signature word.
16684 */
16685 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
16686
16687 /*
16688 * Restore per TID negotiated values.
16689 */
16690 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16691 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16692 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16693 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16694 }
16695 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16696 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
16697 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16698 max_cmd[tid]);
16699 }
16700
16701 return status;
16702 }
16703
16704 /*
16705 * Adv Library Interrupt Service Routine
16706 *
16707 * This function is called by a driver's interrupt service routine.
16708 * The function disables and re-enables interrupts.
16709 *
16710 * When a microcode idle command is completed, the ADV_DVC_VAR
16711 * 'idle_cmd_done' field is set to ADV_TRUE.
16712 *
16713 * Note: AdvISR() can be called when interrupts are disabled or even
16714 * when there is no hardware interrupt condition present. It will
16715 * always check for completed idle commands and microcode requests.
16716 * This is an important feature that shouldn't be changed because it
16717 * allows commands to be completed from polling mode loops.
16718 *
16719 * Return:
16720 * ADV_TRUE(1) - interrupt was pending
16721 * ADV_FALSE(0) - no interrupt was pending
16722 */
16723 static int AdvISR(ADV_DVC_VAR *asc_dvc)
16724 {
16725 AdvPortAddr iop_base;
16726 uchar int_stat;
16727 ushort target_bit;
16728 ADV_CARR_T *free_carrp;
16729 ADV_VADDR irq_next_vpa;
16730 int flags;
16731 ADV_SCSI_REQ_Q *scsiq;
16732
16733 flags = DvcEnterCritical();
16734
16735 iop_base = asc_dvc->iop_base;
16736
16737 /* Reading the register clears the interrupt. */
16738 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
16739
16740 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
16741 ADV_INTR_STATUS_INTRC)) == 0) {
16742 DvcLeaveCritical(flags);
16743 return ADV_FALSE;
16744 }
16745
16746 /*
16747 * Notify the driver of an asynchronous microcode condition by
16748 * calling the ADV_DVC_VAR.async_callback function. The function
16749 * is passed the microcode ASC_MC_INTRB_CODE byte value.
16750 */
16751 if (int_stat & ADV_INTR_STATUS_INTRB) {
16752 uchar intrb_code;
16753
16754 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
16755
16756 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
16757 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
16758 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
16759 asc_dvc->carr_pending_cnt != 0) {
16760 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
16761 ADV_TICKLE_A);
16762 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
16763 AdvWriteByteRegister(iop_base,
16764 IOPB_TICKLE,
16765 ADV_TICKLE_NOP);
16766 }
16767 }
16768 }
16769
16770 if (asc_dvc->async_callback != 0) {
16771 (*asc_dvc->async_callback) (asc_dvc, intrb_code);
16772 }
16773 }
16774
16775 /*
16776 * Check if the IRQ stopper carrier contains a completed request.
16777 */
16778 while (((irq_next_vpa =
16779 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
16780 /*
16781 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
16782 * The RISC will have set 'areq_vpa' to a virtual address.
16783 *
16784 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
16785 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
16786 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
16787 * in AdvExeScsiQueue().
16788 */
16789 scsiq = (ADV_SCSI_REQ_Q *)
16790 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
16791
16792 /*
16793 * Request finished with good status and the queue was not
16794 * DMAed to host memory by the firmware. Set all status fields
16795 * to indicate good status.
16796 */
16797 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
16798 scsiq->done_status = QD_NO_ERROR;
16799 scsiq->host_status = scsiq->scsi_status = 0;
16800 scsiq->data_cnt = 0L;
16801 }
16802
16803 /*
16804 * Advance the stopper pointer to the next carrier
16805 * ignoring the lower four bits. Free the previous
16806 * stopper carrier.
16807 */
16808 free_carrp = asc_dvc->irq_sp;
16809 asc_dvc->irq_sp = (ADV_CARR_T *)
16810 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
16811
16812 free_carrp->next_vpa =
16813 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
16814 asc_dvc->carr_freelist = free_carrp;
16815 asc_dvc->carr_pending_cnt--;
16816
16817 ASC_ASSERT(scsiq != NULL);
16818 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
16819
16820 /*
16821 * Clear request microcode control flag.
16822 */
16823 scsiq->cntl = 0;
16824
16825 /*
16826 * Notify the driver of the completed request by passing
16827 * the ADV_SCSI_REQ_Q pointer to its callback function.
16828 */
16829 scsiq->a_flag |= ADV_SCSIQ_DONE;
16830 (*asc_dvc->isr_callback) (asc_dvc, scsiq);
16831 /*
16832 * Note: After the driver callback function is called, 'scsiq'
16833 * can no longer be referenced.
16834 *
16835 * Fall through and continue processing other completed
16836 * requests...
16837 */
16838
16839 /*
16840 * Disable interrupts again in case the driver inadvertently
16841 * enabled interrupts in its callback function.
16842 *
16843 * The DvcEnterCritical() return value is ignored, because
16844 * the 'flags' saved when AdvISR() was first entered will be
16845 * used to restore the interrupt flag on exit.
16846 */
16847 (void)DvcEnterCritical();
16848 }
16849 DvcLeaveCritical(flags);
16850 return ADV_TRUE;
16851 }
16852
16853 /*
16854 * Send an idle command to the chip and wait for completion.
16855 *
16856 * Command completion is polled for once per microsecond.
16857 *
16858 * The function can be called from anywhere including an interrupt handler.
16859 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
16860 * functions to prevent reentrancy.
16861 *
16862 * Return Values:
16863 * ADV_TRUE - command completed successfully
16864 * ADV_FALSE - command failed
16865 * ADV_ERROR - command timed out
16866 */
16867 static int
16868 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
16869 ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
16870 {
16871 ulong last_int_level;
16872 int result;
16873 ADV_DCNT i, j;
16874 AdvPortAddr iop_base;
16875
16876 last_int_level = DvcEnterCritical();
16877
16878 iop_base = asc_dvc->iop_base;
16879
16880 /*
16881 * Clear the idle command status which is set by the microcode
16882 * to a non-zero value to indicate when the command is completed.
16883 * The non-zero result is one of the IDLE_CMD_STATUS_* values
16884 * defined in a_advlib.h.
16885 */
16886 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
16887
16888 /*
16889 * Write the idle command value after the idle command parameter
16890 * has been written to avoid a race condition. If the order is not
16891 * followed, the microcode may process the idle command before the
16892 * parameters have been written to LRAM.
16893 */
16894 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
16895 cpu_to_le32(idle_cmd_parameter));
16896 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
16897
16898 /*
16899 * Tickle the RISC to tell it to process the idle command.
16900 */
16901 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
16902 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
16903 /*
16904 * Clear the tickle value. In the ASC-3550 the RISC flag
16905 * command 'clr_tickle_b' does not work unless the host
16906 * value is cleared.
16907 */
16908 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
16909 }
16910
16911 /* Wait for up to 100 millisecond for the idle command to timeout. */
16912 for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
16913 /* Poll once each microsecond for command completion. */
16914 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
16915 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
16916 result);
16917 if (result != 0) {
16918 DvcLeaveCritical(last_int_level);
16919 return result;
16920 }
16921 DvcDelayMicroSecond(asc_dvc, (ushort)1);
16922 }
16923 }
16924
16925 ASC_ASSERT(0); /* The idle command should never timeout. */
16926 DvcLeaveCritical(last_int_level);
16927 return ADV_ERROR;
16928 }
16929
16930 static int __devinit
16931 advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
16932 {
16933 int req_cnt = 0;
16934 adv_req_t *reqp = NULL;
16935 int sg_cnt = 0;
16936 adv_sgblk_t *sgp;
16937 int warn_code, err_code;
16938
16939 /*
16940 * Allocate buffer carrier structures. The total size
16941 * is about 4 KB, so allocate all at once.
16942 */
16943 boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
16944 ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp);
16945
16946 if (!boardp->carrp)
16947 goto kmalloc_failed;
16948
16949 /*
16950 * Allocate up to 'max_host_qng' request structures for the Wide
16951 * board. The total size is about 16 KB, so allocate all at once.
16952 * If the allocation fails decrement and try again.
16953 */
16954 for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
16955 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
16956
16957 ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, "
16958 "bytes %lu\n", reqp, req_cnt,
16959 (ulong)sizeof(adv_req_t) * req_cnt);
16960
16961 if (reqp)
16962 break;
16963 }
16964
16965 if (!reqp)
16966 goto kmalloc_failed;
16967
16968 boardp->orig_reqp = reqp;
16969
16970 /*
16971 * Allocate up to ADV_TOT_SG_BLOCK request structures for
16972 * the Wide board. Each structure is about 136 bytes.
16973 */
16974 boardp->adv_sgblkp = NULL;
16975 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
16976 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
16977
16978 if (!sgp)
16979 break;
16980
16981 sgp->next_sgblkp = boardp->adv_sgblkp;
16982 boardp->adv_sgblkp = sgp;
16983
16984 }
16985
16986 ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n",
16987 sg_cnt, sizeof(adv_sgblk_t),
16988 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
16989
16990 if (!boardp->adv_sgblkp)
16991 goto kmalloc_failed;
16992
16993 adv_dvc_varp->carrier_buf = boardp->carrp;
16994
16995 /*
16996 * Point 'adv_reqp' to the request structures and
16997 * link them together.
16998 */
16999 req_cnt--;
17000 reqp[req_cnt].next_reqp = NULL;
17001 for (; req_cnt > 0; req_cnt--) {
17002 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
17003 }
17004 boardp->adv_reqp = &reqp[0];
17005
17006 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17007 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n");
17008 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
17009 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17010 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()"
17011 "\n");
17012 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
17013 } else {
17014 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()"
17015 "\n");
17016 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
17017 }
17018 err_code = adv_dvc_varp->err_code;
17019
17020 if (warn_code || err_code) {
17021 ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
17022 " error 0x%x\n", boardp->id, warn_code, err_code);
17023 }
17024
17025 goto exit;
17026
17027 kmalloc_failed:
17028 ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
17029 "failed\n", boardp->id);
17030 err_code = ADV_ERROR;
17031 exit:
17032 return err_code;
17033 }
17034
17035 static void advansys_wide_free_mem(asc_board_t *boardp)
17036 {
17037 kfree(boardp->carrp);
17038 boardp->carrp = NULL;
17039 kfree(boardp->orig_reqp);
17040 boardp->orig_reqp = boardp->adv_reqp = NULL;
17041 while (boardp->adv_sgblkp) {
17042 adv_sgblk_t *sgp = boardp->adv_sgblkp;
17043 boardp->adv_sgblkp = sgp->next_sgblkp;
17044 kfree(sgp);
17045 }
17046 }
17047
17048 static struct Scsi_Host *__devinit
17049 advansys_board_found(int iop, struct device *dev, int bus_type)
17050 {
17051 struct Scsi_Host *shost;
17052 struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL;
17053 asc_board_t *boardp;
17054 ASC_DVC_VAR *asc_dvc_varp = NULL;
17055 ADV_DVC_VAR *adv_dvc_varp = NULL;
17056 int share_irq;
17057 int warn_code, err_code;
17058 int ret;
17059
17060 /*
17061 * Register the adapter, get its configuration, and
17062 * initialize it.
17063 */
17064 ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n");
17065 shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t));
17066 if (!shost)
17067 return NULL;
17068
17069 /* Initialize private per board data */
17070 boardp = ASC_BOARDP(shost);
17071 memset(boardp, 0, sizeof(asc_board_t));
17072 boardp->id = asc_board_count++;
17073 spin_lock_init(&boardp->lock);
17074 boardp->dev = dev;
17075
17076 /*
17077 * Handle both narrow and wide boards.
17078 *
17079 * If a Wide board was detected, set the board structure
17080 * wide board flag. Set-up the board structure based on
17081 * the board type.
17082 */
17083 #ifdef CONFIG_PCI
17084 if (bus_type == ASC_IS_PCI &&
17085 (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
17086 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
17087 pdev->device == PCI_DEVICE_ID_38C1600_REV1)) {
17088 boardp->flags |= ASC_IS_WIDE_BOARD;
17089 }
17090 #endif /* CONFIG_PCI */
17091
17092 if (ASC_NARROW_BOARD(boardp)) {
17093 ASC_DBG(1, "advansys_board_found: narrow board\n");
17094 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
17095 asc_dvc_varp->bus_type = bus_type;
17096 asc_dvc_varp->drv_ptr = boardp;
17097 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
17098 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
17099 asc_dvc_varp->iop_base = iop;
17100 asc_dvc_varp->isr_callback = asc_isr_callback;
17101 } else {
17102 #ifdef CONFIG_PCI
17103 ASC_DBG(1, "advansys_board_found: wide board\n");
17104 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
17105 adv_dvc_varp->drv_ptr = boardp;
17106 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
17107 adv_dvc_varp->isr_callback = adv_isr_callback;
17108 adv_dvc_varp->async_callback = adv_async_callback;
17109 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
17110 ASC_DBG(1, "advansys_board_found: ASC-3550\n");
17111 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
17112 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
17113 ASC_DBG(1, "advansys_board_found: ASC-38C0800\n");
17114 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
17115 } else {
17116 ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
17117 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
17118 }
17119
17120 boardp->asc_n_io_port = pci_resource_len(pdev, 1);
17121 boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1),
17122 boardp->asc_n_io_port);
17123 if (!boardp->ioremap_addr) {
17124 ASC_PRINT3
17125 ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
17126 boardp->id, pci_resource_start(pdev, 1),
17127 boardp->asc_n_io_port);
17128 goto err_shost;
17129 }
17130 adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr
17131 ASC_DBG1(1, "advansys_board_found: iop_base: 0x%lx\n",
17132 adv_dvc_varp->iop_base);
17133
17134 /*
17135 * Even though it isn't used to access wide boards, other
17136 * than for the debug line below, save I/O Port address so
17137 * that it can be reported.
17138 */
17139 boardp->ioport = iop;
17140
17141 ASC_DBG2(1, "advansys_board_found: iopb_chip_id_1 0x%x, "
17142 "iopw_chip_id_0 0x%x\n", (ushort)inp(iop + 1),
17143 (ushort)inpw(iop));
17144 #endif /* CONFIG_PCI */
17145 }
17146
17147 #ifdef CONFIG_PROC_FS
17148 /*
17149 * Allocate buffer for printing information from
17150 * /proc/scsi/advansys/[0...].
17151 */
17152 boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
17153 if (!boardp->prtbuf) {
17154 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
17155 "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
17156 goto err_unmap;
17157 }
17158 #endif /* CONFIG_PROC_FS */
17159
17160 if (ASC_NARROW_BOARD(boardp)) {
17161 /*
17162 * Set the board bus type and PCI IRQ before
17163 * calling AscInitGetConfig().
17164 */
17165 switch (asc_dvc_varp->bus_type) {
17166 #ifdef CONFIG_ISA
17167 case ASC_IS_ISA:
17168 shost->unchecked_isa_dma = TRUE;
17169 share_irq = 0;
17170 break;
17171 case ASC_IS_VL:
17172 shost->unchecked_isa_dma = FALSE;
17173 share_irq = 0;
17174 break;
17175 case ASC_IS_EISA:
17176 shost->unchecked_isa_dma = FALSE;
17177 share_irq = IRQF_SHARED;
17178 break;
17179 #endif /* CONFIG_ISA */
17180 #ifdef CONFIG_PCI
17181 case ASC_IS_PCI:
17182 shost->irq = asc_dvc_varp->irq_no = pdev->irq;
17183 asc_dvc_varp->cfg->pci_slot_info =
17184 ASC_PCI_MKID(pdev->bus->number,
17185 PCI_SLOT(pdev->devfn),
17186 PCI_FUNC(pdev->devfn));
17187 shost->unchecked_isa_dma = FALSE;
17188 share_irq = IRQF_SHARED;
17189 break;
17190 #endif /* CONFIG_PCI */
17191 default:
17192 ASC_PRINT2
17193 ("advansys_board_found: board %d: unknown adapter type: %d\n",
17194 boardp->id, asc_dvc_varp->bus_type);
17195 shost->unchecked_isa_dma = TRUE;
17196 share_irq = 0;
17197 break;
17198 }
17199 } else {
17200 /*
17201 * For Wide boards set PCI information before calling
17202 * AdvInitGetConfig().
17203 */
17204 #ifdef CONFIG_PCI
17205 shost->irq = adv_dvc_varp->irq_no = pdev->irq;
17206 adv_dvc_varp->cfg->pci_slot_info =
17207 ASC_PCI_MKID(pdev->bus->number,
17208 PCI_SLOT(pdev->devfn),
17209 PCI_FUNC(pdev->devfn));
17210 shost->unchecked_isa_dma = FALSE;
17211 share_irq = IRQF_SHARED;
17212 #endif /* CONFIG_PCI */
17213 }
17214
17215 /*
17216 * Read the board configuration.
17217 */
17218 if (ASC_NARROW_BOARD(boardp)) {
17219 /*
17220 * NOTE: AscInitGetConfig() may change the board's
17221 * bus_type value. The bus_type value should no
17222 * longer be used. If the bus_type field must be
17223 * referenced only use the bit-wise AND operator "&".
17224 */
17225 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
17226 switch (ret = AscInitGetConfig(asc_dvc_varp)) {
17227 case 0: /* No error */
17228 break;
17229 case ASC_WARN_IO_PORT_ROTATE:
17230 ASC_PRINT1
17231 ("AscInitGetConfig: board %d: I/O port address modified\n",
17232 boardp->id);
17233 break;
17234 case ASC_WARN_AUTO_CONFIG:
17235 ASC_PRINT1
17236 ("AscInitGetConfig: board %d: I/O port increment switch enabled\n",
17237 boardp->id);
17238 break;
17239 case ASC_WARN_EEPROM_CHKSUM:
17240 ASC_PRINT1
17241 ("AscInitGetConfig: board %d: EEPROM checksum error\n",
17242 boardp->id);
17243 break;
17244 case ASC_WARN_IRQ_MODIFIED:
17245 ASC_PRINT1
17246 ("AscInitGetConfig: board %d: IRQ modified\n",
17247 boardp->id);
17248 break;
17249 case ASC_WARN_CMD_QNG_CONFLICT:
17250 ASC_PRINT1
17251 ("AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
17252 boardp->id);
17253 break;
17254 default:
17255 ASC_PRINT2
17256 ("AscInitGetConfig: board %d: unknown warning: 0x%x\n",
17257 boardp->id, ret);
17258 break;
17259 }
17260 if ((err_code = asc_dvc_varp->err_code) != 0) {
17261 ASC_PRINT3
17262 ("AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
17263 boardp->id,
17264 asc_dvc_varp->init_state, asc_dvc_varp->err_code);
17265 }
17266 } else {
17267 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
17268
17269 ret = AdvInitGetConfig(pdev, adv_dvc_varp);
17270 if (ret != 0) {
17271 ASC_PRINT2
17272 ("AdvInitGetConfig: board %d: warning: 0x%x\n",
17273 boardp->id, ret);
17274 }
17275 if ((err_code = adv_dvc_varp->err_code) != 0) {
17276 ASC_PRINT2
17277 ("AdvInitGetConfig: board %d error: err_code 0x%x\n",
17278 boardp->id, adv_dvc_varp->err_code);
17279 }
17280 }
17281
17282 if (err_code != 0)
17283 goto err_free_proc;
17284
17285 /*
17286 * Save the EEPROM configuration so that it can be displayed
17287 * from /proc/scsi/advansys/[0...].
17288 */
17289 if (ASC_NARROW_BOARD(boardp)) {
17290
17291 ASCEEP_CONFIG *ep;
17292
17293 /*
17294 * Set the adapter's target id bit in the 'init_tidmask' field.
17295 */
17296 boardp->init_tidmask |=
17297 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
17298
17299 /*
17300 * Save EEPROM settings for the board.
17301 */
17302 ep = &boardp->eep_config.asc_eep;
17303
17304 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
17305 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
17306 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
17307 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
17308 ep->start_motor = asc_dvc_varp->start_motor;
17309 ep->cntl = asc_dvc_varp->dvc_cntl;
17310 ep->no_scam = asc_dvc_varp->no_scam;
17311 ep->max_total_qng = asc_dvc_varp->max_total_qng;
17312 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
17313 /* 'max_tag_qng' is set to the same value for every device. */
17314 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
17315 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
17316 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
17317 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
17318 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
17319 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
17320 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
17321
17322 /*
17323 * Modify board configuration.
17324 */
17325 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
17326 switch (ret = AscInitSetConfig(pdev, asc_dvc_varp)) {
17327 case 0: /* No error. */
17328 break;
17329 case ASC_WARN_IO_PORT_ROTATE:
17330 ASC_PRINT1
17331 ("AscInitSetConfig: board %d: I/O port address modified\n",
17332 boardp->id);
17333 break;
17334 case ASC_WARN_AUTO_CONFIG:
17335 ASC_PRINT1
17336 ("AscInitSetConfig: board %d: I/O port increment switch enabled\n",
17337 boardp->id);
17338 break;
17339 case ASC_WARN_EEPROM_CHKSUM:
17340 ASC_PRINT1
17341 ("AscInitSetConfig: board %d: EEPROM checksum error\n",
17342 boardp->id);
17343 break;
17344 case ASC_WARN_IRQ_MODIFIED:
17345 ASC_PRINT1
17346 ("AscInitSetConfig: board %d: IRQ modified\n",
17347 boardp->id);
17348 break;
17349 case ASC_WARN_CMD_QNG_CONFLICT:
17350 ASC_PRINT1
17351 ("AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
17352 boardp->id);
17353 break;
17354 default:
17355 ASC_PRINT2
17356 ("AscInitSetConfig: board %d: unknown warning: 0x%x\n",
17357 boardp->id, ret);
17358 break;
17359 }
17360 if (asc_dvc_varp->err_code != 0) {
17361 ASC_PRINT3
17362 ("AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
17363 boardp->id,
17364 asc_dvc_varp->init_state, asc_dvc_varp->err_code);
17365 goto err_free_proc;
17366 }
17367
17368 /*
17369 * Finish initializing the 'Scsi_Host' structure.
17370 */
17371 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
17372 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
17373 shost->irq = asc_dvc_varp->irq_no;
17374 }
17375 } else {
17376 ADVEEP_3550_CONFIG *ep_3550;
17377 ADVEEP_38C0800_CONFIG *ep_38C0800;
17378 ADVEEP_38C1600_CONFIG *ep_38C1600;
17379
17380 /*
17381 * Save Wide EEP Configuration Information.
17382 */
17383 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17384 ep_3550 = &boardp->eep_config.adv_3550_eep;
17385
17386 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
17387 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
17388 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17389 ep_3550->termination = adv_dvc_varp->cfg->termination;
17390 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
17391 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
17392 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
17393 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
17394 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
17395 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
17396 ep_3550->start_motor = adv_dvc_varp->start_motor;
17397 ep_3550->scsi_reset_delay =
17398 adv_dvc_varp->scsi_reset_wait;
17399 ep_3550->serial_number_word1 =
17400 adv_dvc_varp->cfg->serial1;
17401 ep_3550->serial_number_word2 =
17402 adv_dvc_varp->cfg->serial2;
17403 ep_3550->serial_number_word3 =
17404 adv_dvc_varp->cfg->serial3;
17405 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17406 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
17407
17408 ep_38C0800->adapter_scsi_id =
17409 adv_dvc_varp->chip_scsi_id;
17410 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
17411 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17412 ep_38C0800->termination_lvd =
17413 adv_dvc_varp->cfg->termination;
17414 ep_38C0800->disc_enable =
17415 adv_dvc_varp->cfg->disc_enable;
17416 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
17417 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
17418 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
17419 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
17420 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
17421 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
17422 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
17423 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
17424 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
17425 ep_38C0800->scsi_reset_delay =
17426 adv_dvc_varp->scsi_reset_wait;
17427 ep_38C0800->serial_number_word1 =
17428 adv_dvc_varp->cfg->serial1;
17429 ep_38C0800->serial_number_word2 =
17430 adv_dvc_varp->cfg->serial2;
17431 ep_38C0800->serial_number_word3 =
17432 adv_dvc_varp->cfg->serial3;
17433 } else {
17434 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
17435
17436 ep_38C1600->adapter_scsi_id =
17437 adv_dvc_varp->chip_scsi_id;
17438 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
17439 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17440 ep_38C1600->termination_lvd =
17441 adv_dvc_varp->cfg->termination;
17442 ep_38C1600->disc_enable =
17443 adv_dvc_varp->cfg->disc_enable;
17444 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
17445 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
17446 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
17447 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
17448 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
17449 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
17450 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
17451 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
17452 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
17453 ep_38C1600->scsi_reset_delay =
17454 adv_dvc_varp->scsi_reset_wait;
17455 ep_38C1600->serial_number_word1 =
17456 adv_dvc_varp->cfg->serial1;
17457 ep_38C1600->serial_number_word2 =
17458 adv_dvc_varp->cfg->serial2;
17459 ep_38C1600->serial_number_word3 =
17460 adv_dvc_varp->cfg->serial3;
17461 }
17462
17463 /*
17464 * Set the adapter's target id bit in the 'init_tidmask' field.
17465 */
17466 boardp->init_tidmask |=
17467 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
17468 }
17469
17470 /*
17471 * Channels are numbered beginning with 0. For AdvanSys one host
17472 * structure supports one channel. Multi-channel boards have a
17473 * separate host structure for each channel.
17474 */
17475 shost->max_channel = 0;
17476 if (ASC_NARROW_BOARD(boardp)) {
17477 shost->max_id = ASC_MAX_TID + 1;
17478 shost->max_lun = ASC_MAX_LUN + 1;
17479
17480 shost->io_port = asc_dvc_varp->iop_base;
17481 boardp->asc_n_io_port = ASC_IOADR_GAP;
17482 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
17483
17484 /* Set maximum number of queues the adapter can handle. */
17485 shost->can_queue = asc_dvc_varp->max_total_qng;
17486 } else {
17487 shost->max_id = ADV_MAX_TID + 1;
17488 shost->max_lun = ADV_MAX_LUN + 1;
17489
17490 /*
17491 * Save the I/O Port address and length even though
17492 * I/O ports are not used to access Wide boards.
17493 * Instead the Wide boards are accessed with
17494 * PCI Memory Mapped I/O.
17495 */
17496 shost->io_port = iop;
17497
17498 shost->this_id = adv_dvc_varp->chip_scsi_id;
17499
17500 /* Set maximum number of queues the adapter can handle. */
17501 shost->can_queue = adv_dvc_varp->max_host_qng;
17502 }
17503
17504 /*
17505 * Following v1.3.89, 'cmd_per_lun' is no longer needed
17506 * and should be set to zero.
17507 *
17508 * But because of a bug introduced in v1.3.89 if the driver is
17509 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
17510 * SCSI function 'allocate_device' will panic. To allow the driver
17511 * to work as a module in these kernels set 'cmd_per_lun' to 1.
17512 *
17513 * Note: This is wrong. cmd_per_lun should be set to the depth
17514 * you want on untagged devices always.
17515 #ifdef MODULE
17516 */
17517 shost->cmd_per_lun = 1;
17518 /* #else
17519 shost->cmd_per_lun = 0;
17520 #endif */
17521
17522 /*
17523 * Set the maximum number of scatter-gather elements the
17524 * adapter can handle.
17525 */
17526 if (ASC_NARROW_BOARD(boardp)) {
17527 /*
17528 * Allow two commands with 'sg_tablesize' scatter-gather
17529 * elements to be executed simultaneously. This value is
17530 * the theoretical hardware limit. It may be decreased
17531 * below.
17532 */
17533 shost->sg_tablesize =
17534 (((asc_dvc_varp->max_total_qng - 2) / 2) *
17535 ASC_SG_LIST_PER_Q) + 1;
17536 } else {
17537 shost->sg_tablesize = ADV_MAX_SG_LIST;
17538 }
17539
17540 /*
17541 * The value of 'sg_tablesize' can not exceed the SCSI
17542 * mid-level driver definition of SG_ALL. SG_ALL also
17543 * must not be exceeded, because it is used to define the
17544 * size of the scatter-gather table in 'struct asc_sg_head'.
17545 */
17546 if (shost->sg_tablesize > SG_ALL) {
17547 shost->sg_tablesize = SG_ALL;
17548 }
17549
17550 ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize);
17551
17552 /* BIOS start address. */
17553 if (ASC_NARROW_BOARD(boardp)) {
17554 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
17555 asc_dvc_varp->bus_type);
17556 } else {
17557 /*
17558 * Fill-in BIOS board variables. The Wide BIOS saves
17559 * information in LRAM that is used by the driver.
17560 */
17561 AdvReadWordLram(adv_dvc_varp->iop_base,
17562 BIOS_SIGNATURE, boardp->bios_signature);
17563 AdvReadWordLram(adv_dvc_varp->iop_base,
17564 BIOS_VERSION, boardp->bios_version);
17565 AdvReadWordLram(adv_dvc_varp->iop_base,
17566 BIOS_CODESEG, boardp->bios_codeseg);
17567 AdvReadWordLram(adv_dvc_varp->iop_base,
17568 BIOS_CODELEN, boardp->bios_codelen);
17569
17570 ASC_DBG2(1,
17571 "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n",
17572 boardp->bios_signature, boardp->bios_version);
17573
17574 ASC_DBG2(1,
17575 "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n",
17576 boardp->bios_codeseg, boardp->bios_codelen);
17577
17578 /*
17579 * If the BIOS saved a valid signature, then fill in
17580 * the BIOS code segment base address.
17581 */
17582 if (boardp->bios_signature == 0x55AA) {
17583 /*
17584 * Convert x86 realmode code segment to a linear
17585 * address by shifting left 4.
17586 */
17587 shost->base = ((ulong)boardp->bios_codeseg << 4);
17588 } else {
17589 shost->base = 0;
17590 }
17591 }
17592
17593 /*
17594 * Register Board Resources - I/O Port, DMA, IRQ
17595 */
17596
17597 /* Register DMA Channel for Narrow boards. */
17598 shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
17599 #ifdef CONFIG_ISA
17600 if (ASC_NARROW_BOARD(boardp)) {
17601 /* Register DMA channel for ISA bus. */
17602 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
17603 shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
17604 ret = request_dma(shost->dma_channel, "advansys");
17605 if (ret) {
17606 ASC_PRINT3
17607 ("advansys_board_found: board %d: request_dma() %d failed %d\n",
17608 boardp->id, shost->dma_channel, ret);
17609 goto err_free_proc;
17610 }
17611 AscEnableIsaDma(shost->dma_channel);
17612 }
17613 }
17614 #endif /* CONFIG_ISA */
17615
17616 /* Register IRQ Number. */
17617 ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq);
17618
17619 ret = request_irq(shost->irq, advansys_interrupt, share_irq,
17620 "advansys", shost);
17621
17622 if (ret) {
17623 if (ret == -EBUSY) {
17624 ASC_PRINT2
17625 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
17626 boardp->id, shost->irq);
17627 } else if (ret == -EINVAL) {
17628 ASC_PRINT2
17629 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
17630 boardp->id, shost->irq);
17631 } else {
17632 ASC_PRINT3
17633 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
17634 boardp->id, shost->irq, ret);
17635 }
17636 goto err_free_dma;
17637 }
17638
17639 /*
17640 * Initialize board RISC chip and enable interrupts.
17641 */
17642 if (ASC_NARROW_BOARD(boardp)) {
17643 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
17644 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
17645 err_code = asc_dvc_varp->err_code;
17646
17647 if (warn_code || err_code) {
17648 ASC_PRINT4
17649 ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
17650 boardp->id,
17651 asc_dvc_varp->init_state, warn_code, err_code);
17652 }
17653 } else {
17654 err_code = advansys_wide_init_chip(boardp, adv_dvc_varp);
17655 }
17656
17657 if (err_code != 0)
17658 goto err_free_wide_mem;
17659
17660 ASC_DBG_PRT_SCSI_HOST(2, shost);
17661
17662 ret = scsi_add_host(shost, dev);
17663 if (ret)
17664 goto err_free_wide_mem;
17665
17666 scsi_scan_host(shost);
17667 return shost;
17668
17669 err_free_wide_mem:
17670 advansys_wide_free_mem(boardp);
17671 free_irq(shost->irq, shost);
17672 err_free_dma:
17673 if (shost->dma_channel != NO_ISA_DMA)
17674 free_dma(shost->dma_channel);
17675 err_free_proc:
17676 kfree(boardp->prtbuf);
17677 err_unmap:
17678 if (boardp->ioremap_addr)
17679 iounmap(boardp->ioremap_addr);
17680 err_shost:
17681 scsi_host_put(shost);
17682 return NULL;
17683 }
17684
17685 /*
17686 * advansys_release()
17687 *
17688 * Release resources allocated for a single AdvanSys adapter.
17689 */
17690 static int advansys_release(struct Scsi_Host *shost)
17691 {
17692 asc_board_t *boardp;
17693
17694 ASC_DBG(1, "advansys_release: begin\n");
17695 scsi_remove_host(shost);
17696 boardp = ASC_BOARDP(shost);
17697 free_irq(shost->irq, shost);
17698 if (shost->dma_channel != NO_ISA_DMA) {
17699 ASC_DBG(1, "advansys_release: free_dma()\n");
17700 free_dma(shost->dma_channel);
17701 }
17702 if (ASC_WIDE_BOARD(boardp)) {
17703 iounmap(boardp->ioremap_addr);
17704 advansys_wide_free_mem(boardp);
17705 }
17706 kfree(boardp->prtbuf);
17707 scsi_host_put(shost);
17708 ASC_DBG(1, "advansys_release: end\n");
17709 return 0;
17710 }
17711
17712 static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
17713 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
17714 0x0210, 0x0230, 0x0250, 0x0330
17715 };
17716
17717 static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
17718 {
17719 PortAddr iop_base = _asc_def_iop_base[id];
17720 struct Scsi_Host *shost;
17721
17722 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
17723 ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n",
17724 iop_base);
17725 return -ENODEV;
17726 }
17727 ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base);
17728 if (!AscFindSignature(iop_base))
17729 goto nodev;
17730 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
17731 goto nodev;
17732
17733 shost = advansys_board_found(iop_base, dev, ASC_IS_ISA);
17734 if (!shost)
17735 goto nodev;
17736
17737 dev_set_drvdata(dev, shost);
17738 return 0;
17739
17740 nodev:
17741 release_region(iop_base, ASC_IOADR_GAP);
17742 return -ENODEV;
17743 }
17744
17745 static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
17746 {
17747 int ioport = _asc_def_iop_base[id];
17748 advansys_release(dev_get_drvdata(dev));
17749 release_region(ioport, ASC_IOADR_GAP);
17750 return 0;
17751 }
17752
17753 static struct isa_driver advansys_isa_driver = {
17754 .probe = advansys_isa_probe,
17755 .remove = __devexit_p(advansys_isa_remove),
17756 .driver = {
17757 .owner = THIS_MODULE,
17758 .name = "advansys",
17759 },
17760 };
17761
17762 static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
17763 {
17764 PortAddr iop_base = _asc_def_iop_base[id];
17765 struct Scsi_Host *shost;
17766
17767 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
17768 ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n",
17769 iop_base);
17770 return -ENODEV;
17771 }
17772 ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base);
17773 if (!AscFindSignature(iop_base))
17774 goto nodev;
17775 /*
17776 * I don't think this condition can actually happen, but the old
17777 * driver did it, and the chances of finding a VLB setup in 2007
17778 * to do testing with is slight to none.
17779 */
17780 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
17781 goto nodev;
17782
17783 shost = advansys_board_found(iop_base, dev, ASC_IS_VL);
17784 if (!shost)
17785 goto nodev;
17786
17787 dev_set_drvdata(dev, shost);
17788 return 0;
17789
17790 nodev:
17791 release_region(iop_base, ASC_IOADR_GAP);
17792 return -ENODEV;
17793 }
17794
17795 static struct isa_driver advansys_vlb_driver = {
17796 .probe = advansys_vlb_probe,
17797 .remove = __devexit_p(advansys_isa_remove),
17798 .driver = {
17799 .owner = THIS_MODULE,
17800 .name = "advansys",
17801 },
17802 };
17803
17804 static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
17805 { "ABP7401" },
17806 { "ABP7501" },
17807 { "" }
17808 };
17809
17810 MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
17811
17812 /*
17813 * EISA is a little more tricky than PCI; each EISA device may have two
17814 * channels, and this driver is written to make each channel its own Scsi_Host
17815 */
17816 struct eisa_scsi_data {
17817 struct Scsi_Host *host[2];
17818 };
17819
17820 static int __devinit advansys_eisa_probe(struct device *dev)
17821 {
17822 int i, ioport;
17823 int err;
17824 struct eisa_device *edev = to_eisa_device(dev);
17825 struct eisa_scsi_data *data;
17826
17827 err = -ENOMEM;
17828 data = kzalloc(sizeof(*data), GFP_KERNEL);
17829 if (!data)
17830 goto fail;
17831 ioport = edev->base_addr + 0xc30;
17832
17833 err = -ENODEV;
17834 for (i = 0; i < 2; i++, ioport += 0x20) {
17835 if (!request_region(ioport, ASC_IOADR_GAP, "advansys")) {
17836 printk(KERN_WARNING "Region %x-%x busy\n", ioport,
17837 ioport + ASC_IOADR_GAP - 1);
17838 continue;
17839 }
17840 if (!AscFindSignature(ioport)) {
17841 release_region(ioport, ASC_IOADR_GAP);
17842 continue;
17843 }
17844
17845 /*
17846 * I don't know why we need to do this for EISA chips, but
17847 * not for any others. It looks to be equivalent to
17848 * AscGetChipCfgMsw, but I may have overlooked something,
17849 * so I'm not converting it until I get an EISA board to
17850 * test with.
17851 */
17852 inw(ioport + 4);
17853 data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA);
17854 if (data->host[i]) {
17855 err = 0;
17856 } else {
17857 release_region(ioport, ASC_IOADR_GAP);
17858 }
17859 }
17860
17861 if (err) {
17862 kfree(data);
17863 } else {
17864 dev_set_drvdata(dev, data);
17865 }
17866
17867 fail:
17868 return err;
17869 }
17870
17871 static __devexit int advansys_eisa_remove(struct device *dev)
17872 {
17873 int i;
17874 struct eisa_scsi_data *data = dev_get_drvdata(dev);
17875
17876 for (i = 0; i < 2; i++) {
17877 int ioport;
17878 struct Scsi_Host *shost = data->host[i];
17879 if (!shost)
17880 continue;
17881 ioport = shost->io_port;
17882 advansys_release(shost);
17883 release_region(ioport, ASC_IOADR_GAP);
17884 }
17885
17886 kfree(data);
17887 return 0;
17888 }
17889
17890 static struct eisa_driver advansys_eisa_driver = {
17891 .id_table = advansys_eisa_table,
17892 .driver = {
17893 .name = "advansys",
17894 .probe = advansys_eisa_probe,
17895 .remove = __devexit_p(advansys_eisa_remove),
17896 }
17897 };
17898
17899 /* PCI Devices supported by this driver */
17900 static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
17901 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
17902 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17903 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
17904 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17905 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
17906 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17907 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
17908 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17909 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
17910 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17911 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
17912 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17913 {}
17914 };
17915
17916 MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
17917
17918 static void __devinit advansys_set_latency(struct pci_dev *pdev)
17919 {
17920 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
17921 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
17922 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
17923 } else {
17924 u8 latency;
17925 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
17926 if (latency < 0x20)
17927 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
17928 }
17929 }
17930
17931 static int __devinit
17932 advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
17933 {
17934 int err, ioport;
17935 struct Scsi_Host *shost;
17936
17937 err = pci_enable_device(pdev);
17938 if (err)
17939 goto fail;
17940 err = pci_request_regions(pdev, "advansys");
17941 if (err)
17942 goto disable_device;
17943 pci_set_master(pdev);
17944 advansys_set_latency(pdev);
17945
17946 if (pci_resource_len(pdev, 0) == 0)
17947 goto nodev;
17948
17949 ioport = pci_resource_start(pdev, 0);
17950 shost = advansys_board_found(ioport, &pdev->dev, ASC_IS_PCI);
17951
17952 if (!shost)
17953 goto nodev;
17954
17955 pci_set_drvdata(pdev, shost);
17956 return 0;
17957
17958 nodev:
17959 err = -ENODEV;
17960 pci_release_regions(pdev);
17961 disable_device:
17962 pci_disable_device(pdev);
17963 fail:
17964 return err;
17965 }
17966
17967 static void __devexit advansys_pci_remove(struct pci_dev *pdev)
17968 {
17969 advansys_release(pci_get_drvdata(pdev));
17970 pci_release_regions(pdev);
17971 pci_disable_device(pdev);
17972 }
17973
17974 static struct pci_driver advansys_pci_driver = {
17975 .name = "advansys",
17976 .id_table = advansys_pci_tbl,
17977 .probe = advansys_pci_probe,
17978 .remove = __devexit_p(advansys_pci_remove),
17979 };
17980
17981 static int __init advansys_init(void)
17982 {
17983 int error;
17984
17985 error = isa_register_driver(&advansys_isa_driver,
17986 ASC_IOADR_TABLE_MAX_IX);
17987 if (error)
17988 goto fail;
17989
17990 error = isa_register_driver(&advansys_vlb_driver,
17991 ASC_IOADR_TABLE_MAX_IX);
17992 if (error)
17993 goto unregister_isa;
17994
17995 error = eisa_driver_register(&advansys_eisa_driver);
17996 if (error)
17997 goto unregister_vlb;
17998
17999 error = pci_register_driver(&advansys_pci_driver);
18000 if (error)
18001 goto unregister_eisa;
18002
18003 return 0;
18004
18005 unregister_eisa:
18006 eisa_driver_unregister(&advansys_eisa_driver);
18007 unregister_vlb:
18008 isa_unregister_driver(&advansys_vlb_driver);
18009 unregister_isa:
18010 isa_unregister_driver(&advansys_isa_driver);
18011 fail:
18012 return error;
18013 }
18014
18015 static void __exit advansys_exit(void)
18016 {
18017 pci_unregister_driver(&advansys_pci_driver);
18018 eisa_driver_unregister(&advansys_eisa_driver);
18019 isa_unregister_driver(&advansys_vlb_driver);
18020 isa_unregister_driver(&advansys_isa_driver);
18021 }
18022
18023 module_init(advansys_init);
18024 module_exit(advansys_exit);
18025
18026 MODULE_LICENSE("GPL");