[SCSI] advansys: Update resource management
[linux-2.6-block.git] / drivers / scsi / advansys.c
CommitLineData
8c6af9e1 1#define ASC_VERSION "3.4" /* AdvanSys Driver Version */
1da177e4
LT
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.
8c6af9e1 8 * Copyright (c) 2007 Matthew Wilcox <matthew@wil.cx>
1da177e4
LT
9 * All Rights Reserved.
10 *
8c6af9e1
MW
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/*
1da177e4
LT
18 * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
19 * changed its name to ConnectCom Solutions, Inc.
8c6af9e1 20 * On June 18, 2001 Initio Corp. acquired ConnectCom's SCSI assets
1da177e4
LT
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
d0be4a7d 120 and after "static struct scsi_host_template builtin_scsi_hosts[] =":
1da177e4
LT
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
d0be4a7d 166 --- Linux 'struct scsi_host_template' and advansys_setup() Functions
1da177e4
LT
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
c304ec94 283 /proc/scsi/advansys/{0,1,2,3,...}
1da177e4
LT
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.
1d6f359a 377 2. Add support for IRQ sharing by setting the IRQF_SHARED flag for
1da177e4
LT
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.
1d6f359a 510 5. Try allocating an IRQ both with and without the IRQF_DISABLED
1da177e4 511 flag set to allow IRQ sharing with drivers that do not set
1d6f359a 512 the IRQF_DISABLED flag. Also display a more descriptive error
1da177e4
LT
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
1da177e4 760#include <linux/module.h>
1da177e4
LT
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>
c304ec94 772#include <linux/isa.h>
b09e05a7 773#include <linux/eisa.h>
8c6af9e1 774#include <linux/pci.h>
1da177e4
LT
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
8c6af9e1
MW
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
b09e05a7 788/* FIXME: (by jejb@steeleye.com)
1da177e4 789 *
b09e05a7 790 * Although all of the necessary command mapping places have the
1da177e4
LT
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
1da177e4
LT
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
1da177e4
LT
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 */
27c868c2
MW
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. */
1da177e4
LT
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
844typedef 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 AscPCIConfigVendorIDRegister 0x0000
858#define AscPCIConfigDeviceIDRegister 0x0002
859#define AscPCIConfigCommandRegister 0x0004
860#define AscPCIConfigStatusRegister 0x0006
861#define AscPCIConfigRevisionIDRegister 0x0008
862#define AscPCIConfigCacheSize 0x000C
863#define AscPCIConfigLatencyTimer 0x000D
864#define AscPCIIOBaseRegister 0x0010
865#define AscPCICmdRegBits_IOMemBusMaster 0x0007
1da177e4
LT
866#define ASC_PCI_ID2FUNC(id) (((id) >> 8) & 0x7)
867#define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
1da177e4
LT
868
869#define ASC_DVCLIB_CALL_DONE (1)
870#define ASC_DVCLIB_CALL_FAILED (0)
871#define ASC_DVCLIB_CALL_ERROR (-1)
872
2672ea86
DJ
873#define PCI_VENDOR_ID_ASP 0x10cd
874#define PCI_DEVICE_ID_ASP_1200A 0x1100
875#define PCI_DEVICE_ID_ASP_ABP940 0x1200
876#define PCI_DEVICE_ID_ASP_ABP940U 0x1300
877#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
878#define PCI_DEVICE_ID_38C0800_REV1 0x2500
879#define PCI_DEVICE_ID_38C1600_REV1 0x2700
880
1da177e4
LT
881/*
882 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
883 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
884 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
885 * SRB structure.
886 */
887#define CC_VERY_LONG_SG_LIST 0
888#define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
889
27c868c2 890#define PortAddr unsigned short /* port address size */
1da177e4
LT
891#define inp(port) inb(port)
892#define outp(port, byte) outb((byte), (port))
893
894#define inpw(port) inw(port)
895#define outpw(port, word) outw((word), (port))
896
897#define ASC_MAX_SG_QUEUE 7
898#define ASC_MAX_SG_LIST 255
899
900#define ASC_CS_TYPE unsigned short
901
902#define ASC_IS_ISA (0x0001)
903#define ASC_IS_ISAPNP (0x0081)
904#define ASC_IS_EISA (0x0002)
905#define ASC_IS_PCI (0x0004)
906#define ASC_IS_PCI_ULTRA (0x0104)
907#define ASC_IS_PCMCIA (0x0008)
908#define ASC_IS_MCA (0x0020)
909#define ASC_IS_VL (0x0040)
910#define ASC_ISA_PNP_PORT_ADDR (0x279)
911#define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
912#define ASC_IS_WIDESCSI_16 (0x0100)
913#define ASC_IS_WIDESCSI_32 (0x0200)
914#define ASC_IS_BIG_ENDIAN (0x8000)
915#define ASC_CHIP_MIN_VER_VL (0x01)
916#define ASC_CHIP_MAX_VER_VL (0x07)
917#define ASC_CHIP_MIN_VER_PCI (0x09)
918#define ASC_CHIP_MAX_VER_PCI (0x0F)
919#define ASC_CHIP_VER_PCI_BIT (0x08)
920#define ASC_CHIP_MIN_VER_ISA (0x11)
921#define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
922#define ASC_CHIP_MAX_VER_ISA (0x27)
923#define ASC_CHIP_VER_ISA_BIT (0x30)
924#define ASC_CHIP_VER_ISAPNP_BIT (0x20)
925#define ASC_CHIP_VER_ASYN_BUG (0x21)
926#define ASC_CHIP_VER_PCI 0x08
927#define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
928#define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
929#define ASC_CHIP_MIN_VER_EISA (0x41)
930#define ASC_CHIP_MAX_VER_EISA (0x47)
931#define ASC_CHIP_VER_EISA_BIT (0x40)
932#define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
933#define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER 0x21
934#define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER 0x0A
935#define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL)
936#define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
937#define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL)
938#define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
939#define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL)
940#define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
941#define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL)
942#define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL)
943
944#define ASC_SCSI_ID_BITS 3
945#define ASC_SCSI_TIX_TYPE uchar
946#define ASC_ALL_DEVICE_BIT_SET 0xFF
947#define ASC_SCSI_BIT_ID_TYPE uchar
948#define ASC_MAX_TID 7
949#define ASC_MAX_LUN 7
950#define ASC_SCSI_WIDTH_BIT_SET 0xFF
951#define ASC_MAX_SENSE_LEN 32
952#define ASC_MIN_SENSE_LEN 14
953#define ASC_MAX_CDB_LEN 12
954#define ASC_SCSI_RESET_HOLD_TIME_US 60
955
956#define ADV_INQ_CLOCKING_ST_ONLY 0x0
957#define ADV_INQ_CLOCKING_DT_ONLY 0x1
958#define ADV_INQ_CLOCKING_ST_AND_DT 0x3
959
960/*
961 * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
962 * and CmdDt (Command Support Data) field bit definitions.
963 */
964#define ADV_INQ_RTN_VPD_AND_CMDDT 0x3
965#define ADV_INQ_RTN_CMDDT_FOR_OP_CODE 0x2
966#define ADV_INQ_RTN_VPD_FOR_PG_CODE 0x1
967#define ADV_INQ_RTN_STD_INQUIRY_DATA 0x0
968
969#define ASC_SCSIDIR_NOCHK 0x00
970#define ASC_SCSIDIR_T2H 0x08
971#define ASC_SCSIDIR_H2T 0x10
972#define ASC_SCSIDIR_NODATA 0x18
973#define SCSI_ASC_NOMEDIA 0x3A
974#define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4))
975#define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F))
976#define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13))
977#define PUT_CDB1(x) ((uchar)((uint)(x) >> 8))
978#define MS_CMD_DONE 0x00
979#define MS_EXTEND 0x01
980#define MS_SDTR_LEN 0x03
981#define MS_SDTR_CODE 0x01
982#define MS_WDTR_LEN 0x02
983#define MS_WDTR_CODE 0x03
984#define MS_MDP_LEN 0x05
985#define MS_MDP_CODE 0x00
986
987/*
988 * Inquiry data structure and bitfield macros
989 *
990 * Only quantities of more than 1 bit are shifted, since the others are
991 * just tested for true or false. C bitfields aren't portable between big
992 * and little-endian platforms so they are not used.
993 */
994
995#define ASC_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f)
996#define ASC_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5)
997#define ASC_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f)
998#define ASC_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80)
999#define ASC_INQ_ANSI_VER(inq) ((inq)->ver & 0x07)
1000#define ASC_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3)
1001#define ASC_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6)
1002#define ASC_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f)
1003#define ASC_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40)
1004#define ASC_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80)
1005#define ASC_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01)
1006#define ASC_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02)
1007#define ASC_INQ_LINK_CMD(inq) ((inq)->flags & 0x08)
1008#define ASC_INQ_SYNC(inq) ((inq)->flags & 0x10)
1009#define ASC_INQ_WIDE16(inq) ((inq)->flags & 0x20)
1010#define ASC_INQ_WIDE32(inq) ((inq)->flags & 0x40)
1011#define ASC_INQ_REL_ADDR(inq) ((inq)->flags & 0x80)
1012#define ASC_INQ_INFO_UNIT(inq) ((inq)->info & 0x01)
1013#define ASC_INQ_QUICK_ARB(inq) ((inq)->info & 0x02)
1014#define ASC_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2)
1015
1016typedef struct {
27c868c2
MW
1017 uchar periph;
1018 uchar devtype;
1019 uchar ver;
1020 uchar byte3;
1021 uchar add_len;
1022 uchar res1;
1023 uchar res2;
1024 uchar flags;
1025 uchar vendor_id[8];
1026 uchar product_id[16];
1027 uchar product_rev_level[4];
1da177e4
LT
1028} ASC_SCSI_INQUIRY;
1029
1030#define ASC_SG_LIST_PER_Q 7
1031#define QS_FREE 0x00
1032#define QS_READY 0x01
1033#define QS_DISC1 0x02
1034#define QS_DISC2 0x04
1035#define QS_BUSY 0x08
1036#define QS_ABORTED 0x40
1037#define QS_DONE 0x80
1038#define QC_NO_CALLBACK 0x01
1039#define QC_SG_SWAP_QUEUE 0x02
1040#define QC_SG_HEAD 0x04
1041#define QC_DATA_IN 0x08
1042#define QC_DATA_OUT 0x10
1043#define QC_URGENT 0x20
1044#define QC_MSG_OUT 0x40
1045#define QC_REQ_SENSE 0x80
1046#define QCSG_SG_XFER_LIST 0x02
1047#define QCSG_SG_XFER_MORE 0x04
1048#define QCSG_SG_XFER_END 0x08
1049#define QD_IN_PROGRESS 0x00
1050#define QD_NO_ERROR 0x01
1051#define QD_ABORTED_BY_HOST 0x02
1052#define QD_WITH_ERROR 0x04
1053#define QD_INVALID_REQUEST 0x80
1054#define QD_INVALID_HOST_NUM 0x81
1055#define QD_INVALID_DEVICE 0x82
1056#define QD_ERR_INTERNAL 0xFF
1057#define QHSTA_NO_ERROR 0x00
1058#define QHSTA_M_SEL_TIMEOUT 0x11
1059#define QHSTA_M_DATA_OVER_RUN 0x12
1060#define QHSTA_M_DATA_UNDER_RUN 0x12
1061#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
1062#define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
1063#define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1064#define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
1065#define QHSTA_D_HOST_ABORT_FAILED 0x23
1066#define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
1067#define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1068#define QHSTA_D_ASPI_NO_BUF_POOL 0x26
1069#define QHSTA_M_WTM_TIMEOUT 0x41
1070#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
1071#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
1072#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1073#define QHSTA_M_TARGET_STATUS_BUSY 0x45
1074#define QHSTA_M_BAD_TAG_CODE 0x46
1075#define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
1076#define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1077#define QHSTA_D_LRAM_CMP_ERROR 0x81
1078#define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1079#define ASC_FLAG_SCSIQ_REQ 0x01
1080#define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
1081#define ASC_FLAG_BIOS_ASYNC_IO 0x04
1082#define ASC_FLAG_SRB_LINEAR_ADDR 0x08
1083#define ASC_FLAG_WIN16 0x10
1084#define ASC_FLAG_WIN32 0x20
1085#define ASC_FLAG_ISA_OVER_16MB 0x40
1086#define ASC_FLAG_DOS_VM_CALLBACK 0x80
1087#define ASC_TAG_FLAG_EXTRA_BYTES 0x10
1088#define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
1089#define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
1090#define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1091#define ASC_SCSIQ_CPY_BEG 4
1092#define ASC_SCSIQ_SGHD_CPY_BEG 2
1093#define ASC_SCSIQ_B_FWD 0
1094#define ASC_SCSIQ_B_BWD 1
1095#define ASC_SCSIQ_B_STATUS 2
1096#define ASC_SCSIQ_B_QNO 3
1097#define ASC_SCSIQ_B_CNTL 4
1098#define ASC_SCSIQ_B_SG_QUEUE_CNT 5
1099#define ASC_SCSIQ_D_DATA_ADDR 8
1100#define ASC_SCSIQ_D_DATA_CNT 12
1101#define ASC_SCSIQ_B_SENSE_LEN 20
1102#define ASC_SCSIQ_DONE_INFO_BEG 22
1103#define ASC_SCSIQ_D_SRBPTR 22
1104#define ASC_SCSIQ_B_TARGET_IX 26
1105#define ASC_SCSIQ_B_CDB_LEN 28
1106#define ASC_SCSIQ_B_TAG_CODE 29
1107#define ASC_SCSIQ_W_VM_ID 30
1108#define ASC_SCSIQ_DONE_STATUS 32
1109#define ASC_SCSIQ_HOST_STATUS 33
1110#define ASC_SCSIQ_SCSI_STATUS 34
1111#define ASC_SCSIQ_CDB_BEG 36
1112#define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1113#define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
1114#define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
1115#define ASC_SCSIQ_B_SG_WK_QP 49
1116#define ASC_SCSIQ_B_SG_WK_IX 50
1117#define ASC_SCSIQ_W_ALT_DC1 52
1118#define ASC_SCSIQ_B_LIST_CNT 6
1119#define ASC_SCSIQ_B_CUR_LIST_CNT 7
1120#define ASC_SGQ_B_SG_CNTL 4
1121#define ASC_SGQ_B_SG_HEAD_QP 5
1122#define ASC_SGQ_B_SG_LIST_CNT 6
1123#define ASC_SGQ_B_SG_CUR_LIST_CNT 7
1124#define ASC_SGQ_LIST_BEG 8
1125#define ASC_DEF_SCSI1_QNG 4
1126#define ASC_MAX_SCSI1_QNG 4
1127#define ASC_DEF_SCSI2_QNG 16
1128#define ASC_MAX_SCSI2_QNG 32
1129#define ASC_TAG_CODE_MASK 0x23
1130#define ASC_STOP_REQ_RISC_STOP 0x01
1131#define ASC_STOP_ACK_RISC_STOP 0x03
1132#define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
1133#define ASC_STOP_CLEAN_UP_DISC_Q 0x20
1134#define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1135#define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1136#define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1137#define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
1138#define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
1139#define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
1140#define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1141#define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
1142
1143typedef struct asc_scsiq_1 {
27c868c2
MW
1144 uchar status;
1145 uchar q_no;
1146 uchar cntl;
1147 uchar sg_queue_cnt;
1148 uchar target_id;
1149 uchar target_lun;
1150 ASC_PADDR data_addr;
1151 ASC_DCNT data_cnt;
1152 ASC_PADDR sense_addr;
1153 uchar sense_len;
1154 uchar extra_bytes;
1da177e4
LT
1155} ASC_SCSIQ_1;
1156
1157typedef struct asc_scsiq_2 {
27c868c2
MW
1158 ASC_VADDR srb_ptr;
1159 uchar target_ix;
1160 uchar flag;
1161 uchar cdb_len;
1162 uchar tag_code;
1163 ushort vm_id;
1da177e4
LT
1164} ASC_SCSIQ_2;
1165
1166typedef struct asc_scsiq_3 {
27c868c2
MW
1167 uchar done_stat;
1168 uchar host_stat;
1169 uchar scsi_stat;
1170 uchar scsi_msg;
1da177e4
LT
1171} ASC_SCSIQ_3;
1172
1173typedef struct asc_scsiq_4 {
27c868c2
MW
1174 uchar cdb[ASC_MAX_CDB_LEN];
1175 uchar y_first_sg_list_qp;
1176 uchar y_working_sg_qp;
1177 uchar y_working_sg_ix;
1178 uchar y_res;
1179 ushort x_req_count;
1180 ushort x_reconnect_rtn;
1181 ASC_PADDR x_saved_data_addr;
1182 ASC_DCNT x_saved_data_cnt;
1da177e4
LT
1183} ASC_SCSIQ_4;
1184
1185typedef struct asc_q_done_info {
27c868c2
MW
1186 ASC_SCSIQ_2 d2;
1187 ASC_SCSIQ_3 d3;
1188 uchar q_status;
1189 uchar q_no;
1190 uchar cntl;
1191 uchar sense_len;
1192 uchar extra_bytes;
1193 uchar res;
1194 ASC_DCNT remain_bytes;
1da177e4
LT
1195} ASC_QDONE_INFO;
1196
1197typedef struct asc_sg_list {
27c868c2
MW
1198 ASC_PADDR addr;
1199 ASC_DCNT bytes;
1da177e4
LT
1200} ASC_SG_LIST;
1201
1202typedef struct asc_sg_head {
27c868c2
MW
1203 ushort entry_cnt;
1204 ushort queue_cnt;
1205 ushort entry_to_copy;
1206 ushort res;
1207 ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1da177e4
LT
1208} ASC_SG_HEAD;
1209
1210#define ASC_MIN_SG_LIST 2
1211
1212typedef struct asc_min_sg_head {
27c868c2
MW
1213 ushort entry_cnt;
1214 ushort queue_cnt;
1215 ushort entry_to_copy;
1216 ushort res;
1217 ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
1da177e4
LT
1218} ASC_MIN_SG_HEAD;
1219
1220#define QCX_SORT (0x0001)
1221#define QCX_COALEASE (0x0002)
1222
1223typedef struct asc_scsi_q {
27c868c2
MW
1224 ASC_SCSIQ_1 q1;
1225 ASC_SCSIQ_2 q2;
1226 uchar *cdbptr;
1227 ASC_SG_HEAD *sg_head;
1228 ushort remain_sg_entry_cnt;
1229 ushort next_sg_index;
1da177e4
LT
1230} ASC_SCSI_Q;
1231
1232typedef struct asc_scsi_req_q {
27c868c2
MW
1233 ASC_SCSIQ_1 r1;
1234 ASC_SCSIQ_2 r2;
1235 uchar *cdbptr;
1236 ASC_SG_HEAD *sg_head;
1237 uchar *sense_ptr;
1238 ASC_SCSIQ_3 r3;
1239 uchar cdb[ASC_MAX_CDB_LEN];
1240 uchar sense[ASC_MIN_SENSE_LEN];
1da177e4
LT
1241} ASC_SCSI_REQ_Q;
1242
1243typedef struct asc_scsi_bios_req_q {
27c868c2
MW
1244 ASC_SCSIQ_1 r1;
1245 ASC_SCSIQ_2 r2;
1246 uchar *cdbptr;
1247 ASC_SG_HEAD *sg_head;
1248 uchar *sense_ptr;
1249 ASC_SCSIQ_3 r3;
1250 uchar cdb[ASC_MAX_CDB_LEN];
1251 uchar sense[ASC_MIN_SENSE_LEN];
1da177e4
LT
1252} ASC_SCSI_BIOS_REQ_Q;
1253
1254typedef struct asc_risc_q {
27c868c2
MW
1255 uchar fwd;
1256 uchar bwd;
1257 ASC_SCSIQ_1 i1;
1258 ASC_SCSIQ_2 i2;
1259 ASC_SCSIQ_3 i3;
1260 ASC_SCSIQ_4 i4;
1da177e4
LT
1261} ASC_RISC_Q;
1262
1263typedef struct asc_sg_list_q {
27c868c2
MW
1264 uchar seq_no;
1265 uchar q_no;
1266 uchar cntl;
1267 uchar sg_head_qp;
1268 uchar sg_list_cnt;
1269 uchar sg_cur_list_cnt;
1da177e4
LT
1270} ASC_SG_LIST_Q;
1271
1272typedef struct asc_risc_sg_list_q {
27c868c2
MW
1273 uchar fwd;
1274 uchar bwd;
1275 ASC_SG_LIST_Q sg;
1276 ASC_SG_LIST sg_list[7];
1da177e4
LT
1277} ASC_RISC_SG_LIST_Q;
1278
1279#define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL
1280#define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024
1281#define ASCQ_ERR_NO_ERROR 0
1282#define ASCQ_ERR_IO_NOT_FOUND 1
1283#define ASCQ_ERR_LOCAL_MEM 2
1284#define ASCQ_ERR_CHKSUM 3
1285#define ASCQ_ERR_START_CHIP 4
1286#define ASCQ_ERR_INT_TARGET_ID 5
1287#define ASCQ_ERR_INT_LOCAL_MEM 6
1288#define ASCQ_ERR_HALT_RISC 7
1289#define ASCQ_ERR_GET_ASPI_ENTRY 8
1290#define ASCQ_ERR_CLOSE_ASPI 9
1291#define ASCQ_ERR_HOST_INQUIRY 0x0A
1292#define ASCQ_ERR_SAVED_SRB_BAD 0x0B
1293#define ASCQ_ERR_QCNTL_SG_LIST 0x0C
1294#define ASCQ_ERR_Q_STATUS 0x0D
1295#define ASCQ_ERR_WR_SCSIQ 0x0E
1296#define ASCQ_ERR_PC_ADDR 0x0F
1297#define ASCQ_ERR_SYN_OFFSET 0x10
1298#define ASCQ_ERR_SYN_XFER_TIME 0x11
1299#define ASCQ_ERR_LOCK_DMA 0x12
1300#define ASCQ_ERR_UNLOCK_DMA 0x13
1301#define ASCQ_ERR_VDS_CHK_INSTALL 0x14
1302#define ASCQ_ERR_MICRO_CODE_HALT 0x15
1303#define ASCQ_ERR_SET_LRAM_ADDR 0x16
1304#define ASCQ_ERR_CUR_QNG 0x17
1305#define ASCQ_ERR_SG_Q_LINKS 0x18
1306#define ASCQ_ERR_SCSIQ_PTR 0x19
1307#define ASCQ_ERR_ISR_RE_ENTRY 0x1A
1308#define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
1309#define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
1310#define ASCQ_ERR_SG_LIST_ODD_ADDRESS 0x1D
1311#define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1312#define ASCQ_ERR_SCSIQ_NULL_PTR 0x1F
1313#define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR 0x20
1314#define ASCQ_ERR_GET_NUM_OF_FREE_Q 0x21
1315#define ASCQ_ERR_SEND_SCSI_Q 0x22
1316#define ASCQ_ERR_HOST_REQ_RISC_HALT 0x23
1317#define ASCQ_ERR_RESET_SDTR 0x24
1318
1319/*
1320 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
1321 */
1322#define ASC_WARN_NO_ERROR 0x0000
1323#define ASC_WARN_IO_PORT_ROTATE 0x0001
1324#define ASC_WARN_EEPROM_CHKSUM 0x0002
1325#define ASC_WARN_IRQ_MODIFIED 0x0004
1326#define ASC_WARN_AUTO_CONFIG 0x0008
1327#define ASC_WARN_CMD_QNG_CONFLICT 0x0010
1328#define ASC_WARN_EEPROM_RECOVER 0x0020
1329#define ASC_WARN_CFG_MSW_RECOVER 0x0040
1330#define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1331
1332/*
1333 * Error code values are set in ASC_DVC_VAR 'err_code'.
1334 */
1335#define ASC_IERR_WRITE_EEPROM 0x0001
1336#define ASC_IERR_MCODE_CHKSUM 0x0002
1337#define ASC_IERR_SET_PC_ADDR 0x0004
1338#define ASC_IERR_START_STOP_CHIP 0x0008
1339#define ASC_IERR_IRQ_NO 0x0010
1340#define ASC_IERR_SET_IRQ_NO 0x0020
1341#define ASC_IERR_CHIP_VERSION 0x0040
1342#define ASC_IERR_SET_SCSI_ID 0x0080
1343#define ASC_IERR_GET_PHY_ADDR 0x0100
1344#define ASC_IERR_BAD_SIGNATURE 0x0200
1345#define ASC_IERR_NO_BUS_TYPE 0x0400
1346#define ASC_IERR_SCAM 0x0800
1347#define ASC_IERR_SET_SDTR 0x1000
1348#define ASC_IERR_RW_LRAM 0x8000
1349
1350#define ASC_DEF_IRQ_NO 10
1351#define ASC_MAX_IRQ_NO 15
1352#define ASC_MIN_IRQ_NO 10
1353#define ASC_MIN_REMAIN_Q (0x02)
1354#define ASC_DEF_MAX_TOTAL_QNG (0xF0)
1355#define ASC_MIN_TAG_Q_PER_DVC (0x04)
1356#define ASC_DEF_TAG_Q_PER_DVC (0x04)
1357#define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q
1358#define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1359#define ASC_MAX_TOTAL_QNG 240
1360#define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1361#define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
1362#define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
1363#define ASC_MAX_INRAM_TAG_QNG 16
1364#define ASC_IOADR_TABLE_MAX_IX 11
1365#define ASC_IOADR_GAP 0x10
1da177e4
LT
1366#define ASC_LIB_SCSIQ_WK_SP 256
1367#define ASC_MAX_SYN_XFER_NO 16
1368#define ASC_SYN_MAX_OFFSET 0x0F
1369#define ASC_DEF_SDTR_OFFSET 0x0F
1370#define ASC_DEF_SDTR_INDEX 0x00
1371#define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
1372#define SYN_XFER_NS_0 25
1373#define SYN_XFER_NS_1 30
1374#define SYN_XFER_NS_2 35
1375#define SYN_XFER_NS_3 40
1376#define SYN_XFER_NS_4 50
1377#define SYN_XFER_NS_5 60
1378#define SYN_XFER_NS_6 70
1379#define SYN_XFER_NS_7 85
1380#define SYN_ULTRA_XFER_NS_0 12
1381#define SYN_ULTRA_XFER_NS_1 19
1382#define SYN_ULTRA_XFER_NS_2 25
1383#define SYN_ULTRA_XFER_NS_3 32
1384#define SYN_ULTRA_XFER_NS_4 38
1385#define SYN_ULTRA_XFER_NS_5 44
1386#define SYN_ULTRA_XFER_NS_6 50
1387#define SYN_ULTRA_XFER_NS_7 57
1388#define SYN_ULTRA_XFER_NS_8 63
1389#define SYN_ULTRA_XFER_NS_9 69
1390#define SYN_ULTRA_XFER_NS_10 75
1391#define SYN_ULTRA_XFER_NS_11 82
1392#define SYN_ULTRA_XFER_NS_12 88
1393#define SYN_ULTRA_XFER_NS_13 94
1394#define SYN_ULTRA_XFER_NS_14 100
1395#define SYN_ULTRA_XFER_NS_15 107
1396
1397typedef struct ext_msg {
27c868c2
MW
1398 uchar msg_type;
1399 uchar msg_len;
1400 uchar msg_req;
1401 union {
1402 struct {
1403 uchar sdtr_xfer_period;
1404 uchar sdtr_req_ack_offset;
1405 } sdtr;
1406 struct {
1407 uchar wdtr_width;
1408 } wdtr;
1409 struct {
1410 uchar mdp_b3;
1411 uchar mdp_b2;
1412 uchar mdp_b1;
1413 uchar mdp_b0;
1414 } mdp;
1415 } u_ext_msg;
1416 uchar res;
1da177e4
LT
1417} EXT_MSG;
1418
1419#define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
1420#define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
1421#define wdtr_width u_ext_msg.wdtr.wdtr_width
1422#define mdp_b3 u_ext_msg.mdp_b3
1423#define mdp_b2 u_ext_msg.mdp_b2
1424#define mdp_b1 u_ext_msg.mdp_b1
1425#define mdp_b0 u_ext_msg.mdp_b0
1426
1427typedef struct asc_dvc_cfg {
27c868c2
MW
1428 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1429 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1430 ASC_SCSI_BIT_ID_TYPE disc_enable;
1431 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1432 uchar chip_scsi_id;
1433 uchar isa_dma_speed;
1434 uchar isa_dma_channel;
1435 uchar chip_version;
1436 ushort lib_serial_no;
1437 ushort lib_version;
1438 ushort mcode_date;
1439 ushort mcode_version;
1440 uchar max_tag_qng[ASC_MAX_TID + 1];
1441 uchar *overrun_buf;
1442 uchar sdtr_period_offset[ASC_MAX_TID + 1];
1443 ushort pci_slot_info;
1444 uchar adapter_info[6];
1445 struct device *dev;
1da177e4
LT
1446} ASC_DVC_CFG;
1447
1448#define ASC_DEF_DVC_CNTL 0xFFFF
1449#define ASC_DEF_CHIP_SCSI_ID 7
1450#define ASC_DEF_ISA_DMA_SPEED 4
1451#define ASC_INIT_STATE_NULL 0x0000
1452#define ASC_INIT_STATE_BEG_GET_CFG 0x0001
1453#define ASC_INIT_STATE_END_GET_CFG 0x0002
1454#define ASC_INIT_STATE_BEG_SET_CFG 0x0004
1455#define ASC_INIT_STATE_END_SET_CFG 0x0008
1456#define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
1457#define ASC_INIT_STATE_END_LOAD_MC 0x0020
1458#define ASC_INIT_STATE_BEG_INQUIRY 0x0040
1459#define ASC_INIT_STATE_END_INQUIRY 0x0080
1460#define ASC_INIT_RESET_SCSI_DONE 0x0100
1461#define ASC_INIT_STATE_WITHOUT_EEP 0x8000
1da177e4
LT
1462#define ASC_BUG_FIX_IF_NOT_DWB 0x0001
1463#define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
1464#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1465#define ASC_MIN_TAGGED_CMD 7
1466#define ASC_MAX_SCSI_RESET_WAIT 30
1467
27c868c2 1468struct asc_dvc_var; /* Forward Declaration. */
1da177e4 1469
27c868c2
MW
1470typedef void (*ASC_ISR_CALLBACK) (struct asc_dvc_var *, ASC_QDONE_INFO *);
1471typedef int (*ASC_EXE_CALLBACK) (struct asc_dvc_var *, ASC_SCSI_Q *);
1da177e4
LT
1472
1473typedef struct asc_dvc_var {
27c868c2
MW
1474 PortAddr iop_base;
1475 ushort err_code;
1476 ushort dvc_cntl;
1477 ushort bug_fix_cntl;
1478 ushort bus_type;
1479 ASC_ISR_CALLBACK isr_callback;
1480 ASC_EXE_CALLBACK exe_callback;
1481 ASC_SCSI_BIT_ID_TYPE init_sdtr;
1482 ASC_SCSI_BIT_ID_TYPE sdtr_done;
1483 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1484 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1485 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1486 ASC_SCSI_BIT_ID_TYPE start_motor;
1487 uchar scsi_reset_wait;
1488 uchar chip_no;
1489 char is_in_int;
1490 uchar max_total_qng;
1491 uchar cur_total_qng;
1492 uchar in_critical_cnt;
1493 uchar irq_no;
1494 uchar last_q_shortage;
1495 ushort init_state;
1496 uchar cur_dvc_qng[ASC_MAX_TID + 1];
1497 uchar max_dvc_qng[ASC_MAX_TID + 1];
1498 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
1499 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
1500 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1501 ASC_DVC_CFG *cfg;
1502 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1503 char redo_scam;
1504 ushort res2;
1505 uchar dos_int13_table[ASC_MAX_TID + 1];
1506 ASC_DCNT max_dma_count;
1507 ASC_SCSI_BIT_ID_TYPE no_scam;
1508 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1509 uchar max_sdtr_index;
1510 uchar host_init_sdtr_index;
1511 struct asc_board *drv_ptr;
1512 ASC_DCNT uc_break;
1da177e4
LT
1513} ASC_DVC_VAR;
1514
1515typedef struct asc_dvc_inq_info {
27c868c2 1516 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1da177e4
LT
1517} ASC_DVC_INQ_INFO;
1518
1519typedef struct asc_cap_info {
27c868c2
MW
1520 ASC_DCNT lba;
1521 ASC_DCNT blk_size;
1da177e4
LT
1522} ASC_CAP_INFO;
1523
1524typedef struct asc_cap_info_array {
27c868c2 1525 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1da177e4
LT
1526} ASC_CAP_INFO_ARRAY;
1527
1528#define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
1529#define ASC_MCNTL_NULL_TARGET (ushort)0x0002
1530#define ASC_CNTL_INITIATOR (ushort)0x0001
1531#define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
1532#define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
1533#define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
1534#define ASC_CNTL_NO_SCAM (ushort)0x0010
1535#define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
1536#define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
1537#define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
1538#define ASC_CNTL_RESET_SCSI (ushort)0x0200
1539#define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
1540#define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
1541#define ASC_CNTL_SCSI_PARITY (ushort)0x1000
1542#define ASC_CNTL_BURST_MODE (ushort)0x2000
1543#define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1544#define ASC_EEP_DVC_CFG_BEG_VL 2
1545#define ASC_EEP_MAX_DVC_ADDR_VL 15
1546#define ASC_EEP_DVC_CFG_BEG 32
1547#define ASC_EEP_MAX_DVC_ADDR 45
1548#define ASC_EEP_DEFINED_WORDS 10
1549#define ASC_EEP_MAX_ADDR 63
1550#define ASC_EEP_RES_WORDS 0
1551#define ASC_EEP_MAX_RETRY 20
1552#define ASC_MAX_INIT_BUSY_RETRY 8
1553#define ASC_EEP_ISA_PNP_WSIZE 16
1554
1555/*
1556 * These macros keep the chip SCSI id and ISA DMA speed
1557 * bitfields in board order. C bitfields aren't portable
1558 * between big and little-endian platforms so they are
1559 * not used.
1560 */
1561
1562#define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
1563#define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
1564#define ASC_EEP_SET_CHIP_ID(cfg, sid) \
1565 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
1566#define ASC_EEP_SET_DMA_SPD(cfg, spd) \
1567 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
1568
1569typedef struct asceep_config {
27c868c2
MW
1570 ushort cfg_lsw;
1571 ushort cfg_msw;
1572 uchar init_sdtr;
1573 uchar disc_enable;
1574 uchar use_cmd_qng;
1575 uchar start_motor;
1576 uchar max_total_qng;
1577 uchar max_tag_qng;
1578 uchar bios_scan;
1579 uchar power_up_wait;
1580 uchar no_scam;
1581 uchar id_speed; /* low order 4 bits is chip scsi id */
1582 /* high order 4 bits is isa dma speed */
1583 uchar dos_int13_table[ASC_MAX_TID + 1];
1584 uchar adapter_info[6];
1585 ushort cntl;
1586 ushort chksum;
1da177e4
LT
1587} ASCEEP_CONFIG;
1588
1589#define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800
1590#define ASC_PCI_CFG_LSW_BURST_MODE 0x0080
1591#define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020
1592
1593#define ASC_EEP_CMD_READ 0x80
1594#define ASC_EEP_CMD_WRITE 0x40
1595#define ASC_EEP_CMD_WRITE_ABLE 0x30
1596#define ASC_EEP_CMD_WRITE_DISABLE 0x00
1597#define ASC_OVERRUN_BSIZE 0x00000048UL
1598#define ASC_CTRL_BREAK_ONCE 0x0001
1599#define ASC_CTRL_BREAK_STAY_IDLE 0x0002
1600#define ASCV_MSGOUT_BEG 0x0000
1601#define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1602#define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1603#define ASCV_BREAK_SAVED_CODE (ushort)0x0006
1604#define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
1605#define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
1606#define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
1607#define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
1608#define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
1609#define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
1610#define ASCV_BREAK_ADDR (ushort)0x0028
1611#define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
1612#define ASCV_BREAK_CONTROL (ushort)0x002C
1613#define ASCV_BREAK_HIT_COUNT (ushort)0x002E
1614
1615#define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
1616#define ASCV_MCODE_CHKSUM_W (ushort)0x0032
1617#define ASCV_MCODE_SIZE_W (ushort)0x0034
1618#define ASCV_STOP_CODE_B (ushort)0x0036
1619#define ASCV_DVC_ERR_CODE_B (ushort)0x0037
1620#define ASCV_OVERRUN_PADDR_D (ushort)0x0038
1621#define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
1622#define ASCV_HALTCODE_W (ushort)0x0040
1623#define ASCV_CHKSUM_W (ushort)0x0042
1624#define ASCV_MC_DATE_W (ushort)0x0044
1625#define ASCV_MC_VER_W (ushort)0x0046
1626#define ASCV_NEXTRDY_B (ushort)0x0048
1627#define ASCV_DONENEXT_B (ushort)0x0049
1628#define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1629#define ASCV_SCSIBUSY_B (ushort)0x004B
1630#define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
1631#define ASCV_CURCDB_B (ushort)0x004D
1632#define ASCV_RCLUN_B (ushort)0x004E
1633#define ASCV_BUSY_QHEAD_B (ushort)0x004F
1634#define ASCV_DISC1_QHEAD_B (ushort)0x0050
1635#define ASCV_DISC_ENABLE_B (ushort)0x0052
1636#define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1637#define ASCV_HOSTSCSI_ID_B (ushort)0x0055
1638#define ASCV_MCODE_CNTL_B (ushort)0x0056
1639#define ASCV_NULL_TARGET_B (ushort)0x0057
1640#define ASCV_FREE_Q_HEAD_W (ushort)0x0058
1641#define ASCV_DONE_Q_TAIL_W (ushort)0x005A
1642#define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
1643#define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
1644#define ASCV_HOST_FLAG_B (ushort)0x005D
1645#define ASCV_TOTAL_READY_Q_B (ushort)0x0064
1646#define ASCV_VER_SERIAL_B (ushort)0x0065
1647#define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1648#define ASCV_WTM_FLAG_B (ushort)0x0068
1649#define ASCV_RISC_FLAG_B (ushort)0x006A
1650#define ASCV_REQ_SG_LIST_QP (ushort)0x006B
1651#define ASC_HOST_FLAG_IN_ISR 0x01
1652#define ASC_HOST_FLAG_ACK_INT 0x02
1653#define ASC_RISC_FLAG_GEN_INT 0x01
1654#define ASC_RISC_FLAG_REQ_SG_LIST 0x02
1655#define IOP_CTRL (0x0F)
1656#define IOP_STATUS (0x0E)
1657#define IOP_INT_ACK IOP_STATUS
1658#define IOP_REG_IFC (0x0D)
1659#define IOP_SYN_OFFSET (0x0B)
1660#define IOP_EXTRA_CONTROL (0x0D)
1661#define IOP_REG_PC (0x0C)
1662#define IOP_RAM_ADDR (0x0A)
1663#define IOP_RAM_DATA (0x08)
1664#define IOP_EEP_DATA (0x06)
1665#define IOP_EEP_CMD (0x07)
1666#define IOP_VERSION (0x03)
1667#define IOP_CONFIG_HIGH (0x04)
1668#define IOP_CONFIG_LOW (0x02)
1669#define IOP_SIG_BYTE (0x01)
1670#define IOP_SIG_WORD (0x00)
1671#define IOP_REG_DC1 (0x0E)
1672#define IOP_REG_DC0 (0x0C)
1673#define IOP_REG_SB (0x0B)
1674#define IOP_REG_DA1 (0x0A)
1675#define IOP_REG_DA0 (0x08)
1676#define IOP_REG_SC (0x09)
1677#define IOP_DMA_SPEED (0x07)
1678#define IOP_REG_FLAG (0x07)
1679#define IOP_FIFO_H (0x06)
1680#define IOP_FIFO_L (0x04)
1681#define IOP_REG_ID (0x05)
1682#define IOP_REG_QP (0x03)
1683#define IOP_REG_IH (0x02)
1684#define IOP_REG_IX (0x01)
1685#define IOP_REG_AX (0x00)
1686#define IFC_REG_LOCK (0x00)
1687#define IFC_REG_UNLOCK (0x09)
1688#define IFC_WR_EN_FILTER (0x10)
1689#define IFC_RD_NO_EEPROM (0x10)
1690#define IFC_SLEW_RATE (0x20)
1691#define IFC_ACT_NEG (0x40)
1692#define IFC_INP_FILTER (0x80)
1693#define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
1694#define SC_SEL (uchar)(0x80)
1695#define SC_BSY (uchar)(0x40)
1696#define SC_ACK (uchar)(0x20)
1697#define SC_REQ (uchar)(0x10)
1698#define SC_ATN (uchar)(0x08)
1699#define SC_IO (uchar)(0x04)
1700#define SC_CD (uchar)(0x02)
1701#define SC_MSG (uchar)(0x01)
1702#define SEC_SCSI_CTL (uchar)(0x80)
1703#define SEC_ACTIVE_NEGATE (uchar)(0x40)
1704#define SEC_SLEW_RATE (uchar)(0x20)
1705#define SEC_ENABLE_FILTER (uchar)(0x10)
1706#define ASC_HALT_EXTMSG_IN (ushort)0x8000
1707#define ASC_HALT_CHK_CONDITION (ushort)0x8100
1708#define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1709#define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
1710#define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
1711#define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1712#define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1713#define ASC_MAX_QNO 0xF8
1714#define ASC_DATA_SEC_BEG (ushort)0x0080
1715#define ASC_DATA_SEC_END (ushort)0x0080
1716#define ASC_CODE_SEC_BEG (ushort)0x0080
1717#define ASC_CODE_SEC_END (ushort)0x0080
1718#define ASC_QADR_BEG (0x4000)
1719#define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
1720#define ASC_QADR_END (ushort)0x7FFF
1721#define ASC_QLAST_ADR (ushort)0x7FC0
1722#define ASC_QBLK_SIZE 0x40
1723#define ASC_BIOS_DATA_QBEG 0xF8
1724#define ASC_MIN_ACTIVE_QNO 0x01
1725#define ASC_QLINK_END 0xFF
1726#define ASC_EEPROM_WORDS 0x10
1727#define ASC_MAX_MGS_LEN 0x10
1728#define ASC_BIOS_ADDR_DEF 0xDC00
1729#define ASC_BIOS_SIZE 0x3800
1730#define ASC_BIOS_RAM_OFF 0x3800
1731#define ASC_BIOS_RAM_SIZE 0x800
1732#define ASC_BIOS_MIN_ADDR 0xC000
1733#define ASC_BIOS_MAX_ADDR 0xEC00
1734#define ASC_BIOS_BANK_SIZE 0x0400
1735#define ASC_MCODE_START_ADDR 0x0080
1736#define ASC_CFG0_HOST_INT_ON 0x0020
1737#define ASC_CFG0_BIOS_ON 0x0040
1738#define ASC_CFG0_VERA_BURST_ON 0x0080
1739#define ASC_CFG0_SCSI_PARITY_ON 0x0800
1740#define ASC_CFG1_SCSI_TARGET_ON 0x0080
1741#define ASC_CFG1_LRAM_8BITS_ON 0x0800
1742#define ASC_CFG_MSW_CLR_MASK 0x3080
1743#define CSW_TEST1 (ASC_CS_TYPE)0x8000
1744#define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
1745#define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
1746#define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
1747#define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
1748#define CSW_TEST2 (ASC_CS_TYPE)0x0400
1749#define CSW_TEST3 (ASC_CS_TYPE)0x0200
1750#define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
1751#define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
1752#define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
1753#define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
1754#define CSW_HALTED (ASC_CS_TYPE)0x0010
1755#define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1756#define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
1757#define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
1758#define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
1759#define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1760#define CIW_INT_ACK (ASC_CS_TYPE)0x0100
1761#define CIW_TEST1 (ASC_CS_TYPE)0x0200
1762#define CIW_TEST2 (ASC_CS_TYPE)0x0400
1763#define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
1764#define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
1765#define CC_CHIP_RESET (uchar)0x80
1766#define CC_SCSI_RESET (uchar)0x40
1767#define CC_HALT (uchar)0x20
1768#define CC_SINGLE_STEP (uchar)0x10
1769#define CC_DMA_ABLE (uchar)0x08
1770#define CC_TEST (uchar)0x04
1771#define CC_BANK_ONE (uchar)0x02
1772#define CC_DIAG (uchar)0x01
1773#define ASC_1000_ID0W 0x04C1
1774#define ASC_1000_ID0W_FIX 0x00C1
1775#define ASC_1000_ID1B 0x25
1da177e4
LT
1776#define ASC_EISA_REV_IOP_MASK (0x0C83)
1777#define ASC_EISA_PID_IOP_MASK (0x0C80)
1778#define ASC_EISA_CFG_IOP_MASK (0x0C86)
1779#define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
1da177e4
LT
1780#define INS_HALTINT (ushort)0x6281
1781#define INS_HALT (ushort)0x6280
1782#define INS_SINT (ushort)0x6200
1783#define INS_RFLAG_WTM (ushort)0x7380
1784#define ASC_MC_SAVE_CODE_WSIZE 0x500
1785#define ASC_MC_SAVE_DATA_WSIZE 0x40
1786
1787typedef struct asc_mc_saved {
27c868c2
MW
1788 ushort data[ASC_MC_SAVE_DATA_WSIZE];
1789 ushort code[ASC_MC_SAVE_CODE_WSIZE];
1da177e4
LT
1790} ASC_MC_SAVED;
1791
1792#define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1793#define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1794#define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1795#define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1796#define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1797#define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1798#define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
1799#define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
1800#define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1801#define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1802#define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1803#define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1804#define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1805#define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1806#define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1807#define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
1808#define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
1809#define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
1810#define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
1811#define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
1812#define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
1813#define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
1814#define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
1815#define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
1816#define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
1817#define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
1818#define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1819#define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1820#define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
1821#define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
1822#define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
1823#define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
1824#define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1825#define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
1826#define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
1827#define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
1828#define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
1829#define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
1830#define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
1831#define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
1832#define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1833#define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1834#define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
1835#define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
1836#define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
1837#define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
1838#define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
1839#define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
1840#define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
1841#define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
1842#define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
1843#define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
1844#define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
1845#define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
1846#define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
1847#define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
1848#define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
1849#define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
1850#define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
1851#define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
1852#define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
1853#define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
1854#define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
1855#define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
1856#define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
1857#define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
1858#define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
1859#define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
1860
27c868c2
MW
1861static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1862static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1863static void AscWaitEEPRead(void);
1864static void AscWaitEEPWrite(void);
1865static ushort AscReadEEPWord(PortAddr, uchar);
1866static ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1867static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1868static int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1869static int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1870static int AscStartChip(PortAddr);
1871static int AscStopChip(PortAddr);
1872static void AscSetChipIH(PortAddr, ushort);
1873static int AscIsChipHalted(PortAddr);
1874static void AscAckInterrupt(PortAddr);
1875static void AscDisableInterrupt(PortAddr);
1876static void AscEnableInterrupt(PortAddr);
1877static void AscSetBank(PortAddr, uchar);
1878static int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1da177e4 1879#ifdef CONFIG_ISA
27c868c2
MW
1880static ushort AscGetIsaDmaChannel(PortAddr);
1881static ushort AscSetIsaDmaChannel(PortAddr, ushort);
1882static uchar AscSetIsaDmaSpeed(PortAddr, uchar);
1883static uchar AscGetIsaDmaSpeed(PortAddr);
1da177e4 1884#endif /* CONFIG_ISA */
27c868c2
MW
1885static uchar AscReadLramByte(PortAddr, ushort);
1886static ushort AscReadLramWord(PortAddr, ushort);
1da177e4 1887#if CC_VERY_LONG_SG_LIST
27c868c2 1888static ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1da177e4 1889#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
1890static void AscWriteLramWord(PortAddr, ushort, ushort);
1891static void AscWriteLramByte(PortAddr, ushort, uchar);
1892static ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
1893static void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1894static void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1895static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1896static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
1897static ushort AscInitAscDvcVar(ASC_DVC_VAR *);
1898static ushort AscInitFromEEP(ASC_DVC_VAR *);
1899static ushort AscInitFromAscDvcVar(ASC_DVC_VAR *);
1900static ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1901static int AscTestExternalLram(ASC_DVC_VAR *);
1902static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1903static uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1904static void AscSetChipSDTR(PortAddr, uchar, uchar);
1905static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1906static uchar AscAllocFreeQueue(PortAddr, uchar);
1907static uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1908static int AscHostReqRiscHalt(PortAddr);
1909static int AscStopQueueExe(PortAddr);
1910static int AscSendScsiQueue(ASC_DVC_VAR *,
1911 ASC_SCSI_Q *scsiq, uchar n_q_required);
1912static int AscPutReadyQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1913static int AscPutReadySgListQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1914static int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1915static int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1916static ushort AscInitLram(ASC_DVC_VAR *);
1917static ushort AscInitQLinkVar(ASC_DVC_VAR *);
1918static int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1919static int AscIsrChipHalted(ASC_DVC_VAR *);
1920static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1921 ASC_QDONE_INFO *, ASC_DCNT);
1922static int AscIsrQDone(ASC_DVC_VAR *);
1923static int AscCompareString(uchar *, uchar *, int);
1da177e4 1924#ifdef CONFIG_ISA
27c868c2 1925static ushort AscGetEisaChipCfg(PortAddr);
1da177e4 1926#endif /* CONFIG_ISA */
27c868c2
MW
1927static uchar AscGetChipScsiCtrl(PortAddr);
1928static uchar AscSetChipScsiID(PortAddr, uchar);
1929static uchar AscGetChipVersion(PortAddr, ushort);
1930static ushort AscGetChipBusType(PortAddr);
1931static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
1932static int AscFindSignature(PortAddr);
1933static void AscToggleIRQAct(PortAddr);
1934static uchar AscGetChipIRQ(PortAddr, ushort);
1935static uchar AscSetChipIRQ(PortAddr, uchar, ushort);
1936static ushort AscGetChipBiosAddress(PortAddr, ushort);
1937static inline ulong DvcEnterCritical(void);
1938static inline void DvcLeaveCritical(ulong);
1da177e4 1939#ifdef CONFIG_PCI
27c868c2
MW
1940static uchar DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort);
1941static void DvcWritePCIConfigByte(ASC_DVC_VAR *, ushort, uchar);
1da177e4 1942#endif /* CONFIG_PCI */
27c868c2
MW
1943static ushort AscGetChipBiosAddress(PortAddr, ushort);
1944static void DvcSleepMilliSecond(ASC_DCNT);
1945static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
1946static void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1947static void DvcGetQinfo(PortAddr, ushort, uchar *, int);
1948static ushort AscInitGetConfig(ASC_DVC_VAR *);
1949static ushort AscInitSetConfig(ASC_DVC_VAR *);
1950static ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
1951static void AscAsyncFix(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *);
1952static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
1953static void AscInquiryHandling(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *);
1954static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
1955static int AscISR(ASC_DVC_VAR *);
1956static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar);
1957static int AscSgListToQueue(int);
1da177e4 1958#ifdef CONFIG_ISA
27c868c2 1959static void AscEnableIsaDma(uchar);
1da177e4 1960#endif /* CONFIG_ISA */
27c868c2
MW
1961static ASC_DCNT AscGetMaxDmaCount(ushort);
1962static const char *advansys_info(struct Scsi_Host *shost);
1da177e4
LT
1963
1964/*
1965 * --- Adv Library Constants and Macros
1966 */
1967
1968#define ADV_LIB_VERSION_MAJOR 5
1969#define ADV_LIB_VERSION_MINOR 14
1970
1971/*
1972 * Define Adv Library required special types.
1973 */
1974
1975/*
1976 * Portable Data Types
1977 *
1978 * Any instance where a 32-bit long or pointer type is assumed
1979 * for precision or HW defined structures, the following define
1980 * types must be used. In Linux the char, short, and int types
1981 * are all consistent at 8, 16, and 32 bits respectively. Pointers
1982 * and long types are 64 bits on Alpha and UltraSPARC.
1983 */
27c868c2
MW
1984#define ADV_PADDR __u32 /* Physical address data type. */
1985#define ADV_VADDR __u32 /* Virtual address data type. */
1986#define ADV_DCNT __u32 /* Unsigned Data count type. */
1987#define ADV_SDCNT __s32 /* Signed Data count type. */
1da177e4
LT
1988
1989/*
1990 * These macros are used to convert a virtual address to a
1991 * 32-bit value. This currently can be used on Linux Alpha
1992 * which uses 64-bit virtual address but a 32-bit bus address.
1993 * This is likely to break in the future, but doing this now
1994 * will give us time to change the HW and FW to handle 64-bit
1995 * addresses.
1996 */
1997#define ADV_VADDR_TO_U32 virt_to_bus
1998#define ADV_U32_TO_VADDR bus_to_virt
1999
27c868c2 2000#define AdvPortAddr void __iomem * /* Virtual memory address size */
1da177e4
LT
2001
2002/*
2003 * Define Adv Library required memory access macros.
2004 */
2005#define ADV_MEM_READB(addr) readb(addr)
2006#define ADV_MEM_READW(addr) readw(addr)
2007#define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
2008#define ADV_MEM_WRITEW(addr, word) writew(word, addr)
2009#define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
2010
2011#define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
2012
2013/*
2014 * For wide boards a CDB length maximum of 16 bytes
2015 * is supported.
2016 */
2017#define ADV_MAX_CDB_LEN 16
2018
2019/*
2020 * Define total number of simultaneous maximum element scatter-gather
2021 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
2022 * maximum number of outstanding commands per wide host adapter. Each
2023 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
2024 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
2025 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
2026 * structures or 255 scatter-gather elements.
2027 *
2028 */
2029#define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
2030
2031/*
2032 * Define Adv Library required maximum number of scatter-gather
2033 * elements per request.
2034 */
2035#define ADV_MAX_SG_LIST 255
2036
2037/* Number of SG blocks needed. */
2038#define ADV_NUM_SG_BLOCK \
2039 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
2040
2041/* Total contiguous memory needed for SG blocks. */
2042#define ADV_SG_TOTAL_MEM_SIZE \
2043 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
2044
2045#define ADV_PAGE_SIZE PAGE_SIZE
2046
2047#define ADV_NUM_PAGE_CROSSING \
2048 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2049
1da177e4
LT
2050#define ADV_EEP_DVC_CFG_BEGIN (0x00)
2051#define ADV_EEP_DVC_CFG_END (0x15)
27c868c2 2052#define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
1da177e4
LT
2053#define ADV_EEP_MAX_WORD_ADDR (0x1E)
2054
2055#define ADV_EEP_DELAY_MS 100
2056
27c868c2
MW
2057#define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
2058#define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
1da177e4
LT
2059/*
2060 * For the ASC3550 Bit 13 is Termination Polarity control bit.
2061 * For later ICs Bit 13 controls whether the CIS (Card Information
2062 * Service Section) is loaded from EEPROM.
2063 */
27c868c2
MW
2064#define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
2065#define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
1da177e4
LT
2066/*
2067 * ASC38C1600 Bit 11
2068 *
2069 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
2070 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
2071 * Function 0 will specify INT B.
2072 *
2073 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
2074 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
2075 * Function 1 will specify INT A.
2076 */
27c868c2
MW
2077#define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
2078
2079typedef struct adveep_3550_config {
2080 /* Word Offset, Description */
2081
2082 ushort cfg_lsw; /* 00 power up initialization */
2083 /* bit 13 set - Term Polarity Control */
2084 /* bit 14 set - BIOS Enable */
2085 /* bit 15 set - Big Endian Mode */
2086 ushort cfg_msw; /* 01 unused */
2087 ushort disc_enable; /* 02 disconnect enable */
2088 ushort wdtr_able; /* 03 Wide DTR able */
2089 ushort sdtr_able; /* 04 Synchronous DTR able */
2090 ushort start_motor; /* 05 send start up motor */
2091 ushort tagqng_able; /* 06 tag queuing able */
2092 ushort bios_scan; /* 07 BIOS device control */
2093 ushort scam_tolerant; /* 08 no scam */
2094
2095 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2096 uchar bios_boot_delay; /* power up wait */
2097
2098 uchar scsi_reset_delay; /* 10 reset delay */
2099 uchar bios_id_lun; /* first boot device scsi id & lun */
2100 /* high nibble is lun */
2101 /* low nibble is scsi id */
2102
2103 uchar termination; /* 11 0 - automatic */
2104 /* 1 - low off / high off */
2105 /* 2 - low off / high on */
2106 /* 3 - low on / high on */
2107 /* There is no low on / high off */
2108
2109 uchar reserved1; /* reserved byte (not used) */
2110
2111 ushort bios_ctrl; /* 12 BIOS control bits */
2112 /* bit 0 BIOS don't act as initiator. */
2113 /* bit 1 BIOS > 1 GB support */
2114 /* bit 2 BIOS > 2 Disk Support */
2115 /* bit 3 BIOS don't support removables */
2116 /* bit 4 BIOS support bootable CD */
2117 /* bit 5 BIOS scan enabled */
2118 /* bit 6 BIOS support multiple LUNs */
2119 /* bit 7 BIOS display of message */
2120 /* bit 8 SCAM disabled */
2121 /* bit 9 Reset SCSI bus during init. */
2122 /* bit 10 */
2123 /* bit 11 No verbose initialization. */
2124 /* bit 12 SCSI parity enabled */
2125 /* bit 13 */
2126 /* bit 14 */
2127 /* bit 15 */
2128 ushort ultra_able; /* 13 ULTRA speed able */
2129 ushort reserved2; /* 14 reserved */
2130 uchar max_host_qng; /* 15 maximum host queuing */
2131 uchar max_dvc_qng; /* maximum per device queuing */
2132 ushort dvc_cntl; /* 16 control bit for driver */
2133 ushort bug_fix; /* 17 control bit for bug fix */
2134 ushort serial_number_word1; /* 18 Board serial number word 1 */
2135 ushort serial_number_word2; /* 19 Board serial number word 2 */
2136 ushort serial_number_word3; /* 20 Board serial number word 3 */
2137 ushort check_sum; /* 21 EEP check sum */
2138 uchar oem_name[16]; /* 22 OEM name */
2139 ushort dvc_err_code; /* 30 last device driver error code */
2140 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2141 ushort adv_err_addr; /* 32 last uc error address */
2142 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2143 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2144 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2145 ushort num_of_err; /* 36 number of error */
1da177e4
LT
2146} ADVEEP_3550_CONFIG;
2147
27c868c2
MW
2148typedef struct adveep_38C0800_config {
2149 /* Word Offset, Description */
2150
2151 ushort cfg_lsw; /* 00 power up initialization */
2152 /* bit 13 set - Load CIS */
2153 /* bit 14 set - BIOS Enable */
2154 /* bit 15 set - Big Endian Mode */
2155 ushort cfg_msw; /* 01 unused */
2156 ushort disc_enable; /* 02 disconnect enable */
2157 ushort wdtr_able; /* 03 Wide DTR able */
2158 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2159 ushort start_motor; /* 05 send start up motor */
2160 ushort tagqng_able; /* 06 tag queuing able */
2161 ushort bios_scan; /* 07 BIOS device control */
2162 ushort scam_tolerant; /* 08 no scam */
2163
2164 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2165 uchar bios_boot_delay; /* power up wait */
2166
2167 uchar scsi_reset_delay; /* 10 reset delay */
2168 uchar bios_id_lun; /* first boot device scsi id & lun */
2169 /* high nibble is lun */
2170 /* low nibble is scsi id */
2171
2172 uchar termination_se; /* 11 0 - automatic */
2173 /* 1 - low off / high off */
2174 /* 2 - low off / high on */
2175 /* 3 - low on / high on */
2176 /* There is no low on / high off */
2177
2178 uchar termination_lvd; /* 11 0 - automatic */
2179 /* 1 - low off / high off */
2180 /* 2 - low off / high on */
2181 /* 3 - low on / high on */
2182 /* There is no low on / high off */
2183
2184 ushort bios_ctrl; /* 12 BIOS control bits */
2185 /* bit 0 BIOS don't act as initiator. */
2186 /* bit 1 BIOS > 1 GB support */
2187 /* bit 2 BIOS > 2 Disk Support */
2188 /* bit 3 BIOS don't support removables */
2189 /* bit 4 BIOS support bootable CD */
2190 /* bit 5 BIOS scan enabled */
2191 /* bit 6 BIOS support multiple LUNs */
2192 /* bit 7 BIOS display of message */
2193 /* bit 8 SCAM disabled */
2194 /* bit 9 Reset SCSI bus during init. */
2195 /* bit 10 */
2196 /* bit 11 No verbose initialization. */
2197 /* bit 12 SCSI parity enabled */
2198 /* bit 13 */
2199 /* bit 14 */
2200 /* bit 15 */
2201 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2202 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2203 uchar max_host_qng; /* 15 maximum host queueing */
2204 uchar max_dvc_qng; /* maximum per device queuing */
2205 ushort dvc_cntl; /* 16 control bit for driver */
2206 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2207 ushort serial_number_word1; /* 18 Board serial number word 1 */
2208 ushort serial_number_word2; /* 19 Board serial number word 2 */
2209 ushort serial_number_word3; /* 20 Board serial number word 3 */
2210 ushort check_sum; /* 21 EEP check sum */
2211 uchar oem_name[16]; /* 22 OEM name */
2212 ushort dvc_err_code; /* 30 last device driver error code */
2213 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2214 ushort adv_err_addr; /* 32 last uc error address */
2215 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2216 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2217 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2218 ushort reserved36; /* 36 reserved */
2219 ushort reserved37; /* 37 reserved */
2220 ushort reserved38; /* 38 reserved */
2221 ushort reserved39; /* 39 reserved */
2222 ushort reserved40; /* 40 reserved */
2223 ushort reserved41; /* 41 reserved */
2224 ushort reserved42; /* 42 reserved */
2225 ushort reserved43; /* 43 reserved */
2226 ushort reserved44; /* 44 reserved */
2227 ushort reserved45; /* 45 reserved */
2228 ushort reserved46; /* 46 reserved */
2229 ushort reserved47; /* 47 reserved */
2230 ushort reserved48; /* 48 reserved */
2231 ushort reserved49; /* 49 reserved */
2232 ushort reserved50; /* 50 reserved */
2233 ushort reserved51; /* 51 reserved */
2234 ushort reserved52; /* 52 reserved */
2235 ushort reserved53; /* 53 reserved */
2236 ushort reserved54; /* 54 reserved */
2237 ushort reserved55; /* 55 reserved */
2238 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2239 ushort cisprt_msw; /* 57 CIS PTR MSW */
2240 ushort subsysvid; /* 58 SubSystem Vendor ID */
2241 ushort subsysid; /* 59 SubSystem ID */
2242 ushort reserved60; /* 60 reserved */
2243 ushort reserved61; /* 61 reserved */
2244 ushort reserved62; /* 62 reserved */
2245 ushort reserved63; /* 63 reserved */
1da177e4
LT
2246} ADVEEP_38C0800_CONFIG;
2247
27c868c2
MW
2248typedef struct adveep_38C1600_config {
2249 /* Word Offset, Description */
2250
2251 ushort cfg_lsw; /* 00 power up initialization */
2252 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
2253 /* clear - Func. 0 INTA, Func. 1 INTB */
2254 /* bit 13 set - Load CIS */
2255 /* bit 14 set - BIOS Enable */
2256 /* bit 15 set - Big Endian Mode */
2257 ushort cfg_msw; /* 01 unused */
2258 ushort disc_enable; /* 02 disconnect enable */
2259 ushort wdtr_able; /* 03 Wide DTR able */
2260 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2261 ushort start_motor; /* 05 send start up motor */
2262 ushort tagqng_able; /* 06 tag queuing able */
2263 ushort bios_scan; /* 07 BIOS device control */
2264 ushort scam_tolerant; /* 08 no scam */
2265
2266 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2267 uchar bios_boot_delay; /* power up wait */
2268
2269 uchar scsi_reset_delay; /* 10 reset delay */
2270 uchar bios_id_lun; /* first boot device scsi id & lun */
2271 /* high nibble is lun */
2272 /* low nibble is scsi id */
2273
2274 uchar termination_se; /* 11 0 - automatic */
2275 /* 1 - low off / high off */
2276 /* 2 - low off / high on */
2277 /* 3 - low on / high on */
2278 /* There is no low on / high off */
2279
2280 uchar termination_lvd; /* 11 0 - automatic */
2281 /* 1 - low off / high off */
2282 /* 2 - low off / high on */
2283 /* 3 - low on / high on */
2284 /* There is no low on / high off */
2285
2286 ushort bios_ctrl; /* 12 BIOS control bits */
2287 /* bit 0 BIOS don't act as initiator. */
2288 /* bit 1 BIOS > 1 GB support */
2289 /* bit 2 BIOS > 2 Disk Support */
2290 /* bit 3 BIOS don't support removables */
2291 /* bit 4 BIOS support bootable CD */
2292 /* bit 5 BIOS scan enabled */
2293 /* bit 6 BIOS support multiple LUNs */
2294 /* bit 7 BIOS display of message */
2295 /* bit 8 SCAM disabled */
2296 /* bit 9 Reset SCSI bus during init. */
2297 /* bit 10 Basic Integrity Checking disabled */
2298 /* bit 11 No verbose initialization. */
2299 /* bit 12 SCSI parity enabled */
2300 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
2301 /* bit 14 */
2302 /* bit 15 */
2303 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2304 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2305 uchar max_host_qng; /* 15 maximum host queueing */
2306 uchar max_dvc_qng; /* maximum per device queuing */
2307 ushort dvc_cntl; /* 16 control bit for driver */
2308 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2309 ushort serial_number_word1; /* 18 Board serial number word 1 */
2310 ushort serial_number_word2; /* 19 Board serial number word 2 */
2311 ushort serial_number_word3; /* 20 Board serial number word 3 */
2312 ushort check_sum; /* 21 EEP check sum */
2313 uchar oem_name[16]; /* 22 OEM name */
2314 ushort dvc_err_code; /* 30 last device driver error code */
2315 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2316 ushort adv_err_addr; /* 32 last uc error address */
2317 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2318 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2319 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2320 ushort reserved36; /* 36 reserved */
2321 ushort reserved37; /* 37 reserved */
2322 ushort reserved38; /* 38 reserved */
2323 ushort reserved39; /* 39 reserved */
2324 ushort reserved40; /* 40 reserved */
2325 ushort reserved41; /* 41 reserved */
2326 ushort reserved42; /* 42 reserved */
2327 ushort reserved43; /* 43 reserved */
2328 ushort reserved44; /* 44 reserved */
2329 ushort reserved45; /* 45 reserved */
2330 ushort reserved46; /* 46 reserved */
2331 ushort reserved47; /* 47 reserved */
2332 ushort reserved48; /* 48 reserved */
2333 ushort reserved49; /* 49 reserved */
2334 ushort reserved50; /* 50 reserved */
2335 ushort reserved51; /* 51 reserved */
2336 ushort reserved52; /* 52 reserved */
2337 ushort reserved53; /* 53 reserved */
2338 ushort reserved54; /* 54 reserved */
2339 ushort reserved55; /* 55 reserved */
2340 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2341 ushort cisprt_msw; /* 57 CIS PTR MSW */
2342 ushort subsysvid; /* 58 SubSystem Vendor ID */
2343 ushort subsysid; /* 59 SubSystem ID */
2344 ushort reserved60; /* 60 reserved */
2345 ushort reserved61; /* 61 reserved */
2346 ushort reserved62; /* 62 reserved */
2347 ushort reserved63; /* 63 reserved */
1da177e4
LT
2348} ADVEEP_38C1600_CONFIG;
2349
2350/*
2351 * EEPROM Commands
2352 */
2353#define ASC_EEP_CMD_DONE 0x0200
2354#define ASC_EEP_CMD_DONE_ERR 0x0001
2355
2356/* cfg_word */
2357#define EEP_CFG_WORD_BIG_ENDIAN 0x8000
2358
2359/* bios_ctrl */
2360#define BIOS_CTRL_BIOS 0x0001
2361#define BIOS_CTRL_EXTENDED_XLAT 0x0002
2362#define BIOS_CTRL_GT_2_DISK 0x0004
2363#define BIOS_CTRL_BIOS_REMOVABLE 0x0008
2364#define BIOS_CTRL_BOOTABLE_CD 0x0010
2365#define BIOS_CTRL_MULTIPLE_LUN 0x0040
2366#define BIOS_CTRL_DISPLAY_MSG 0x0080
2367#define BIOS_CTRL_NO_SCAM 0x0100
2368#define BIOS_CTRL_RESET_SCSI_BUS 0x0200
2369#define BIOS_CTRL_INIT_VERBOSE 0x0800
2370#define BIOS_CTRL_SCSI_PARITY 0x1000
2371#define BIOS_CTRL_AIPP_DIS 0x2000
2372
27c868c2
MW
2373#define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
2374#define ADV_3550_IOLEN 0x40 /* I/O Port Range in bytes */
1da177e4 2375
27c868c2
MW
2376#define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2377#define ADV_38C0800_IOLEN 0x100 /* I/O Port Range in bytes */
1da177e4
LT
2378
2379/*
2380 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
2381 * a special 16K Adv Library and Microcode version. After the issue is
2382 * resolved, should restore 32K support.
2383 *
2384 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
2385 */
27c868c2
MW
2386#define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2387#define ADV_38C1600_IOLEN 0x100 /* I/O Port Range 256 bytes */
2388#define ADV_38C1600_MEMLEN 0x1000 /* Memory Range 4KB bytes */
1da177e4
LT
2389
2390/*
2391 * Byte I/O register address from base of 'iop_base'.
2392 */
2393#define IOPB_INTR_STATUS_REG 0x00
2394#define IOPB_CHIP_ID_1 0x01
2395#define IOPB_INTR_ENABLES 0x02
2396#define IOPB_CHIP_TYPE_REV 0x03
2397#define IOPB_RES_ADDR_4 0x04
2398#define IOPB_RES_ADDR_5 0x05
2399#define IOPB_RAM_DATA 0x06
2400#define IOPB_RES_ADDR_7 0x07
2401#define IOPB_FLAG_REG 0x08
2402#define IOPB_RES_ADDR_9 0x09
2403#define IOPB_RISC_CSR 0x0A
2404#define IOPB_RES_ADDR_B 0x0B
2405#define IOPB_RES_ADDR_C 0x0C
2406#define IOPB_RES_ADDR_D 0x0D
2407#define IOPB_SOFT_OVER_WR 0x0E
2408#define IOPB_RES_ADDR_F 0x0F
2409#define IOPB_MEM_CFG 0x10
2410#define IOPB_RES_ADDR_11 0x11
2411#define IOPB_GPIO_DATA 0x12
2412#define IOPB_RES_ADDR_13 0x13
2413#define IOPB_FLASH_PAGE 0x14
2414#define IOPB_RES_ADDR_15 0x15
2415#define IOPB_GPIO_CNTL 0x16
2416#define IOPB_RES_ADDR_17 0x17
2417#define IOPB_FLASH_DATA 0x18
2418#define IOPB_RES_ADDR_19 0x19
2419#define IOPB_RES_ADDR_1A 0x1A
2420#define IOPB_RES_ADDR_1B 0x1B
2421#define IOPB_RES_ADDR_1C 0x1C
2422#define IOPB_RES_ADDR_1D 0x1D
2423#define IOPB_RES_ADDR_1E 0x1E
2424#define IOPB_RES_ADDR_1F 0x1F
2425#define IOPB_DMA_CFG0 0x20
2426#define IOPB_DMA_CFG1 0x21
2427#define IOPB_TICKLE 0x22
2428#define IOPB_DMA_REG_WR 0x23
2429#define IOPB_SDMA_STATUS 0x24
2430#define IOPB_SCSI_BYTE_CNT 0x25
2431#define IOPB_HOST_BYTE_CNT 0x26
2432#define IOPB_BYTE_LEFT_TO_XFER 0x27
2433#define IOPB_BYTE_TO_XFER_0 0x28
2434#define IOPB_BYTE_TO_XFER_1 0x29
2435#define IOPB_BYTE_TO_XFER_2 0x2A
2436#define IOPB_BYTE_TO_XFER_3 0x2B
2437#define IOPB_ACC_GRP 0x2C
2438#define IOPB_RES_ADDR_2D 0x2D
2439#define IOPB_DEV_ID 0x2E
2440#define IOPB_RES_ADDR_2F 0x2F
2441#define IOPB_SCSI_DATA 0x30
2442#define IOPB_RES_ADDR_31 0x31
2443#define IOPB_RES_ADDR_32 0x32
2444#define IOPB_SCSI_DATA_HSHK 0x33
2445#define IOPB_SCSI_CTRL 0x34
2446#define IOPB_RES_ADDR_35 0x35
2447#define IOPB_RES_ADDR_36 0x36
2448#define IOPB_RES_ADDR_37 0x37
2449#define IOPB_RAM_BIST 0x38
2450#define IOPB_PLL_TEST 0x39
2451#define IOPB_PCI_INT_CFG 0x3A
2452#define IOPB_RES_ADDR_3B 0x3B
2453#define IOPB_RFIFO_CNT 0x3C
2454#define IOPB_RES_ADDR_3D 0x3D
2455#define IOPB_RES_ADDR_3E 0x3E
2456#define IOPB_RES_ADDR_3F 0x3F
2457
2458/*
2459 * Word I/O register address from base of 'iop_base'.
2460 */
27c868c2
MW
2461#define IOPW_CHIP_ID_0 0x00 /* CID0 */
2462#define IOPW_CTRL_REG 0x02 /* CC */
2463#define IOPW_RAM_ADDR 0x04 /* LA */
2464#define IOPW_RAM_DATA 0x06 /* LD */
1da177e4 2465#define IOPW_RES_ADDR_08 0x08
27c868c2
MW
2466#define IOPW_RISC_CSR 0x0A /* CSR */
2467#define IOPW_SCSI_CFG0 0x0C /* CFG0 */
2468#define IOPW_SCSI_CFG1 0x0E /* CFG1 */
1da177e4 2469#define IOPW_RES_ADDR_10 0x10
27c868c2 2470#define IOPW_SEL_MASK 0x12 /* SM */
1da177e4 2471#define IOPW_RES_ADDR_14 0x14
27c868c2 2472#define IOPW_FLASH_ADDR 0x16 /* FA */
1da177e4 2473#define IOPW_RES_ADDR_18 0x18
27c868c2
MW
2474#define IOPW_EE_CMD 0x1A /* EC */
2475#define IOPW_EE_DATA 0x1C /* ED */
2476#define IOPW_SFIFO_CNT 0x1E /* SFC */
1da177e4 2477#define IOPW_RES_ADDR_20 0x20
27c868c2
MW
2478#define IOPW_Q_BASE 0x22 /* QB */
2479#define IOPW_QP 0x24 /* QP */
2480#define IOPW_IX 0x26 /* IX */
2481#define IOPW_SP 0x28 /* SP */
2482#define IOPW_PC 0x2A /* PC */
1da177e4
LT
2483#define IOPW_RES_ADDR_2C 0x2C
2484#define IOPW_RES_ADDR_2E 0x2E
27c868c2
MW
2485#define IOPW_SCSI_DATA 0x30 /* SD */
2486#define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
2487#define IOPW_SCSI_CTRL 0x34 /* SC */
2488#define IOPW_HSHK_CFG 0x36 /* HCFG */
2489#define IOPW_SXFR_STATUS 0x36 /* SXS */
2490#define IOPW_SXFR_CNTL 0x38 /* SXL */
2491#define IOPW_SXFR_CNTH 0x3A /* SXH */
1da177e4 2492#define IOPW_RES_ADDR_3C 0x3C
27c868c2 2493#define IOPW_RFIFO_DATA 0x3E /* RFD */
1da177e4
LT
2494
2495/*
2496 * Doubleword I/O register address from base of 'iop_base'.
2497 */
2498#define IOPDW_RES_ADDR_0 0x00
2499#define IOPDW_RAM_DATA 0x04
2500#define IOPDW_RES_ADDR_8 0x08
2501#define IOPDW_RES_ADDR_C 0x0C
2502#define IOPDW_RES_ADDR_10 0x10
2503#define IOPDW_COMMA 0x14
2504#define IOPDW_COMMB 0x18
2505#define IOPDW_RES_ADDR_1C 0x1C
2506#define IOPDW_SDMA_ADDR0 0x20
2507#define IOPDW_SDMA_ADDR1 0x24
2508#define IOPDW_SDMA_COUNT 0x28
2509#define IOPDW_SDMA_ERROR 0x2C
2510#define IOPDW_RDMA_ADDR0 0x30
2511#define IOPDW_RDMA_ADDR1 0x34
2512#define IOPDW_RDMA_COUNT 0x38
2513#define IOPDW_RDMA_ERROR 0x3C
2514
2515#define ADV_CHIP_ID_BYTE 0x25
2516#define ADV_CHIP_ID_WORD 0x04C1
2517
2518#define ADV_SC_SCSI_BUS_RESET 0x2000
2519
2520#define ADV_INTR_ENABLE_HOST_INTR 0x01
2521#define ADV_INTR_ENABLE_SEL_INTR 0x02
2522#define ADV_INTR_ENABLE_DPR_INTR 0x04
2523#define ADV_INTR_ENABLE_RTA_INTR 0x08
2524#define ADV_INTR_ENABLE_RMA_INTR 0x10
2525#define ADV_INTR_ENABLE_RST_INTR 0x20
2526#define ADV_INTR_ENABLE_DPE_INTR 0x40
2527#define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
2528
2529#define ADV_INTR_STATUS_INTRA 0x01
2530#define ADV_INTR_STATUS_INTRB 0x02
2531#define ADV_INTR_STATUS_INTRC 0x04
2532
2533#define ADV_RISC_CSR_STOP (0x0000)
2534#define ADV_RISC_TEST_COND (0x2000)
2535#define ADV_RISC_CSR_RUN (0x4000)
2536#define ADV_RISC_CSR_SINGLE_STEP (0x8000)
2537
2538#define ADV_CTRL_REG_HOST_INTR 0x0100
2539#define ADV_CTRL_REG_SEL_INTR 0x0200
2540#define ADV_CTRL_REG_DPR_INTR 0x0400
2541#define ADV_CTRL_REG_RTA_INTR 0x0800
2542#define ADV_CTRL_REG_RMA_INTR 0x1000
2543#define ADV_CTRL_REG_RES_BIT14 0x2000
2544#define ADV_CTRL_REG_DPE_INTR 0x4000
2545#define ADV_CTRL_REG_POWER_DONE 0x8000
2546#define ADV_CTRL_REG_ANY_INTR 0xFF00
2547
2548#define ADV_CTRL_REG_CMD_RESET 0x00C6
2549#define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
2550#define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
2551#define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
2552#define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
2553
2554#define ADV_TICKLE_NOP 0x00
2555#define ADV_TICKLE_A 0x01
2556#define ADV_TICKLE_B 0x02
2557#define ADV_TICKLE_C 0x03
2558
2559#define ADV_SCSI_CTRL_RSTOUT 0x2000
2560
2561#define AdvIsIntPending(port) \
2562 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2563
2564/*
2565 * SCSI_CFG0 Register bit definitions
2566 */
27c868c2
MW
2567#define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
2568#define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
2569#define EVEN_PARITY 0x1000 /* Select Even Parity */
2570#define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2571#define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
2572#define PRIM_MODE 0x0100 /* Primitive SCSI mode */
2573#define SCAM_EN 0x0080 /* Enable SCAM selection */
2574#define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2575#define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2576#define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
2577#define OUR_ID 0x000F /* SCSI ID */
1da177e4
LT
2578
2579/*
2580 * SCSI_CFG1 Register bit definitions
2581 */
27c868c2
MW
2582#define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
2583#define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2584#define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
2585#define FILTER_SEL 0x0C00 /* Filter Period Selection */
2586#define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
2587#define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
2588#define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
2589#define ACTIVE_DBL 0x0200 /* Disable Active Negation */
2590#define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
2591#define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
2592#define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
2593#define TERM_CTL 0x0030 /* External SCSI Termination Bits */
2594#define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
2595#define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
2596#define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
1da177e4
LT
2597
2598/*
2599 * Addendum for ASC-38C0800 Chip
2600 *
2601 * The ASC-38C1600 Chip uses the same definitions except that the
2602 * bus mode override bits [12:10] have been moved to byte register
2603 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
2604 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
2605 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
2606 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
2607 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
2608 */
27c868c2
MW
2609#define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
2610#define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
2611#define HVD 0x1000 /* HVD Device Detect */
2612#define LVD 0x0800 /* LVD Device Detect */
2613#define SE 0x0400 /* SE Device Detect */
2614#define TERM_LVD 0x00C0 /* LVD Termination Bits */
2615#define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
2616#define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
2617#define TERM_SE 0x0030 /* SE Termination Bits */
2618#define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
2619#define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
2620#define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
2621#define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
2622#define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
2623#define C_DET_SE 0x0003 /* SE Cable Detect Bits */
2624#define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
2625#define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
1da177e4
LT
2626
2627#define CABLE_ILLEGAL_A 0x7
2628 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
2629
2630#define CABLE_ILLEGAL_B 0xB
2631 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
2632
2633/*
2634 * MEM_CFG Register bit definitions
2635 */
27c868c2
MW
2636#define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
2637#define FAST_EE_CLK 0x20 /* Diagnostic Bit */
2638#define RAM_SZ 0x1C /* Specify size of RAM to RISC */
2639#define RAM_SZ_2KB 0x00 /* 2 KB */
2640#define RAM_SZ_4KB 0x04 /* 4 KB */
2641#define RAM_SZ_8KB 0x08 /* 8 KB */
2642#define RAM_SZ_16KB 0x0C /* 16 KB */
2643#define RAM_SZ_32KB 0x10 /* 32 KB */
2644#define RAM_SZ_64KB 0x14 /* 64 KB */
1da177e4
LT
2645
2646/*
2647 * DMA_CFG0 Register bit definitions
2648 *
2649 * This register is only accessible to the host.
2650 */
27c868c2
MW
2651#define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
2652#define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
2653#define FIFO_THRESH_16B 0x00 /* 16 bytes */
2654#define FIFO_THRESH_32B 0x20 /* 32 bytes */
2655#define FIFO_THRESH_48B 0x30 /* 48 bytes */
2656#define FIFO_THRESH_64B 0x40 /* 64 bytes */
2657#define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
2658#define FIFO_THRESH_96B 0x60 /* 96 bytes */
2659#define FIFO_THRESH_112B 0x70 /* 112 bytes */
2660#define START_CTL 0x0C /* DMA start conditions */
2661#define START_CTL_TH 0x00 /* Wait threshold level (default) */
2662#define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
2663#define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
2664#define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
2665#define READ_CMD 0x03 /* Memory Read Method */
2666#define READ_CMD_MR 0x00 /* Memory Read */
2667#define READ_CMD_MRL 0x02 /* Memory Read Long */
2668#define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
1da177e4
LT
2669
2670/*
2671 * ASC-38C0800 RAM BIST Register bit definitions
2672 */
2673#define RAM_TEST_MODE 0x80
2674#define PRE_TEST_MODE 0x40
2675#define NORMAL_MODE 0x00
2676#define RAM_TEST_DONE 0x10
2677#define RAM_TEST_STATUS 0x0F
2678#define RAM_TEST_HOST_ERROR 0x08
2679#define RAM_TEST_INTRAM_ERROR 0x04
2680#define RAM_TEST_RISC_ERROR 0x02
2681#define RAM_TEST_SCSI_ERROR 0x01
2682#define RAM_TEST_SUCCESS 0x00
2683#define PRE_TEST_VALUE 0x05
2684#define NORMAL_VALUE 0x00
2685
2686/*
2687 * ASC38C1600 Definitions
2688 *
2689 * IOPB_PCI_INT_CFG Bit Field Definitions
2690 */
2691
27c868c2 2692#define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
1da177e4
LT
2693
2694/*
2695 * Bit 1 can be set to change the interrupt for the Function to operate in
2696 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
2697 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
2698 * mode, otherwise the operating mode is undefined.
2699 */
2700#define TOTEMPOLE 0x02
2701
2702/*
2703 * Bit 0 can be used to change the Int Pin for the Function. The value is
2704 * 0 by default for both Functions with Function 0 using INT A and Function
2705 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
2706 * INT A is used.
2707 *
2708 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
2709 * value specified in the PCI Configuration Space.
2710 */
2711#define INTAB 0x01
2712
2713/* a_advlib.h */
2714
2715/*
2716 * Adv Library Status Definitions
2717 */
2718#define ADV_TRUE 1
2719#define ADV_FALSE 0
2720#define ADV_NOERROR 1
2721#define ADV_SUCCESS 1
2722#define ADV_BUSY 0
2723#define ADV_ERROR (-1)
2724
1da177e4
LT
2725/*
2726 * ADV_DVC_VAR 'warn_code' values
2727 */
27c868c2
MW
2728#define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
2729#define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
2730#define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
2731#define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */
2732#define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
1da177e4 2733
27c868c2
MW
2734#define ADV_MAX_TID 15 /* max. target identifier */
2735#define ADV_MAX_LUN 7 /* max. logical unit number */
1da177e4
LT
2736
2737/*
2738 * Error code values are set in ADV_DVC_VAR 'err_code'.
2739 */
27c868c2
MW
2740#define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */
2741#define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
2742#define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */
2743#define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
2744#define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */
2745#define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
2746#define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */
2747#define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
2748#define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
2749#define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */
2750#define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */
2751#define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */
2752#define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */
2753#define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */
1da177e4
LT
2754
2755/*
2756 * Fixed locations of microcode operating variables.
2757 */
27c868c2
MW
2758#define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
2759#define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
2760#define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
2761#define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
2762#define ASC_MC_VERSION_NUM 0x003A /* microcode number */
2763#define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
2764#define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
2765#define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
2766#define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
2767#define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
2768#define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
2769#define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
2770#define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
1da177e4
LT
2771#define ASC_MC_CHIP_TYPE 0x009A
2772#define ASC_MC_INTRB_CODE 0x009B
2773#define ASC_MC_WDTR_ABLE 0x009C
2774#define ASC_MC_SDTR_ABLE 0x009E
2775#define ASC_MC_TAGQNG_ABLE 0x00A0
2776#define ASC_MC_DISC_ENABLE 0x00A2
2777#define ASC_MC_IDLE_CMD_STATUS 0x00A4
2778#define ASC_MC_IDLE_CMD 0x00A6
2779#define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
2780#define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
2781#define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
2782#define ASC_MC_DEFAULT_MEM_CFG 0x00B0
2783#define ASC_MC_DEFAULT_SEL_MASK 0x00B2
2784#define ASC_MC_SDTR_DONE 0x00B6
2785#define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
2786#define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
2787#define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
27c868c2 2788#define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
1da177e4 2789#define ASC_MC_WDTR_DONE 0x0124
27c868c2 2790#define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
1da177e4
LT
2791#define ASC_MC_ICQ 0x0160
2792#define ASC_MC_IRQ 0x0164
2793#define ASC_MC_PPR_ABLE 0x017A
2794
2795/*
2796 * BIOS LRAM variable absolute offsets.
2797 */
2798#define BIOS_CODESEG 0x54
2799#define BIOS_CODELEN 0x56
2800#define BIOS_SIGNATURE 0x58
2801#define BIOS_VERSION 0x5A
2802
2803/*
2804 * Microcode Control Flags
2805 *
2806 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2807 * and handled by the microcode.
2808 */
27c868c2
MW
2809#define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
2810#define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
1da177e4
LT
2811
2812/*
2813 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2814 */
2815#define HSHK_CFG_WIDE_XFR 0x8000
2816#define HSHK_CFG_RATE 0x0F00
2817#define HSHK_CFG_OFFSET 0x001F
2818
27c868c2
MW
2819#define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
2820#define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
2821#define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
2822#define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
2823
2824#define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2825#define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
2826#define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2827#define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
2828#define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2829
2830#define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
2831#define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
2832#define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
2833#define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
2834#define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
1da177e4
LT
2835/*
2836 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
2837 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
2838 */
27c868c2
MW
2839#define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
2840#define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
1da177e4
LT
2841
2842/*
2843 * All fields here are accessed by the board microcode and need to be
2844 * little-endian.
2845 */
27c868c2
MW
2846typedef struct adv_carr_t {
2847 ADV_VADDR carr_va; /* Carrier Virtual Address */
2848 ADV_PADDR carr_pa; /* Carrier Physical Address */
2849 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
2850 /*
2851 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
2852 *
2853 * next_vpa [3:1] Reserved Bits
2854 * next_vpa [0] Done Flag set in Response Queue.
2855 */
2856 ADV_VADDR next_vpa;
1da177e4
LT
2857} ADV_CARR_T;
2858
2859/*
2860 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2861 */
2862#define ASC_NEXT_VPA_MASK 0xFFFFFFF0
2863
2864#define ASC_RQ_DONE 0x00000001
2865#define ASC_RQ_GOOD 0x00000002
2866#define ASC_CQ_STOPPER 0x00000000
2867
2868#define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2869
2870#define ADV_CARRIER_NUM_PAGE_CROSSING \
2871 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2872 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2873
2874#define ADV_CARRIER_BUFSIZE \
2875 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2876
2877/*
2878 * ASC_SCSI_REQ_Q 'a_flag' definitions
2879 *
2880 * The Adv Library should limit use to the lower nibble (4 bits) of
2881 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2882 */
27c868c2
MW
2883#define ADV_POLL_REQUEST 0x01 /* poll for request completion */
2884#define ADV_SCSIQ_DONE 0x02 /* request done */
2885#define ADV_DONT_RETRY 0x08 /* don't do retry */
1da177e4 2886
27c868c2
MW
2887#define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
2888#define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
2889#define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
1da177e4
LT
2890
2891/*
2892 * Adapter temporary configuration structure
2893 *
2894 * This structure can be discarded after initialization. Don't add
2895 * fields here needed after initialization.
2896 *
2897 * Field naming convention:
2898 *
2899 * *_enable indicates the field enables or disables a feature. The
2900 * value of the field is never reset.
2901 */
2902typedef struct adv_dvc_cfg {
27c868c2
MW
2903 ushort disc_enable; /* enable disconnection */
2904 uchar chip_version; /* chip version */
2905 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2906 ushort lib_version; /* Adv Library version number */
2907 ushort control_flag; /* Microcode Control Flag */
2908 ushort mcode_date; /* Microcode date */
2909 ushort mcode_version; /* Microcode version */
2910 ushort pci_slot_info; /* high byte device/function number */
2911 /* bits 7-3 device num., bits 2-0 function num. */
2912 /* low byte bus num. */
2913 ushort serial1; /* EEPROM serial number word 1 */
2914 ushort serial2; /* EEPROM serial number word 2 */
2915 ushort serial3; /* EEPROM serial number word 3 */
2916 struct device *dev; /* pointer to the pci dev structure for this board */
1da177e4
LT
2917} ADV_DVC_CFG;
2918
2919struct adv_dvc_var;
2920struct adv_scsi_req_q;
2921
27c868c2
MW
2922typedef void (*ADV_ISR_CALLBACK)
2923 (struct adv_dvc_var *, struct adv_scsi_req_q *);
1da177e4 2924
27c868c2
MW
2925typedef void (*ADV_ASYNC_CALLBACK)
2926 (struct adv_dvc_var *, uchar);
1da177e4
LT
2927
2928/*
2929 * Adapter operation variable structure.
2930 *
2931 * One structure is required per host adapter.
2932 *
2933 * Field naming convention:
2934 *
2935 * *_able indicates both whether a feature should be enabled or disabled
2936 * and whether a device isi capable of the feature. At initialization
2937 * this field may be set, but later if a device is found to be incapable
2938 * of the feature, the field is cleared.
2939 */
2940typedef struct adv_dvc_var {
27c868c2
MW
2941 AdvPortAddr iop_base; /* I/O port address */
2942 ushort err_code; /* fatal error code */
2943 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
2944 ADV_ISR_CALLBACK isr_callback;
2945 ADV_ASYNC_CALLBACK async_callback;
2946 ushort wdtr_able; /* try WDTR for a device */
2947 ushort sdtr_able; /* try SDTR for a device */
2948 ushort ultra_able; /* try SDTR Ultra speed for a device */
2949 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
2950 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
2951 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
2952 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
2953 ushort tagqng_able; /* try tagged queuing with a device */
2954 ushort ppr_able; /* PPR message capable per TID bitmask. */
2955 uchar max_dvc_qng; /* maximum number of tagged commands per device */
2956 ushort start_motor; /* start motor command allowed */
2957 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
2958 uchar chip_no; /* should be assigned by caller */
2959 uchar max_host_qng; /* maximum number of Q'ed command allowed */
2960 uchar irq_no; /* IRQ number */
2961 ushort no_scam; /* scam_tolerant of EEPROM */
2962 struct asc_board *drv_ptr; /* driver pointer to private structure */
2963 uchar chip_scsi_id; /* chip SCSI target ID */
2964 uchar chip_type;
2965 uchar bist_err_code;
2966 ADV_CARR_T *carrier_buf;
2967 ADV_CARR_T *carr_freelist; /* Carrier free list. */
2968 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
2969 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
2970 ushort carr_pending_cnt; /* Count of pending carriers. */
2971 /*
2972 * Note: The following fields will not be used after initialization. The
2973 * driver may discard the buffer after initialization is done.
2974 */
2975 ADV_DVC_CFG *cfg; /* temporary configuration structure */
1da177e4
LT
2976} ADV_DVC_VAR;
2977
2978#define NO_OF_SG_PER_BLOCK 15
2979
2980typedef struct asc_sg_block {
27c868c2
MW
2981 uchar reserved1;
2982 uchar reserved2;
2983 uchar reserved3;
2984 uchar sg_cnt; /* Valid entries in block. */
2985 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
2986 struct {
2987 ADV_PADDR sg_addr; /* SG element address. */
2988 ADV_DCNT sg_count; /* SG element count. */
2989 } sg_list[NO_OF_SG_PER_BLOCK];
1da177e4
LT
2990} ADV_SG_BLOCK;
2991
2992/*
2993 * ADV_SCSI_REQ_Q - microcode request structure
2994 *
2995 * All fields in this structure up to byte 60 are used by the microcode.
2996 * The microcode makes assumptions about the size and ordering of fields
2997 * in this structure. Do not change the structure definition here without
2998 * coordinating the change with the microcode.
2999 *
3000 * All fields accessed by microcode must be maintained in little_endian
3001 * order.
3002 */
3003typedef struct adv_scsi_req_q {
27c868c2
MW
3004 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
3005 uchar target_cmd;
3006 uchar target_id; /* Device target identifier. */
3007 uchar target_lun; /* Device target logical unit number. */
3008 ADV_PADDR data_addr; /* Data buffer physical address. */
3009 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
3010 ADV_PADDR sense_addr;
3011 ADV_PADDR carr_pa;
3012 uchar mflag;
3013 uchar sense_len;
3014 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
3015 uchar scsi_cntl;
3016 uchar done_status; /* Completion status. */
3017 uchar scsi_status; /* SCSI status byte. */
3018 uchar host_status; /* Ucode host status. */
3019 uchar sg_working_ix;
3020 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
3021 ADV_PADDR sg_real_addr; /* SG list physical address. */
3022 ADV_PADDR scsiq_rptr;
3023 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
3024 ADV_VADDR scsiq_ptr;
3025 ADV_VADDR carr_va;
3026 /*
3027 * End of microcode structure - 60 bytes. The rest of the structure
3028 * is used by the Adv Library and ignored by the microcode.
3029 */
3030 ADV_VADDR srb_ptr;
3031 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
3032 char *vdata_addr; /* Data buffer virtual address. */
3033 uchar a_flag;
3034 uchar pad[2]; /* Pad out to a word boundary. */
1da177e4
LT
3035} ADV_SCSI_REQ_Q;
3036
3037/*
3038 * Microcode idle loop commands
3039 */
3040#define IDLE_CMD_COMPLETED 0
3041#define IDLE_CMD_STOP_CHIP 0x0001
3042#define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
3043#define IDLE_CMD_SEND_INT 0x0004
3044#define IDLE_CMD_ABORT 0x0008
3045#define IDLE_CMD_DEVICE_RESET 0x0010
27c868c2
MW
3046#define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
3047#define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
1da177e4
LT
3048#define IDLE_CMD_SCSIREQ 0x0080
3049
3050#define IDLE_CMD_STATUS_SUCCESS 0x0001
3051#define IDLE_CMD_STATUS_FAILURE 0x0002
3052
3053/*
3054 * AdvSendIdleCmd() flag definitions.
3055 */
3056#define ADV_NOWAIT 0x01
3057
3058/*
3059 * Wait loop time out values.
3060 */
27c868c2
MW
3061#define SCSI_WAIT_10_SEC 10UL /* 10 seconds */
3062#define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
3063#define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
3064#define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */
3065#define SCSI_MAX_RETRY 10 /* retry count */
1da177e4 3066
27c868c2
MW
3067#define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
3068#define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
3069#define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
3070#define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
1da177e4 3071
27c868c2 3072#define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
1da177e4
LT
3073
3074/*
3075 * Device drivers must define the following functions.
3076 */
27c868c2
MW
3077static inline ulong DvcEnterCritical(void);
3078static inline void DvcLeaveCritical(ulong);
3079static void DvcSleepMilliSecond(ADV_DCNT);
3080static uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
3081static void DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
3082static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
3083 uchar *, ASC_SDCNT *, int);
3084static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
1da177e4
LT
3085
3086/*
3087 * Adv Library functions available to drivers.
3088 */
27c868c2
MW
3089static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3090static int AdvISR(ADV_DVC_VAR *);
3091static int AdvInitGetConfig(ADV_DVC_VAR *);
3092static int AdvInitAsc3550Driver(ADV_DVC_VAR *);
3093static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
3094static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
3095static int AdvResetChipAndSB(ADV_DVC_VAR *);
3096static int AdvResetSB(ADV_DVC_VAR *asc_dvc);
1da177e4
LT
3097
3098/*
3099 * Internal Adv Library functions.
3100 */
27c868c2
MW
3101static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
3102static void AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3103static int AdvInitFrom3550EEP(ADV_DVC_VAR *);
3104static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
3105static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
3106static ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3107static void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3108static ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3109static void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3110static ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3111static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3112static void AdvWaitEEPCmd(AdvPortAddr);
3113static ushort AdvReadEEPWord(AdvPortAddr, int);
1da177e4
LT
3114
3115/*
3116 * PCI Bus Definitions
3117 */
3118#define AscPCICmdRegBits_BusMastering 0x0007
3119#define AscPCICmdRegBits_ParErrRespCtrl 0x0040
3120
3121/* Read byte from a register. */
3122#define AdvReadByteRegister(iop_base, reg_off) \
3123 (ADV_MEM_READB((iop_base) + (reg_off)))
3124
3125/* Write byte to a register. */
3126#define AdvWriteByteRegister(iop_base, reg_off, byte) \
3127 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3128
3129/* Read word (2 bytes) from a register. */
3130#define AdvReadWordRegister(iop_base, reg_off) \
3131 (ADV_MEM_READW((iop_base) + (reg_off)))
3132
3133/* Write word (2 bytes) to a register. */
3134#define AdvWriteWordRegister(iop_base, reg_off, word) \
3135 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
3136
3137/* Write dword (4 bytes) to a register. */
3138#define AdvWriteDWordRegister(iop_base, reg_off, dword) \
3139 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
3140
3141/* Read byte from LRAM. */
3142#define AdvReadByteLram(iop_base, addr, byte) \
3143do { \
3144 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3145 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3146} while (0)
3147
3148/* Write byte to LRAM. */
3149#define AdvWriteByteLram(iop_base, addr, byte) \
3150 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3151 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3152
3153/* Read word (2 bytes) from LRAM. */
3154#define AdvReadWordLram(iop_base, addr, word) \
3155do { \
3156 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3157 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3158} while (0)
3159
3160/* Write word (2 bytes) to LRAM. */
3161#define AdvWriteWordLram(iop_base, addr, word) \
3162 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3163 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3164
3165/* Write little-endian double word (4 bytes) to LRAM */
3166/* Because of unspecified C language ordering don't use auto-increment. */
3167#define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
3168 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3169 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3170 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3171 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3172 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3173 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3174
3175/* Read word (2 bytes) from LRAM assuming that the address is already set. */
3176#define AdvReadWordAutoIncLram(iop_base) \
3177 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3178
3179/* Write word (2 bytes) to LRAM assuming that the address is already set. */
3180#define AdvWriteWordAutoIncLram(iop_base, word) \
3181 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3182
1da177e4
LT
3183/*
3184 * Define macro to check for Condor signature.
3185 *
3186 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3187 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3188 */
3189#define AdvFindSignature(iop_base) \
3190 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3191 ADV_CHIP_ID_BYTE) && \
3192 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3193 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
3194
3195/*
3196 * Define macro to Return the version number of the chip at 'iop_base'.
3197 *
3198 * The second parameter 'bus_type' is currently unused.
3199 */
3200#define AdvGetChipVersion(iop_base, bus_type) \
3201 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3202
3203/*
3204 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3205 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3206 *
3207 * If the request has not yet been sent to the device it will simply be
3208 * aborted from RISC memory. If the request is disconnected it will be
3209 * aborted on reselection by sending an Abort Message to the target ID.
3210 *
3211 * Return value:
3212 * ADV_TRUE(1) - Queue was successfully aborted.
3213 * ADV_FALSE(0) - Queue was not found on the active queue list.
3214 */
3215#define AdvAbortQueue(asc_dvc, scsiq) \
3216 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3217 (ADV_DCNT) (scsiq))
3218
3219/*
3220 * Send a Bus Device Reset Message to the specified target ID.
3221 *
3222 * All outstanding commands will be purged if sending the
3223 * Bus Device Reset Message is successful.
3224 *
3225 * Return Value:
3226 * ADV_TRUE(1) - All requests on the target are purged.
3227 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3228 * are not purged.
3229 */
3230#define AdvResetDevice(asc_dvc, target_id) \
3231 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3232 (ADV_DCNT) (target_id))
3233
3234/*
3235 * SCSI Wide Type definition.
3236 */
3237#define ADV_SCSI_BIT_ID_TYPE ushort
3238
3239/*
3240 * AdvInitScsiTarget() 'cntl_flag' options.
3241 */
3242#define ADV_SCAN_LUN 0x01
3243#define ADV_CAPINFO_NOLUN 0x02
3244
3245/*
3246 * Convert target id to target id bit mask.
3247 */
3248#define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
3249
3250/*
3251 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3252 */
3253
27c868c2 3254#define QD_NO_STATUS 0x00 /* Request not completed yet. */
1da177e4
LT
3255#define QD_NO_ERROR 0x01
3256#define QD_ABORTED_BY_HOST 0x02
3257#define QD_WITH_ERROR 0x04
3258
3259#define QHSTA_NO_ERROR 0x00
3260#define QHSTA_M_SEL_TIMEOUT 0x11
3261#define QHSTA_M_DATA_OVER_RUN 0x12
3262#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3263#define QHSTA_M_QUEUE_ABORTED 0x15
27c868c2
MW
3264#define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
3265#define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
3266#define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
3267#define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
3268#define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
3269#define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
3270#define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
1da177e4 3271/* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
27c868c2
MW
3272#define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
3273#define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
3274#define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
3275#define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
3276#define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
3277#define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
3278#define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
3279#define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
1da177e4
LT
3280#define QHSTA_M_WTM_TIMEOUT 0x41
3281#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
3282#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
3283#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
27c868c2
MW
3284#define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
3285#define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
3286#define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
1da177e4
LT
3287
3288/*
3289 * Default EEPROM Configuration structure defined in a_init.c.
3290 */
3291static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
3292static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
3293static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
3294
3295/*
3296 * DvcGetPhyAddr() flag arguments
3297 */
27c868c2
MW
3298#define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
3299#define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
3300#define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
3301#define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
3302#define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
3303#define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
1da177e4
LT
3304
3305/* Return the address that is aligned at the next doubleword >= to 'addr'. */
3306#define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
3307#define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
3308#define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
3309
3310/*
3311 * Total contiguous memory needed for driver SG blocks.
3312 *
3313 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3314 * number of scatter-gather elements the driver supports in a
3315 * single request.
3316 */
3317
3318#define ADV_SG_LIST_MAX_BYTE_SIZE \
3319 (sizeof(ADV_SG_BLOCK) * \
3320 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3321
3322/*
3323 * Inquiry data structure and bitfield macros
3324 *
3325 * Using bitfields to access the subchar data isn't portable across
3326 * endianness, so instead mask and shift. Only quantities of more
3327 * than 1 bit are shifted, since the others are just tested for true
3328 * or false.
3329 */
3330
3331#define ADV_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f)
3332#define ADV_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5)
3333#define ADV_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f)
3334#define ADV_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80)
3335#define ADV_INQ_ANSI_VER(inq) ((inq)->ver & 0x07)
3336#define ADV_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3)
3337#define ADV_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6)
3338#define ADV_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f)
3339#define ADV_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40)
3340#define ADV_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80)
3341#define ADV_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01)
3342#define ADV_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02)
3343#define ADV_INQ_LINK_CMD(inq) ((inq)->flags & 0x08)
3344#define ADV_INQ_SYNC(inq) ((inq)->flags & 0x10)
3345#define ADV_INQ_WIDE16(inq) ((inq)->flags & 0x20)
3346#define ADV_INQ_WIDE32(inq) ((inq)->flags & 0x40)
3347#define ADV_INQ_REL_ADDR(inq) ((inq)->flags & 0x80)
3348#define ADV_INQ_INFO_UNIT(inq) ((inq)->info & 0x01)
3349#define ADV_INQ_QUICK_ARB(inq) ((inq)->info & 0x02)
3350#define ADV_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2)
3351
3352typedef struct {
27c868c2
MW
3353 uchar periph; /* peripheral device type [0:4] */
3354 /* peripheral qualifier [5:7] */
3355 uchar devtype; /* device type modifier (for SCSI I) [0:6] */
3356 /* RMB - removable medium bit [7] */
3357 uchar ver; /* ANSI approved version [0:2] */
3358 /* ECMA version [3:5] */
3359 /* ISO version [6:7] */
3360 uchar byte3; /* response data format [0:3] */
3361 /* 0 SCSI 1 */
3362 /* 1 CCS */
3363 /* 2 SCSI-2 */
3364 /* 3-F reserved */
3365 /* reserved [4:5] */
3366 /* terminate I/O process bit (see 5.6.22) [6] */
3367 /* asynch. event notification (processor) [7] */
3368 uchar add_len; /* additional length */
3369 uchar res1; /* reserved */
3370 uchar res2; /* reserved */
3371 uchar flags; /* soft reset implemented [0] */
3372 /* command queuing [1] */
3373 /* reserved [2] */
3374 /* linked command for this logical unit [3] */
3375 /* synchronous data transfer [4] */
3376 /* wide bus 16 bit data transfer [5] */
3377 /* wide bus 32 bit data transfer [6] */
3378 /* relative addressing mode [7] */
3379 uchar vendor_id[8]; /* vendor identification */
3380 uchar product_id[16]; /* product identification */
3381 uchar product_rev_level[4]; /* product revision level */
3382 uchar vendor_specific[20]; /* vendor specific */
3383 uchar info; /* information unit supported [0] */
3384 /* quick arbitrate supported [1] */
3385 /* clocking field [2:3] */
3386 /* reserved [4:7] */
3387 uchar res3; /* reserved */
3388} ADV_SCSI_INQUIRY; /* 58 bytes */
1da177e4
LT
3389
3390/*
3391 * --- Driver Constants and Macros
3392 */
3393
1da177e4
LT
3394/* Reference Scsi_Host hostdata */
3395#define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3396
3397/* asc_board_t flags */
3398#define ASC_HOST_IN_RESET 0x01
27c868c2 3399#define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
1da177e4
LT
3400#define ASC_SELECT_QUEUE_DEPTHS 0x08
3401
3402#define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3403#define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD)
3404
27c868c2 3405#define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
1da177e4 3406
27c868c2 3407#define ASC_INFO_SIZE 128 /* advansys_info() line size */
1da177e4
LT
3408
3409#ifdef CONFIG_PROC_FS
3410/* /proc/scsi/advansys/[0...] related definitions */
3411#define ASC_PRTBUF_SIZE 2048
3412#define ASC_PRTLINE_SIZE 160
3413
3414#define ASC_PRT_NEXT() \
3415 if (cp) { \
3416 totlen += len; \
3417 leftlen -= len; \
3418 if (leftlen == 0) { \
3419 return totlen; \
3420 } \
3421 cp += len; \
3422 }
3423#endif /* CONFIG_PROC_FS */
3424
3425/* Asc Library return codes */
3426#define ASC_TRUE 1
3427#define ASC_FALSE 0
3428#define ASC_NOERROR 1
3429#define ASC_BUSY 0
3430#define ASC_ERROR (-1)
3431
3432/* struct scsi_cmnd function return codes */
3433#define STATUS_BYTE(byte) (byte)
3434#define MSG_BYTE(byte) ((byte) << 8)
3435#define HOST_BYTE(byte) ((byte) << 16)
3436#define DRIVER_BYTE(byte) ((byte) << 24)
3437
3438/*
3439 * The following definitions and macros are OS independent interfaces to
3440 * the queue functions:
3441 * REQ - SCSI request structure
3442 * REQP - pointer to SCSI request structure
3443 * REQPTID(reqp) - reqp's target id
3444 * REQPNEXT(reqp) - reqp's next pointer
3445 * REQPNEXTP(reqp) - pointer to reqp's next pointer
3446 * REQPTIME(reqp) - reqp's time stamp value
3447 * REQTIMESTAMP() - system time stamp value
3448 */
27c868c2 3449typedef struct scsi_cmnd REQ, *REQP;
1da177e4
LT
3450#define REQPNEXT(reqp) ((REQP) ((reqp)->host_scribble))
3451#define REQPNEXTP(reqp) ((REQP *) &((reqp)->host_scribble))
3452#define REQPTID(reqp) ((reqp)->device->id)
3453#define REQPTIME(reqp) ((reqp)->SCp.this_residual)
3454#define REQTIMESTAMP() (jiffies)
3455
3456#define REQTIMESTAT(function, ascq, reqp, tid) \
3457{ \
3458 /*
3459 * If the request time stamp is less than the system time stamp, then \
3460 * maybe the system time stamp wrapped. Set the request time to zero.\
3461 */ \
3462 if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3463 REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3464 } else { \
3465 /* Indicate an error occurred with the assertion. */ \
3466 ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3467 REQPTIME(reqp) = 0; \
3468 } \
3469 /* Handle first minimum time case without external initialization. */ \
3470 if (((ascq)->q_tot_cnt[tid] == 1) || \
3471 (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3472 (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3473 ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3474 (function), (tid), (ascq)->q_min_tim[tid]); \
3475 } \
3476 if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3477 (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3478 ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3479 (function), tid, (ascq)->q_max_tim[tid]); \
3480 } \
3481 (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3482 /* Reset the time stamp field. */ \
3483 REQPTIME(reqp) = 0; \
3484}
3485
3486/* asc_enqueue() flags */
3487#define ASC_FRONT 1
3488#define ASC_BACK 2
3489
3490/* asc_dequeue_list() argument */
3491#define ASC_TID_ALL (-1)
3492
3493/* Return non-zero, if the queue is empty. */
3494#define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0)
3495
1da177e4 3496#ifndef ADVANSYS_STATS
27c868c2
MW
3497#define ASC_STATS(shost, counter)
3498#define ASC_STATS_ADD(shost, counter, count)
1da177e4 3499#else /* ADVANSYS_STATS */
27c868c2
MW
3500#define ASC_STATS(shost, counter) \
3501 (ASC_BOARDP(shost)->asc_stats.counter++)
1da177e4 3502
27c868c2
MW
3503#define ASC_STATS_ADD(shost, counter, count) \
3504 (ASC_BOARDP(shost)->asc_stats.counter += (count))
1da177e4
LT
3505#endif /* ADVANSYS_STATS */
3506
3507#define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3508
3509/* If the result wraps when calculating tenths, return 0. */
3510#define ASC_TENTHS(num, den) \
3511 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3512 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3513
3514/*
3515 * Display a message to the console.
3516 */
3517#define ASC_PRINT(s) \
3518 { \
3519 printk("advansys: "); \
3520 printk(s); \
3521 }
3522
3523#define ASC_PRINT1(s, a1) \
3524 { \
3525 printk("advansys: "); \
3526 printk((s), (a1)); \
3527 }
3528
3529#define ASC_PRINT2(s, a1, a2) \
3530 { \
3531 printk("advansys: "); \
3532 printk((s), (a1), (a2)); \
3533 }
3534
3535#define ASC_PRINT3(s, a1, a2, a3) \
3536 { \
3537 printk("advansys: "); \
3538 printk((s), (a1), (a2), (a3)); \
3539 }
3540
3541#define ASC_PRINT4(s, a1, a2, a3, a4) \
3542 { \
3543 printk("advansys: "); \
3544 printk((s), (a1), (a2), (a3), (a4)); \
3545 }
3546
1da177e4
LT
3547#ifndef ADVANSYS_DEBUG
3548
3549#define ASC_DBG(lvl, s)
3550#define ASC_DBG1(lvl, s, a1)
3551#define ASC_DBG2(lvl, s, a1, a2)
3552#define ASC_DBG3(lvl, s, a1, a2, a3)
3553#define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3554#define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3555#define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3556#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3557#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3558#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3559#define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3560#define ASC_DBG_PRT_HEX(lvl, name, start, length)
3561#define ASC_DBG_PRT_CDB(lvl, cdb, len)
3562#define ASC_DBG_PRT_SENSE(lvl, sense, len)
3563#define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3564
3565#else /* ADVANSYS_DEBUG */
3566
3567/*
3568 * Debugging Message Levels:
3569 * 0: Errors Only
3570 * 1: High-Level Tracing
3571 * 2-N: Verbose Tracing
3572 */
3573
3574#define ASC_DBG(lvl, s) \
3575 { \
3576 if (asc_dbglvl >= (lvl)) { \
3577 printk(s); \
3578 } \
3579 }
3580
3581#define ASC_DBG1(lvl, s, a1) \
3582 { \
3583 if (asc_dbglvl >= (lvl)) { \
3584 printk((s), (a1)); \
3585 } \
3586 }
3587
3588#define ASC_DBG2(lvl, s, a1, a2) \
3589 { \
3590 if (asc_dbglvl >= (lvl)) { \
3591 printk((s), (a1), (a2)); \
3592 } \
3593 }
3594
3595#define ASC_DBG3(lvl, s, a1, a2, a3) \
3596 { \
3597 if (asc_dbglvl >= (lvl)) { \
3598 printk((s), (a1), (a2), (a3)); \
3599 } \
3600 }
3601
3602#define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3603 { \
3604 if (asc_dbglvl >= (lvl)) { \
3605 printk((s), (a1), (a2), (a3), (a4)); \
3606 } \
3607 }
3608
3609#define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3610 { \
3611 if (asc_dbglvl >= (lvl)) { \
3612 asc_prt_scsi_host(s); \
3613 } \
3614 }
3615
3616#define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3617 { \
3618 if (asc_dbglvl >= (lvl)) { \
3619 asc_prt_scsi_cmnd(s); \
3620 } \
3621 }
3622
3623#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3624 { \
3625 if (asc_dbglvl >= (lvl)) { \
3626 asc_prt_asc_scsi_q(scsiqp); \
3627 } \
3628 }
3629
3630#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3631 { \
3632 if (asc_dbglvl >= (lvl)) { \
3633 asc_prt_asc_qdone_info(qdone); \
3634 } \
3635 }
3636
3637#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3638 { \
3639 if (asc_dbglvl >= (lvl)) { \
3640 asc_prt_adv_scsi_req_q(scsiqp); \
3641 } \
3642 }
3643
3644#define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3645 { \
3646 if (asc_dbglvl >= (lvl)) { \
3647 asc_prt_hex((name), (start), (length)); \
3648 } \
3649 }
3650
3651#define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3652 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3653
3654#define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3655 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3656
3657#define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3658 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3659#endif /* ADVANSYS_DEBUG */
3660
3661#ifndef ADVANSYS_ASSERT
3662#define ASC_ASSERT(a)
3663#else /* ADVANSYS_ASSERT */
3664
3665#define ASC_ASSERT(a) \
3666 { \
3667 if (!(a)) { \
3668 printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3669 __FILE__, __LINE__); \
3670 } \
3671 }
3672
3673#endif /* ADVANSYS_ASSERT */
3674
1da177e4
LT
3675/*
3676 * --- Driver Structures
3677 */
3678
3679#ifdef ADVANSYS_STATS
3680
3681/* Per board statistics structure */
3682struct asc_stats {
27c868c2
MW
3683 /* Driver Entrypoint Statistics */
3684 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
3685 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
3686 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
3687 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
3688 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
3689 ADV_DCNT done; /* # calls to request's scsi_done function */
3690 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
3691 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
3692 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
3693 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3694 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
3695 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
3696 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
3697 ADV_DCNT exe_unknown; /* # unknown returns. */
3698 /* Data Transfer Statistics */
3699 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
3700 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
3701 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
3702 ADV_DCNT sg_elem; /* # scatter-gather elements */
3703 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
1da177e4
LT
3704};
3705#endif /* ADVANSYS_STATS */
3706
3707/*
3708 * Request queuing structure
3709 */
3710typedef struct asc_queue {
27c868c2
MW
3711 ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */
3712 REQP q_first[ADV_MAX_TID + 1]; /* first queued request */
3713 REQP q_last[ADV_MAX_TID + 1]; /* last queued request */
1da177e4 3714#ifdef ADVANSYS_STATS
27c868c2
MW
3715 short q_cur_cnt[ADV_MAX_TID + 1]; /* current queue count */
3716 short q_max_cnt[ADV_MAX_TID + 1]; /* maximum queue count */
3717 ADV_DCNT q_tot_cnt[ADV_MAX_TID + 1]; /* total enqueue count */
3718 ADV_DCNT q_tot_tim[ADV_MAX_TID + 1]; /* total time queued */
3719 ushort q_max_tim[ADV_MAX_TID + 1]; /* maximum time queued */
3720 ushort q_min_tim[ADV_MAX_TID + 1]; /* minimum time queued */
3721#endif /* ADVANSYS_STATS */
1da177e4
LT
3722} asc_queue_t;
3723
3724/*
3725 * Adv Library Request Structures
3726 *
3727 * The following two structures are used to process Wide Board requests.
3728 *
3729 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
3730 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
3731 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
3732 * Mid-Level SCSI request structure.
3733 *
3734 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
3735 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
3736 * up to 255 scatter-gather elements may be used per request or
3737 * ADV_SCSI_REQ_Q.
3738 *
3739 * Both structures must be 32 byte aligned.
3740 */
3741typedef struct adv_sgblk {
27c868c2
MW
3742 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
3743 uchar align[32]; /* Sgblock structure padding. */
3744 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
1da177e4
LT
3745} adv_sgblk_t;
3746
3747typedef struct adv_req {
27c868c2
MW
3748 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
3749 uchar align[32]; /* Request structure padding. */
3750 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
3751 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
3752 struct adv_req *next_reqp; /* Next Request Structure. */
1da177e4
LT
3753} adv_req_t;
3754
3755/*
3756 * Structure allocated for each board.
3757 *
8dfb5379 3758 * This structure is allocated by scsi_host_alloc() at the end
1da177e4
LT
3759 * of the 'Scsi_Host' structure starting at the 'hostdata'
3760 * field. It is guaranteed to be allocated from DMA-able memory.
3761 */
3762typedef struct asc_board {
27c868c2
MW
3763 int id; /* Board Id */
3764 uint flags; /* Board flags */
3765 union {
3766 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
3767 ADV_DVC_VAR adv_dvc_var; /* Wide board */
3768 } dvc_var;
3769 union {
3770 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
3771 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
3772 } dvc_cfg;
3773 ushort asc_n_io_port; /* Number I/O ports. */
3774 asc_queue_t active; /* Active command queue */
3775 asc_queue_t waiting; /* Waiting command queue */
3776 asc_queue_t done; /* Done command queue */
3777 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
3778 struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */
3779 ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
3780 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
3781 ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
3782 union {
3783 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
3784 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
3785 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
3786 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
3787 } eep_config;
3788 ulong last_reset; /* Saved last reset time */
3789 spinlock_t lock; /* Board spinlock */
27c868c2
MW
3790 /* /proc/scsi/advansys/[0...] */
3791 char *prtbuf; /* /proc print buffer */
1da177e4 3792#ifdef ADVANSYS_STATS
27c868c2
MW
3793 struct asc_stats asc_stats; /* Board statistics */
3794#endif /* ADVANSYS_STATS */
3795 /*
3796 * The following fields are used only for Narrow Boards.
3797 */
3798 /* The following three structures must be in DMA-able memory. */
3799 ASC_SCSI_REQ_Q scsireqq;
3800 ASC_CAP_INFO cap_info;
3801 ASC_SCSI_INQUIRY inquiry;
3802 uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */
3803 /*
3804 * The following fields are used only for Wide Boards.
3805 */
3806 void __iomem *ioremap_addr; /* I/O Memory remap address. */
3807 ushort ioport; /* I/O Port address. */
b2c16f58 3808 ADV_CARR_T *carrp; /* ADV_CARR_T memory block. */
27c868c2
MW
3809 adv_req_t *orig_reqp; /* adv_req_t memory block. */
3810 adv_req_t *adv_reqp; /* Request structures. */
3811 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
3812 ushort bios_signature; /* BIOS Signature. */
3813 ushort bios_version; /* BIOS Version. */
3814 ushort bios_codeseg; /* BIOS Code Segment. */
3815 ushort bios_codelen; /* BIOS Code Segment Length. */
1da177e4
LT
3816} asc_board_t;
3817
1da177e4 3818/* Number of boards detected in system. */
78e77d8b
MW
3819static int asc_board_count;
3820
1da177e4 3821/* Overrun buffer used by all narrow boards. */
27c868c2 3822static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
1da177e4
LT
3823
3824/*
3825 * Global structures required to issue a command.
3826 */
27c868c2
MW
3827static ASC_SCSI_Q asc_scsi_q = { {0} };
3828static ASC_SG_HEAD asc_sg_head = { 0 };
1da177e4 3829
1da177e4 3830#ifdef ADVANSYS_DEBUG
27c868c2 3831static int asc_dbglvl = 3;
1da177e4
LT
3832#endif /* ADVANSYS_DEBUG */
3833
1da177e4
LT
3834/*
3835 * --- Driver Function Prototypes
3836 *
3837 * advansys.h contains function prototypes for functions global to Linux.
3838 */
3839
27c868c2
MW
3840static int advansys_slave_configure(struct scsi_device *);
3841static void asc_scsi_done_list(struct scsi_cmnd *);
3842static int asc_execute_scsi_cmnd(struct scsi_cmnd *);
3843static int asc_build_req(asc_board_t *, struct scsi_cmnd *);
3844static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
3845static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
3846static void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
3847static void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3848static void adv_async_callback(ADV_DVC_VAR *, uchar);
3849static void asc_enqueue(asc_queue_t *, REQP, int);
3850static REQP asc_dequeue(asc_queue_t *, int);
3851static REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
3852static int asc_rmqueue(asc_queue_t *, REQP);
3853static void asc_execute_queue(asc_queue_t *);
1da177e4 3854#ifdef CONFIG_PROC_FS
27c868c2
MW
3855static int asc_proc_copy(off_t, off_t, char *, int, char *, int);
3856static int asc_prt_board_devices(struct Scsi_Host *, char *, int);
3857static int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
3858static int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
3859static int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
3860static int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
3861static int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
3862static int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
3863static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
3864static int asc_prt_line(char *, int, char *fmt, ...);
1da177e4
LT
3865#endif /* CONFIG_PROC_FS */
3866
3867/* Declaration for Asc Library internal functions referenced by driver. */
27c868c2
MW
3868static int AscFindSignature(PortAddr);
3869static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1da177e4
LT
3870
3871/* Statistics function prototypes. */
3872#ifdef ADVANSYS_STATS
3873#ifdef CONFIG_PROC_FS
27c868c2
MW
3874static int asc_prt_board_stats(struct Scsi_Host *, char *, int);
3875static int asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
1da177e4
LT
3876#endif /* CONFIG_PROC_FS */
3877#endif /* ADVANSYS_STATS */
3878
3879/* Debug function prototypes. */
3880#ifdef ADVANSYS_DEBUG
27c868c2
MW
3881static void asc_prt_scsi_host(struct Scsi_Host *);
3882static void asc_prt_scsi_cmnd(struct scsi_cmnd *);
3883static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
3884static void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
3885static void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
3886static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
3887static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
3888static void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
3889static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
3890static void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
3891static void asc_prt_hex(char *f, uchar *, int);
1da177e4
LT
3892#endif /* ADVANSYS_DEBUG */
3893
1da177e4
LT
3894#ifdef CONFIG_PROC_FS
3895/*
c304ec94 3896 * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
1da177e4
LT
3897 *
3898 * *buffer: I/O buffer
3899 * **start: if inout == FALSE pointer into buffer where user read should start
3900 * offset: current offset into a /proc/scsi/advansys/[0...] file
3901 * length: length of buffer
3902 * hostno: Scsi_Host host_no
3903 * inout: TRUE - user is writing; FALSE - user is reading
3904 *
3905 * Return the number of bytes read from or written to a
3906 * /proc/scsi/advansys/[0...] file.
3907 *
3908 * Note: This function uses the per board buffer 'prtbuf' which is
3909 * allocated when the board is initialized in advansys_detect(). The
3910 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
3911 * used to write to the buffer. The way asc_proc_copy() is written
3912 * if 'prtbuf' is too small it will not be overwritten. Instead the
3913 * user just won't get all the available statistics.
3914 */
70c8d897 3915static int
1da177e4 3916advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
27c868c2 3917 off_t offset, int length, int inout)
1da177e4 3918{
27c868c2 3919 asc_board_t *boardp;
27c868c2
MW
3920 char *cp;
3921 int cplen;
3922 int cnt;
3923 int totcnt;
3924 int leftlen;
3925 char *curbuf;
3926 off_t advoffset;
1da177e4 3927#ifdef ADVANSYS_STATS
27c868c2 3928 int tgt_id;
1da177e4
LT
3929#endif /* ADVANSYS_STATS */
3930
27c868c2 3931 ASC_DBG(1, "advansys_proc_info: begin\n");
1da177e4 3932
27c868c2
MW
3933 /*
3934 * User write not supported.
3935 */
3936 if (inout == TRUE) {
3937 return (-ENOSYS);
3938 }
1da177e4 3939
27c868c2
MW
3940 /*
3941 * User read of /proc/scsi/advansys/[0...] file.
3942 */
1da177e4 3943
2a437959 3944 boardp = ASC_BOARDP(shost);
27c868c2
MW
3945
3946 /* Copy read data starting at the beginning of the buffer. */
3947 *start = buffer;
3948 curbuf = buffer;
3949 advoffset = 0;
3950 totcnt = 0;
3951 leftlen = length;
3952
3953 /*
3954 * Get board configuration information.
3955 *
3956 * advansys_info() returns the board string from its own static buffer.
3957 */
2a437959 3958 cp = (char *)advansys_info(shost);
27c868c2
MW
3959 strcat(cp, "\n");
3960 cplen = strlen(cp);
3961 /* Copy board information. */
3962 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3963 totcnt += cnt;
3964 leftlen -= cnt;
3965 if (leftlen == 0) {
3966 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3967 return totcnt;
3968 }
3969 advoffset += cplen;
3970 curbuf += cnt;
3971
3972 /*
3973 * Display Wide Board BIOS Information.
3974 */
3975 if (ASC_WIDE_BOARD(boardp)) {
3976 cp = boardp->prtbuf;
2a437959 3977 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
3978 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3979 cnt =
3980 asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
3981 cplen);
3982 totcnt += cnt;
3983 leftlen -= cnt;
3984 if (leftlen == 0) {
3985 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3986 return totcnt;
3987 }
3988 advoffset += cplen;
3989 curbuf += cnt;
3990 }
1da177e4 3991
27c868c2
MW
3992 /*
3993 * Display driver information for each device attached to the board.
3994 */
3995 cp = boardp->prtbuf;
2a437959 3996 cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
3997 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3998 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3999 totcnt += cnt;
4000 leftlen -= cnt;
4001 if (leftlen == 0) {
4002 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4003 return totcnt;
4004 }
4005 advoffset += cplen;
4006 curbuf += cnt;
4007
4008 /*
4009 * Display EEPROM configuration for the board.
4010 */
4011 cp = boardp->prtbuf;
4012 if (ASC_NARROW_BOARD(boardp)) {
2a437959 4013 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 4014 } else {
2a437959 4015 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
4016 }
4017 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4018 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4019 totcnt += cnt;
4020 leftlen -= cnt;
4021 if (leftlen == 0) {
4022 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4023 return totcnt;
4024 }
4025 advoffset += cplen;
4026 curbuf += cnt;
4027
4028 /*
4029 * Display driver configuration and information for the board.
4030 */
4031 cp = boardp->prtbuf;
2a437959 4032 cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
4033 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4034 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4035 totcnt += cnt;
4036 leftlen -= cnt;
4037 if (leftlen == 0) {
4038 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4039 return totcnt;
4040 }
4041 advoffset += cplen;
4042 curbuf += cnt;
1da177e4
LT
4043
4044#ifdef ADVANSYS_STATS
27c868c2
MW
4045 /*
4046 * Display driver statistics for the board.
4047 */
4048 cp = boardp->prtbuf;
2a437959 4049 cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
4050 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4051 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4052 totcnt += cnt;
4053 leftlen -= cnt;
4054 if (leftlen == 0) {
4055 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4056 return totcnt;
4057 }
4058 advoffset += cplen;
4059 curbuf += cnt;
4060
4061 /*
4062 * Display driver statistics for each target.
4063 */
4064 for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
4065 cp = boardp->prtbuf;
2a437959
MW
4066 cplen = asc_prt_target_stats(shost, tgt_id, cp,
4067 ASC_PRTBUF_SIZE);
27c868c2
MW
4068 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4069 cnt =
4070 asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
4071 cplen);
4072 totcnt += cnt;
4073 leftlen -= cnt;
4074 if (leftlen == 0) {
4075 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4076 return totcnt;
4077 }
4078 advoffset += cplen;
4079 curbuf += cnt;
4080 }
1da177e4
LT
4081#endif /* ADVANSYS_STATS */
4082
27c868c2
MW
4083 /*
4084 * Display Asc Library dynamic configuration information
4085 * for the board.
4086 */
4087 cp = boardp->prtbuf;
4088 if (ASC_NARROW_BOARD(boardp)) {
2a437959 4089 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 4090 } else {
2a437959 4091 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
4092 }
4093 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4094 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4095 totcnt += cnt;
4096 leftlen -= cnt;
4097 if (leftlen == 0) {
4098 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4099 return totcnt;
4100 }
4101 advoffset += cplen;
4102 curbuf += cnt;
1da177e4 4103
27c868c2 4104 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
1da177e4 4105
27c868c2 4106 return totcnt;
1da177e4 4107}
1da177e4 4108#endif /* CONFIG_PROC_FS */
1da177e4
LT
4109
4110/*
4111 * advansys_info()
4112 *
4113 * Return suitable for printing on the console with the argument
4114 * adapter's configuration information.
4115 *
4116 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
4117 * otherwise the static 'info' array will be overrun.
4118 */
27c868c2 4119static const char *advansys_info(struct Scsi_Host *shost)
1da177e4 4120{
27c868c2
MW
4121 static char info[ASC_INFO_SIZE];
4122 asc_board_t *boardp;
4123 ASC_DVC_VAR *asc_dvc_varp;
4124 ADV_DVC_VAR *adv_dvc_varp;
4125 char *busname;
4126 int iolen;
4127 char *widename = NULL;
4128
4129 boardp = ASC_BOARDP(shost);
4130 if (ASC_NARROW_BOARD(boardp)) {
4131 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4132 ASC_DBG(1, "advansys_info: begin\n");
4133 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
4134 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
4135 ASC_IS_ISAPNP) {
4136 busname = "ISA PnP";
4137 } else {
4138 busname = "ISA";
4139 }
4140 /* Don't reference 'shost->n_io_port'; It may be truncated. */
4141 sprintf(info,
4142 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
4143 ASC_VERSION, busname,
4144 (ulong)shost->io_port,
4145 (ulong)shost->io_port + boardp->asc_n_io_port -
4146 1, shost->irq, shost->dma_channel);
4147 } else {
4148 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
4149 busname = "VL";
4150 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
4151 busname = "EISA";
4152 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
4153 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
4154 == ASC_IS_PCI_ULTRA) {
4155 busname = "PCI Ultra";
4156 } else {
4157 busname = "PCI";
4158 }
4159 } else {
4160 busname = "?";
4161 ASC_PRINT2
4162 ("advansys_info: board %d: unknown bus type %d\n",
4163 boardp->id, asc_dvc_varp->bus_type);
4164 }
4165 /* Don't reference 'shost->n_io_port'; It may be truncated. */
4166 sprintf(info,
4167 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
4168 ASC_VERSION, busname,
4169 (ulong)shost->io_port,
4170 (ulong)shost->io_port + boardp->asc_n_io_port -
4171 1, shost->irq);
4172 }
4173 } else {
4174 /*
4175 * Wide Adapter Information
4176 *
4177 * Memory-mapped I/O is used instead of I/O space to access
4178 * the adapter, but display the I/O Port range. The Memory
4179 * I/O address is displayed through the driver /proc file.
4180 */
4181 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4182 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4183 iolen = ADV_3550_IOLEN;
4184 widename = "Ultra-Wide";
4185 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4186 iolen = ADV_38C0800_IOLEN;
4187 widename = "Ultra2-Wide";
4188 } else {
4189 iolen = ADV_38C1600_IOLEN;
4190 widename = "Ultra3-Wide";
4191 }
4192 sprintf(info,
4193 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
4194 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
4195 (ulong)adv_dvc_varp->iop_base + iolen - 1, shost->irq);
4196 }
4197 ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
4198 ASC_DBG(1, "advansys_info: end\n");
4199 return info;
1da177e4
LT
4200}
4201
4202/*
4203 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
4204 *
4205 * This function always returns 0. Command return status is saved
4206 * in the 'scp' result field.
4207 */
70c8d897 4208static int
27c868c2 4209advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *))
1da177e4 4210{
27c868c2
MW
4211 struct Scsi_Host *shost;
4212 asc_board_t *boardp;
4213 ulong flags;
4214 struct scsi_cmnd *done_scp;
1da177e4 4215
27c868c2
MW
4216 shost = scp->device->host;
4217 boardp = ASC_BOARDP(shost);
4218 ASC_STATS(shost, queuecommand);
1da177e4 4219
27c868c2
MW
4220 /* host_lock taken by mid-level prior to call but need to protect */
4221 /* against own ISR */
4222 spin_lock_irqsave(&boardp->lock, flags);
1da177e4 4223
27c868c2
MW
4224 /*
4225 * Block new commands while handling a reset or abort request.
4226 */
4227 if (boardp->flags & ASC_HOST_IN_RESET) {
4228 ASC_DBG1(1,
4229 "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
4230 (ulong)scp);
4231 scp->result = HOST_BYTE(DID_RESET);
1da177e4 4232
27c868c2
MW
4233 /*
4234 * Add blocked requests to the board's 'done' queue. The queued
4235 * requests will be completed at the end of the abort or reset
4236 * handling.
4237 */
4238 asc_enqueue(&boardp->done, scp, ASC_BACK);
4239 spin_unlock_irqrestore(&boardp->lock, flags);
4240 return 0;
4241 }
1da177e4 4242
27c868c2
MW
4243 /*
4244 * Attempt to execute any waiting commands for the board.
4245 */
4246 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4247 ASC_DBG(1,
4248 "advansys_queuecommand: before asc_execute_queue() waiting\n");
4249 asc_execute_queue(&boardp->waiting);
4250 }
4251
4252 /*
4253 * Save the function pointer to Linux mid-level 'done' function
4254 * and attempt to execute the command.
4255 *
4256 * If ASC_NOERROR is returned the request has been added to the
4257 * board's 'active' queue and will be completed by the interrupt
4258 * handler.
4259 *
4260 * If ASC_BUSY is returned add the request to the board's per
4261 * target waiting list. This is the first time the request has
4262 * been tried. Add it to the back of the waiting list. It will be
4263 * retried later.
4264 *
4265 * If an error occurred, the request will have been placed on the
4266 * board's 'done' queue and must be completed before returning.
4267 */
4268 scp->scsi_done = done;
4269 switch (asc_execute_scsi_cmnd(scp)) {
4270 case ASC_NOERROR:
4271 break;
4272 case ASC_BUSY:
4273 asc_enqueue(&boardp->waiting, scp, ASC_BACK);
4274 break;
4275 case ASC_ERROR:
4276 default:
4277 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
4278 /* Interrupts could be enabled here. */
4279 asc_scsi_done_list(done_scp);
4280 break;
4281 }
4282 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 4283
27c868c2 4284 return 0;
1da177e4
LT
4285}
4286
4287/*
4288 * advansys_reset()
4289 *
4290 * Reset the bus associated with the command 'scp'.
4291 *
4292 * This function runs its own thread. Interrupts must be blocked but
4293 * sleeping is allowed and no locking other than for host structures is
4294 * required. Returns SUCCESS or FAILED.
4295 */
27c868c2 4296static int advansys_reset(struct scsi_cmnd *scp)
1da177e4 4297{
27c868c2
MW
4298 struct Scsi_Host *shost;
4299 asc_board_t *boardp;
4300 ASC_DVC_VAR *asc_dvc_varp;
4301 ADV_DVC_VAR *adv_dvc_varp;
4302 ulong flags;
4303 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4304 struct scsi_cmnd *tscp, *new_last_scp;
4305 int status;
4306 int ret = SUCCESS;
4307
4308 ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp);
1da177e4
LT
4309
4310#ifdef ADVANSYS_STATS
27c868c2
MW
4311 if (scp->device->host != NULL) {
4312 ASC_STATS(scp->device->host, reset);
4313 }
1da177e4
LT
4314#endif /* ADVANSYS_STATS */
4315
27c868c2
MW
4316 if ((shost = scp->device->host) == NULL) {
4317 scp->result = HOST_BYTE(DID_ERROR);
4318 return FAILED;
4319 }
1da177e4 4320
27c868c2 4321 boardp = ASC_BOARDP(shost);
1da177e4 4322
27c868c2
MW
4323 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
4324 boardp->id);
4325 /*
4326 * Check for re-entrancy.
4327 */
1da177e4 4328 spin_lock_irqsave(&boardp->lock, flags);
27c868c2
MW
4329 if (boardp->flags & ASC_HOST_IN_RESET) {
4330 spin_unlock_irqrestore(&boardp->lock, flags);
4331 return FAILED;
4332 }
4333 boardp->flags |= ASC_HOST_IN_RESET;
4334 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 4335
27c868c2
MW
4336 if (ASC_NARROW_BOARD(boardp)) {
4337 /*
4338 * Narrow Board
4339 */
4340 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
1da177e4 4341
27c868c2
MW
4342 /*
4343 * Reset the chip and SCSI bus.
4344 */
4345 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
4346 status = AscInitAsc1000Driver(asc_dvc_varp);
4347
4348 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
4349 if (asc_dvc_varp->err_code) {
4350 ASC_PRINT2
4351 ("advansys_reset: board %d: SCSI bus reset error: 0x%x\n",
4352 boardp->id, asc_dvc_varp->err_code);
4353 ret = FAILED;
4354 } else if (status) {
4355 ASC_PRINT2
4356 ("advansys_reset: board %d: SCSI bus reset warning: 0x%x\n",
4357 boardp->id, status);
4358 } else {
4359 ASC_PRINT1
4360 ("advansys_reset: board %d: SCSI bus reset successful.\n",
4361 boardp->id);
4362 }
4363
4364 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
4365 spin_lock_irqsave(&boardp->lock, flags);
1da177e4 4366
27c868c2
MW
4367 } else {
4368 /*
4369 * Wide Board
4370 *
4371 * If the suggest reset bus flags are set, then reset the bus.
4372 * Otherwise only reset the device.
4373 */
4374 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
1da177e4 4375
27c868c2
MW
4376 /*
4377 * Reset the target's SCSI bus.
4378 */
4379 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
4380 switch (AdvResetChipAndSB(adv_dvc_varp)) {
4381 case ASC_TRUE:
4382 ASC_PRINT1
4383 ("advansys_reset: board %d: SCSI bus reset successful.\n",
4384 boardp->id);
4385 break;
4386 case ASC_FALSE:
4387 default:
4388 ASC_PRINT1
4389 ("advansys_reset: board %d: SCSI bus reset error.\n",
4390 boardp->id);
4391 ret = FAILED;
4392 break;
4393 }
4394 spin_lock_irqsave(&boardp->lock, flags);
4395 (void)AdvISR(adv_dvc_varp);
4396 }
4397 /* Board lock is held. */
4398
4399 /*
4400 * Dequeue all board 'done' requests. A pointer to the last request
4401 * is returned in 'last_scp'.
4402 */
4403 done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
4404
4405 /*
4406 * Dequeue all board 'active' requests for all devices and set
4407 * the request status to DID_RESET. A pointer to the last request
4408 * is returned in 'last_scp'.
4409 */
4410 if (done_scp == NULL) {
4411 done_scp =
4412 asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL);
4413 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4414 tscp->result = HOST_BYTE(DID_RESET);
4415 }
4416 } else {
4417 /* Append to 'done_scp' at the end with 'last_scp'. */
4418 ASC_ASSERT(last_scp != NULL);
4419 last_scp->host_scribble =
4420 (unsigned char *)asc_dequeue_list(&boardp->active,
4421 &new_last_scp,
4422 ASC_TID_ALL);
4423 if (new_last_scp != NULL) {
4424 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4425 for (tscp = REQPNEXT(last_scp); tscp;
4426 tscp = REQPNEXT(tscp)) {
4427 tscp->result = HOST_BYTE(DID_RESET);
4428 }
4429 last_scp = new_last_scp;
4430 }
4431 }
1da177e4 4432
27c868c2
MW
4433 /*
4434 * Dequeue all 'waiting' requests and set the request status
4435 * to DID_RESET.
4436 */
4437 if (done_scp == NULL) {
4438 done_scp =
4439 asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL);
4440 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4441 tscp->result = HOST_BYTE(DID_RESET);
4442 }
4443 } else {
4444 /* Append to 'done_scp' at the end with 'last_scp'. */
4445 ASC_ASSERT(last_scp != NULL);
4446 last_scp->host_scribble =
4447 (unsigned char *)asc_dequeue_list(&boardp->waiting,
4448 &new_last_scp,
4449 ASC_TID_ALL);
4450 if (new_last_scp != NULL) {
4451 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4452 for (tscp = REQPNEXT(last_scp); tscp;
4453 tscp = REQPNEXT(tscp)) {
4454 tscp->result = HOST_BYTE(DID_RESET);
4455 }
4456 last_scp = new_last_scp;
4457 }
4458 }
1da177e4 4459
27c868c2
MW
4460 /* Save the time of the most recently completed reset. */
4461 boardp->last_reset = jiffies;
1da177e4 4462
27c868c2
MW
4463 /* Clear reset flag. */
4464 boardp->flags &= ~ASC_HOST_IN_RESET;
4465 spin_unlock_irqrestore(&boardp->lock, flags);
4466
4467 /*
4468 * Complete all the 'done_scp' requests.
4469 */
4470 if (done_scp != NULL) {
4471 asc_scsi_done_list(done_scp);
4472 }
1da177e4 4473
27c868c2 4474 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
1da177e4 4475
27c868c2 4476 return ret;
1da177e4
LT
4477}
4478
4479/*
4480 * advansys_biosparam()
4481 *
4482 * Translate disk drive geometry if the "BIOS greater than 1 GB"
4483 * support is enabled for a drive.
4484 *
4485 * ip (information pointer) is an int array with the following definition:
4486 * ip[0]: heads
4487 * ip[1]: sectors
4488 * ip[2]: cylinders
4489 */
70c8d897 4490static int
1da177e4 4491advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
27c868c2 4492 sector_t capacity, int ip[])
1da177e4 4493{
27c868c2
MW
4494 asc_board_t *boardp;
4495
4496 ASC_DBG(1, "advansys_biosparam: begin\n");
4497 ASC_STATS(sdev->host, biosparam);
4498 boardp = ASC_BOARDP(sdev->host);
4499 if (ASC_NARROW_BOARD(boardp)) {
4500 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
4501 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
4502 ip[0] = 255;
4503 ip[1] = 63;
4504 } else {
4505 ip[0] = 64;
4506 ip[1] = 32;
4507 }
4508 } else {
4509 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
4510 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
4511 ip[0] = 255;
4512 ip[1] = 63;
4513 } else {
4514 ip[0] = 64;
4515 ip[1] = 32;
4516 }
4517 }
4518 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
4519 ASC_DBG(1, "advansys_biosparam: end\n");
4520 return 0;
1da177e4
LT
4521}
4522
8dfb5379 4523static struct scsi_host_template advansys_template = {
27c868c2 4524 .proc_name = "advansys",
1da177e4 4525#ifdef CONFIG_PROC_FS
27c868c2 4526 .proc_info = advansys_proc_info,
1da177e4 4527#endif
27c868c2 4528 .name = "advansys",
27c868c2
MW
4529 .info = advansys_info,
4530 .queuecommand = advansys_queuecommand,
4531 .eh_bus_reset_handler = advansys_reset,
4532 .bios_param = advansys_biosparam,
4533 .slave_configure = advansys_slave_configure,
4534 /*
4535 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
8dfb5379
MW
4536 * must be set. The flag will be cleared in advansys_board_found
4537 * for non-ISA adapters.
27c868c2
MW
4538 */
4539 .unchecked_isa_dma = 1,
4540 /*
4541 * All adapters controlled by this driver are capable of large
4542 * scatter-gather lists. According to the mid-level SCSI documentation
4543 * this obviates any performance gain provided by setting
4544 * 'use_clustering'. But empirically while CPU utilization is increased
4545 * by enabling clustering, I/O throughput increases as well.
4546 */
4547 .use_clustering = ENABLE_CLUSTERING,
1da177e4 4548};
1da177e4 4549
1da177e4
LT
4550/*
4551 * --- Miscellaneous Driver Functions
4552 */
4553
4554/*
4555 * First-level interrupt handler.
4556 *
4557 * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
4558 * all boards are currently checked for interrupts on each interrupt, 'dev_id'
4559 * is not referenced. 'dev_id' could be used to identify an interrupt passed
4560 * to the AdvanSys driver which is for a device sharing an interrupt with
4561 * an AdvanSys adapter.
4562 */
27c868c2 4563static irqreturn_t advansys_interrupt(int irq, void *dev_id)
1da177e4 4564{
074c8fe4 4565 unsigned long flags;
27c868c2
MW
4566 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4567 struct scsi_cmnd *new_last_scp;
074c8fe4
MW
4568 struct Scsi_Host *shost = dev_id;
4569 asc_board_t *boardp = ASC_BOARDP(shost);
4570 irqreturn_t result = IRQ_NONE;
27c868c2 4571
074c8fe4
MW
4572 ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp);
4573 spin_lock_irqsave(&boardp->lock, flags);
4574 if (ASC_NARROW_BOARD(boardp)) {
4575 /*
4576 * Narrow Board
4577 */
4578 if (AscIsIntPending(shost->io_port)) {
4579 result = IRQ_HANDLED;
4580 ASC_STATS(shost, interrupt);
4581 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
4582 AscISR(&boardp->dvc_var.asc_dvc_var);
4583 }
4584 } else {
4585 /*
4586 * Wide Board
4587 */
4588 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
4589 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
4590 result = IRQ_HANDLED;
4591 ASC_STATS(shost, interrupt);
4592 }
4593 }
27c868c2
MW
4594
4595 /*
074c8fe4
MW
4596 * Start waiting requests and create a list of completed requests.
4597 *
4598 * If a reset request is being performed for the board, the reset
4599 * handler will complete pending requests after it has completed.
4600 */
4601 if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
4602 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%p, "
4603 "last_scp 0x%p\n", done_scp, last_scp);
4604
4605 /* Start any waiting commands for the board. */
4606 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4607 ASC_DBG(1, "advansys_interrupt: before "
4608 "asc_execute_queue()\n");
4609 asc_execute_queue(&boardp->waiting);
27c868c2 4610 }
1da177e4 4611
27c868c2 4612 /*
074c8fe4 4613 * Add to the list of requests that must be completed.
27c868c2 4614 *
074c8fe4
MW
4615 * 'done_scp' will always be NULL on the first iteration of
4616 * this loop. 'last_scp' is set at the same time as 'done_scp'.
27c868c2 4617 */
074c8fe4
MW
4618 if (done_scp == NULL) {
4619 done_scp = asc_dequeue_list(&boardp->done,
4620 &last_scp, ASC_TID_ALL);
4621 } else {
4622 ASC_ASSERT(last_scp != NULL);
4623 last_scp->host_scribble =
4624 (unsigned char *)asc_dequeue_list(&boardp->
4625 done,
4626 &new_last_scp,
4627 ASC_TID_ALL);
4628 if (new_last_scp != NULL) {
4629 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4630 last_scp = new_last_scp;
27c868c2
MW
4631 }
4632 }
27c868c2 4633 }
074c8fe4 4634 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 4635
27c868c2
MW
4636 /*
4637 * If interrupts were enabled on entry, then they
4638 * are now enabled here.
4639 *
4640 * Complete all requests on the done list.
4641 */
1da177e4 4642
27c868c2 4643 asc_scsi_done_list(done_scp);
1da177e4 4644
27c868c2 4645 ASC_DBG(1, "advansys_interrupt: end\n");
074c8fe4 4646 return result;
1da177e4
LT
4647}
4648
4649/*
4650 * Set the number of commands to queue per device for the
4651 * specified host adapter.
4652 */
27c868c2 4653static int advansys_slave_configure(struct scsi_device *device)
1da177e4 4654{
27c868c2 4655 asc_board_t *boardp;
1da177e4 4656
27c868c2
MW
4657 boardp = ASC_BOARDP(device->host);
4658 boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
4659 /*
4660 * Save a pointer to the device and set its initial/maximum
4661 * queue depth. Only save the pointer for a lun0 dev though.
4662 */
4663 if (device->lun == 0)
4664 boardp->device[device->id] = device;
4665 if (device->tagged_supported) {
4666 if (ASC_NARROW_BOARD(boardp)) {
4667 scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
4668 boardp->dvc_var.asc_dvc_var.
4669 max_dvc_qng[device->id]);
4670 } else {
4671 scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
4672 boardp->dvc_var.adv_dvc_var.
4673 max_dvc_qng);
4674 }
4675 } else {
4676 scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun);
4677 }
4678 ASC_DBG4(1,
4679 "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n",
4680 (ulong)device, (ulong)boardp, device->id, device->queue_depth);
4681 return 0;
1da177e4
LT
4682}
4683
4684/*
4685 * Complete all requests on the singly linked list pointed
4686 * to by 'scp'.
4687 *
4688 * Interrupts can be enabled on entry.
4689 */
27c868c2 4690static void asc_scsi_done_list(struct scsi_cmnd *scp)
1da177e4 4691{
27c868c2 4692 struct scsi_cmnd *tscp;
1da177e4 4693
27c868c2
MW
4694 ASC_DBG(2, "asc_scsi_done_list: begin\n");
4695 while (scp != NULL) {
4696 asc_board_t *boardp;
4697 struct device *dev;
1da177e4 4698
27c868c2
MW
4699 ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp);
4700 tscp = REQPNEXT(scp);
4701 scp->host_scribble = NULL;
1da177e4 4702
27c868c2 4703 boardp = ASC_BOARDP(scp->device->host);
1da177e4 4704
27c868c2
MW
4705 if (ASC_NARROW_BOARD(boardp))
4706 dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
4707 else
4708 dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
1da177e4 4709
27c868c2
MW
4710 if (scp->use_sg)
4711 dma_unmap_sg(dev,
4712 (struct scatterlist *)scp->request_buffer,
4713 scp->use_sg, scp->sc_data_direction);
4714 else if (scp->request_bufflen)
4715 dma_unmap_single(dev, scp->SCp.dma_handle,
4716 scp->request_bufflen,
4717 scp->sc_data_direction);
1da177e4 4718
27c868c2
MW
4719 ASC_STATS(scp->device->host, done);
4720 ASC_ASSERT(scp->scsi_done != NULL);
1da177e4 4721
27c868c2 4722 scp->scsi_done(scp);
1da177e4 4723
27c868c2
MW
4724 scp = tscp;
4725 }
4726 ASC_DBG(2, "asc_scsi_done_list: done\n");
4727 return;
1da177e4
LT
4728}
4729
4730/*
4731 * Execute a single 'Scsi_Cmnd'.
4732 *
4733 * The function 'done' is called when the request has been completed.
4734 *
4735 * Scsi_Cmnd:
4736 *
4737 * host - board controlling device
4738 * device - device to send command
4739 * target - target of device
4740 * lun - lun of device
4741 * cmd_len - length of SCSI CDB
4742 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
4743 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
4744 *
4745 * if (use_sg == 0) {
4746 * request_buffer - buffer address for request
4747 * request_bufflen - length of request buffer
4748 * } else {
4749 * request_buffer - pointer to scatterlist structure
4750 * }
4751 *
4752 * sense_buffer - sense command buffer
4753 *
4754 * result (4 bytes of an int):
4755 * Byte Meaning
4756 * 0 SCSI Status Byte Code
4757 * 1 SCSI One Byte Message Code
4758 * 2 Host Error Code
4759 * 3 Mid-Level Error Code
4760 *
4761 * host driver fields:
4762 * SCp - Scsi_Pointer used for command processing status
4763 * scsi_done - used to save caller's done function
4764 * host_scribble - used for pointer to another struct scsi_cmnd
4765 *
4766 * If this function returns ASC_NOERROR the request has been enqueued
4767 * on the board's 'active' queue and will be completed from the
4768 * interrupt handler.
4769 *
4770 * If this function returns ASC_NOERROR the request has been enqueued
4771 * on the board's 'done' queue and must be completed by the caller.
4772 *
4773 * If ASC_BUSY is returned the request will be enqueued by the
4774 * caller on the target's waiting queue and re-tried later.
4775 */
27c868c2 4776static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
1da177e4 4777{
27c868c2
MW
4778 asc_board_t *boardp;
4779 ASC_DVC_VAR *asc_dvc_varp;
4780 ADV_DVC_VAR *adv_dvc_varp;
4781 ADV_SCSI_REQ_Q *adv_scsiqp;
4782 struct scsi_device *device;
4783 int ret;
4784
4785 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
4786 (ulong)scp, (ulong)scp->scsi_done);
4787
4788 boardp = ASC_BOARDP(scp->device->host);
4789 device = boardp->device[scp->device->id];
4790
4791 if (ASC_NARROW_BOARD(boardp)) {
4792 /*
4793 * Build and execute Narrow Board request.
4794 */
4795
4796 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4797
4798 /*
4799 * Build Asc Library request structure using the
4800 * global structures 'asc_scsi_req' and 'asc_sg_head'.
4801 *
4802 * If an error is returned, then the request has been
4803 * queued on the board done queue. It will be completed
4804 * by the caller.
4805 *
4806 * asc_build_req() can not return ASC_BUSY.
4807 */
4808 if (asc_build_req(boardp, scp) == ASC_ERROR) {
4809 ASC_STATS(scp->device->host, build_error);
4810 return ASC_ERROR;
4811 }
4812
4813 /*
4814 * Execute the command. If there is no error, add the command
4815 * to the active queue.
4816 */
4817 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
4818 case ASC_NOERROR:
4819 ASC_STATS(scp->device->host, exe_noerror);
4820 /*
4821 * Increment monotonically increasing per device successful
4822 * request counter. Wrapping doesn't matter.
4823 */
4824 boardp->reqcnt[scp->device->id]++;
4825 asc_enqueue(&boardp->active, scp, ASC_BACK);
4826 ASC_DBG(1,
4827 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
4828 break;
4829 case ASC_BUSY:
4830 /*
4831 * Caller will enqueue request on the target's waiting queue
4832 * and retry later.
4833 */
4834 ASC_STATS(scp->device->host, exe_busy);
4835 break;
4836 case ASC_ERROR:
4837 ASC_PRINT2
4838 ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4839 boardp->id, asc_dvc_varp->err_code);
4840 ASC_STATS(scp->device->host, exe_error);
4841 scp->result = HOST_BYTE(DID_ERROR);
4842 asc_enqueue(&boardp->done, scp, ASC_BACK);
4843 break;
4844 default:
4845 ASC_PRINT2
4846 ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
4847 boardp->id, asc_dvc_varp->err_code);
4848 ASC_STATS(scp->device->host, exe_unknown);
4849 scp->result = HOST_BYTE(DID_ERROR);
4850 asc_enqueue(&boardp->done, scp, ASC_BACK);
4851 break;
4852 }
4853 } else {
4854 /*
4855 * Build and execute Wide Board request.
4856 */
4857 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4858
4859 /*
4860 * Build and get a pointer to an Adv Library request structure.
4861 *
4862 * If the request is successfully built then send it below,
4863 * otherwise return with an error.
4864 */
4865 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
4866 case ASC_NOERROR:
4867 ASC_DBG(3,
4868 "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
4869 break;
4870 case ASC_BUSY:
4871 ASC_DBG(1,
4872 "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
4873 /*
4874 * If busy is returned the request has not been enqueued.
4875 * It will be enqueued by the caller on the target's waiting
4876 * queue and retried later.
4877 *
4878 * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg'
4879 * count wide board busy conditions. They are updated in
4880 * adv_build_req and adv_get_sglist, respectively.
4881 */
4882 return ASC_BUSY;
4883 case ASC_ERROR:
4884 /*
4885 * If an error is returned, then the request has been
4886 * queued on the board done queue. It will be completed
4887 * by the caller.
4888 */
4889 default:
4890 ASC_DBG(1,
4891 "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
4892 ASC_STATS(scp->device->host, build_error);
4893 return ASC_ERROR;
4894 }
1da177e4 4895
27c868c2
MW
4896 /*
4897 * Execute the command. If there is no error, add the command
4898 * to the active queue.
4899 */
4900 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
4901 case ASC_NOERROR:
4902 ASC_STATS(scp->device->host, exe_noerror);
4903 /*
4904 * Increment monotonically increasing per device successful
4905 * request counter. Wrapping doesn't matter.
4906 */
4907 boardp->reqcnt[scp->device->id]++;
4908 asc_enqueue(&boardp->active, scp, ASC_BACK);
4909 ASC_DBG(1,
4910 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
4911 break;
4912 case ASC_BUSY:
4913 /*
4914 * Caller will enqueue request on the target's waiting queue
4915 * and retry later.
4916 */
4917 ASC_STATS(scp->device->host, exe_busy);
4918 break;
4919 case ASC_ERROR:
4920 ASC_PRINT2
4921 ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4922 boardp->id, adv_dvc_varp->err_code);
4923 ASC_STATS(scp->device->host, exe_error);
4924 scp->result = HOST_BYTE(DID_ERROR);
4925 asc_enqueue(&boardp->done, scp, ASC_BACK);
4926 break;
4927 default:
4928 ASC_PRINT2
4929 ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
4930 boardp->id, adv_dvc_varp->err_code);
4931 ASC_STATS(scp->device->host, exe_unknown);
4932 scp->result = HOST_BYTE(DID_ERROR);
4933 asc_enqueue(&boardp->done, scp, ASC_BACK);
4934 break;
4935 }
4936 }
4937
4938 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
4939 return ret;
1da177e4
LT
4940}
4941
4942/*
4943 * Build a request structure for the Asc Library (Narrow Board).
4944 *
4945 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
4946 * used to build the request.
4947 *
4948 * If an error occurs, then queue the request on the board done
4949 * queue and return ASC_ERROR.
4950 */
27c868c2 4951static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
1da177e4 4952{
27c868c2
MW
4953 struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
4954
4955 /*
4956 * Mutually exclusive access is required to 'asc_scsi_q' and
4957 * 'asc_sg_head' until after the request is started.
4958 */
4959 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
4960
4961 /*
4962 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
4963 */
4964 asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
4965
4966 /*
4967 * Build the ASC_SCSI_Q request.
4968 *
4969 * For narrow boards a CDB length maximum of 12 bytes
4970 * is supported.
4971 */
4972 if (scp->cmd_len > ASC_MAX_CDB_LEN) {
4973 ASC_PRINT3
4974 ("asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN %d\n",
4975 boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN);
4976 scp->result = HOST_BYTE(DID_ERROR);
4977 asc_enqueue(&boardp->done, scp, ASC_BACK);
4978 return ASC_ERROR;
4979 }
4980 asc_scsi_q.cdbptr = &scp->cmnd[0];
4981 asc_scsi_q.q2.cdb_len = scp->cmd_len;
4982 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
4983 asc_scsi_q.q1.target_lun = scp->device->lun;
4984 asc_scsi_q.q2.target_ix =
4985 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
4986 asc_scsi_q.q1.sense_addr =
4987 cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
4988 asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
4989
4990 /*
4991 * If there are any outstanding requests for the current target,
4992 * then every 255th request send an ORDERED request. This heuristic
4993 * tries to retain the benefit of request sorting while preventing
4994 * request starvation. 255 is the max number of tags or pending commands
4995 * a device may have outstanding.
4996 *
4997 * The request count is incremented below for every successfully
4998 * started request.
4999 *
5000 */
5001 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
5002 (boardp->reqcnt[scp->device->id] % 255) == 0) {
5003 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
5004 } else {
5005 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
5006 }
1da177e4 5007
27c868c2
MW
5008 /*
5009 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
5010 * buffer command.
5011 */
5012 if (scp->use_sg == 0) {
5013 /*
5014 * CDB request of single contiguous buffer.
5015 */
5016 ASC_STATS(scp->device->host, cont_cnt);
5017 scp->SCp.dma_handle = scp->request_bufflen ?
5018 dma_map_single(dev, scp->request_buffer,
5019 scp->request_bufflen,
5020 scp->sc_data_direction) : 0;
5021 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
5022 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
5023 ASC_STATS_ADD(scp->device->host, cont_xfer,
5024 ASC_CEILING(scp->request_bufflen, 512));
5025 asc_scsi_q.q1.sg_queue_cnt = 0;
5026 asc_scsi_q.sg_head = NULL;
5027 } else {
5028 /*
5029 * CDB scatter-gather request list.
5030 */
5031 int sgcnt;
5032 int use_sg;
5033 struct scatterlist *slp;
5034
5035 slp = (struct scatterlist *)scp->request_buffer;
5036 use_sg =
5037 dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
5038
5039 if (use_sg > scp->device->host->sg_tablesize) {
5040 ASC_PRINT3
5041 ("asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
5042 boardp->id, use_sg,
5043 scp->device->host->sg_tablesize);
5044 dma_unmap_sg(dev, slp, scp->use_sg,
5045 scp->sc_data_direction);
5046 scp->result = HOST_BYTE(DID_ERROR);
5047 asc_enqueue(&boardp->done, scp, ASC_BACK);
5048 return ASC_ERROR;
5049 }
5050
5051 ASC_STATS(scp->device->host, sg_cnt);
1da177e4 5052
27c868c2
MW
5053 /*
5054 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
5055 * structure to point to it.
5056 */
5057 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
5058
5059 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
5060 asc_scsi_q.sg_head = &asc_sg_head;
5061 asc_scsi_q.q1.data_cnt = 0;
5062 asc_scsi_q.q1.data_addr = 0;
5063 /* This is a byte value, otherwise it would need to be swapped. */
5064 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
5065 ASC_STATS_ADD(scp->device->host, sg_elem,
5066 asc_sg_head.entry_cnt);
1da177e4 5067
27c868c2
MW
5068 /*
5069 * Convert scatter-gather list into ASC_SG_HEAD list.
5070 */
5071 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
5072 asc_sg_head.sg_list[sgcnt].addr =
5073 cpu_to_le32(sg_dma_address(slp));
5074 asc_sg_head.sg_list[sgcnt].bytes =
5075 cpu_to_le32(sg_dma_len(slp));
5076 ASC_STATS_ADD(scp->device->host, sg_xfer,
5077 ASC_CEILING(sg_dma_len(slp), 512));
5078 }
5079 }
1da177e4 5080
27c868c2
MW
5081 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
5082 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
1da177e4 5083
27c868c2 5084 return ASC_NOERROR;
1da177e4
LT
5085}
5086
5087/*
5088 * Build a request structure for the Adv Library (Wide Board).
5089 *
5090 * If an adv_req_t can not be allocated to issue the request,
5091 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
5092 *
5093 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
5094 * microcode for DMA addresses or math operations are byte swapped
5095 * to little-endian order.
5096 */
27c868c2 5097static int
1da177e4 5098adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
27c868c2 5099 ADV_SCSI_REQ_Q **adv_scsiqpp)
1da177e4 5100{
27c868c2
MW
5101 adv_req_t *reqp;
5102 ADV_SCSI_REQ_Q *scsiqp;
5103 int i;
5104 int ret;
5105 struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
5106
5107 /*
5108 * Allocate an adv_req_t structure from the board to execute
5109 * the command.
5110 */
5111 if (boardp->adv_reqp == NULL) {
5112 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
5113 ASC_STATS(scp->device->host, adv_build_noreq);
5114 return ASC_BUSY;
5115 } else {
5116 reqp = boardp->adv_reqp;
5117 boardp->adv_reqp = reqp->next_reqp;
5118 reqp->next_reqp = NULL;
5119 }
1da177e4 5120
27c868c2
MW
5121 /*
5122 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
5123 */
5124 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5125
5126 /*
5127 * Initialize the structure.
5128 */
5129 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
5130
5131 /*
5132 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
5133 */
5134 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
5135
5136 /*
5137 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
5138 */
5139 reqp->cmndp = scp;
5140
5141 /*
5142 * Build the ADV_SCSI_REQ_Q request.
5143 */
5144
5145 /*
5146 * Set CDB length and copy it to the request structure.
5147 * For wide boards a CDB length maximum of 16 bytes
5148 * is supported.
5149 */
5150 if (scp->cmd_len > ADV_MAX_CDB_LEN) {
5151 ASC_PRINT3
5152 ("adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n",
5153 boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
5154 scp->result = HOST_BYTE(DID_ERROR);
5155 asc_enqueue(&boardp->done, scp, ASC_BACK);
5156 return ASC_ERROR;
5157 }
5158 scsiqp->cdb_len = scp->cmd_len;
5159 /* Copy first 12 CDB bytes to cdb[]. */
5160 for (i = 0; i < scp->cmd_len && i < 12; i++) {
5161 scsiqp->cdb[i] = scp->cmnd[i];
5162 }
5163 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
5164 for (; i < scp->cmd_len; i++) {
5165 scsiqp->cdb16[i - 12] = scp->cmnd[i];
5166 }
1da177e4 5167
27c868c2
MW
5168 scsiqp->target_id = scp->device->id;
5169 scsiqp->target_lun = scp->device->lun;
1da177e4 5170
27c868c2
MW
5171 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
5172 scsiqp->sense_len = sizeof(scp->sense_buffer);
1da177e4 5173
27c868c2
MW
5174 /*
5175 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
5176 * buffer command.
5177 */
1da177e4 5178
1da177e4 5179 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
27c868c2
MW
5180 scsiqp->vdata_addr = scp->request_buffer;
5181 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
1da177e4 5182
27c868c2
MW
5183 if (scp->use_sg == 0) {
5184 /*
5185 * CDB request of single contiguous buffer.
5186 */
5187 reqp->sgblkp = NULL;
5188 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
5189 if (scp->request_bufflen) {
5190 scsiqp->vdata_addr = scp->request_buffer;
5191 scp->SCp.dma_handle =
5192 dma_map_single(dev, scp->request_buffer,
5193 scp->request_bufflen,
5194 scp->sc_data_direction);
5195 } else {
5196 scsiqp->vdata_addr = NULL;
5197 scp->SCp.dma_handle = 0;
5198 }
5199 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
5200 scsiqp->sg_list_ptr = NULL;
5201 scsiqp->sg_real_addr = 0;
5202 ASC_STATS(scp->device->host, cont_cnt);
5203 ASC_STATS_ADD(scp->device->host, cont_xfer,
5204 ASC_CEILING(scp->request_bufflen, 512));
5205 } else {
5206 /*
5207 * CDB scatter-gather request list.
5208 */
5209 struct scatterlist *slp;
5210 int use_sg;
5211
5212 slp = (struct scatterlist *)scp->request_buffer;
5213 use_sg =
5214 dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
5215
5216 if (use_sg > ADV_MAX_SG_LIST) {
5217 ASC_PRINT3
5218 ("adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
5219 boardp->id, use_sg,
5220 scp->device->host->sg_tablesize);
5221 dma_unmap_sg(dev, slp, scp->use_sg,
5222 scp->sc_data_direction);
5223 scp->result = HOST_BYTE(DID_ERROR);
5224 asc_enqueue(&boardp->done, scp, ASC_BACK);
5225
5226 /*
5227 * Free the 'adv_req_t' structure by adding it back to the
5228 * board free list.
5229 */
5230 reqp->next_reqp = boardp->adv_reqp;
5231 boardp->adv_reqp = reqp;
5232
5233 return ASC_ERROR;
5234 }
5235
5236 if ((ret =
5237 adv_get_sglist(boardp, reqp, scp,
5238 use_sg)) != ADV_SUCCESS) {
5239 /*
5240 * Free the adv_req_t structure by adding it back to the
5241 * board free list.
5242 */
5243 reqp->next_reqp = boardp->adv_reqp;
5244 boardp->adv_reqp = reqp;
5245
5246 return ret;
5247 }
5248
5249 ASC_STATS(scp->device->host, sg_cnt);
5250 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
5251 }
1da177e4 5252
27c868c2
MW
5253 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5254 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
1da177e4 5255
27c868c2 5256 *adv_scsiqpp = scsiqp;
1da177e4 5257
27c868c2 5258 return ASC_NOERROR;
1da177e4
LT
5259}
5260
5261/*
5262 * Build scatter-gather list for Adv Library (Wide Board).
5263 *
5264 * Additional ADV_SG_BLOCK structures will need to be allocated
5265 * if the total number of scatter-gather elements exceeds
5266 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
5267 * assumed to be physically contiguous.
5268 *
5269 * Return:
5270 * ADV_SUCCESS(1) - SG List successfully created
5271 * ADV_ERROR(-1) - SG List creation failed
5272 */
27c868c2
MW
5273static int
5274adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
5275 int use_sg)
1da177e4 5276{
27c868c2
MW
5277 adv_sgblk_t *sgblkp;
5278 ADV_SCSI_REQ_Q *scsiqp;
5279 struct scatterlist *slp;
5280 int sg_elem_cnt;
5281 ADV_SG_BLOCK *sg_block, *prev_sg_block;
5282 ADV_PADDR sg_block_paddr;
5283 int i;
5284
5285 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5286 slp = (struct scatterlist *)scp->request_buffer;
5287 sg_elem_cnt = use_sg;
5288 prev_sg_block = NULL;
5289 reqp->sgblkp = NULL;
5290
5291 do {
5292 /*
5293 * Allocate a 'adv_sgblk_t' structure from the board free
5294 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
5295 * (15) scatter-gather elements.
5296 */
5297 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
5298 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
5299 ASC_STATS(scp->device->host, adv_build_nosg);
5300
5301 /*
5302 * Allocation failed. Free 'adv_sgblk_t' structures already
5303 * allocated for the request.
5304 */
5305 while ((sgblkp = reqp->sgblkp) != NULL) {
5306 /* Remove 'sgblkp' from the request list. */
5307 reqp->sgblkp = sgblkp->next_sgblkp;
5308
5309 /* Add 'sgblkp' to the board free list. */
5310 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5311 boardp->adv_sgblkp = sgblkp;
5312 }
5313 return ASC_BUSY;
5314 } else {
5315 /* Complete 'adv_sgblk_t' board allocation. */
5316 boardp->adv_sgblkp = sgblkp->next_sgblkp;
5317 sgblkp->next_sgblkp = NULL;
5318
5319 /*
5320 * Get 8 byte aligned virtual and physical addresses for
5321 * the allocated ADV_SG_BLOCK structure.
5322 */
5323 sg_block =
5324 (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
5325 sg_block_paddr = virt_to_bus(sg_block);
5326
5327 /*
5328 * Check if this is the first 'adv_sgblk_t' for the request.
5329 */
5330 if (reqp->sgblkp == NULL) {
5331 /* Request's first scatter-gather block. */
5332 reqp->sgblkp = sgblkp;
5333
5334 /*
5335 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
5336 * address pointers.
5337 */
5338 scsiqp->sg_list_ptr = sg_block;
5339 scsiqp->sg_real_addr =
5340 cpu_to_le32(sg_block_paddr);
5341 } else {
5342 /* Request's second or later scatter-gather block. */
5343 sgblkp->next_sgblkp = reqp->sgblkp;
5344 reqp->sgblkp = sgblkp;
5345
5346 /*
5347 * Point the previous ADV_SG_BLOCK structure to
5348 * the newly allocated ADV_SG_BLOCK structure.
5349 */
5350 ASC_ASSERT(prev_sg_block != NULL);
5351 prev_sg_block->sg_ptr =
5352 cpu_to_le32(sg_block_paddr);
5353 }
5354 }
5355
5356 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
5357 sg_block->sg_list[i].sg_addr =
5358 cpu_to_le32(sg_dma_address(slp));
5359 sg_block->sg_list[i].sg_count =
5360 cpu_to_le32(sg_dma_len(slp));
5361 ASC_STATS_ADD(scp->device->host, sg_xfer,
5362 ASC_CEILING(sg_dma_len(slp), 512));
5363
5364 if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */
5365 sg_block->sg_cnt = i + 1;
5366 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
5367 return ADV_SUCCESS;
5368 }
5369 slp++;
5370 }
5371 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
5372 prev_sg_block = sg_block;
5373 }
5374 while (1);
5375 /* NOTREACHED */
1da177e4
LT
5376}
5377
5378/*
5379 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
5380 *
5381 * Interrupt callback function for the Narrow SCSI Asc Library.
5382 */
27c868c2 5383static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
1da177e4 5384{
27c868c2
MW
5385 asc_board_t *boardp;
5386 struct scsi_cmnd *scp;
5387 struct Scsi_Host *shost;
27c868c2
MW
5388
5389 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
5390 (ulong)asc_dvc_varp, (ulong)qdonep);
5391 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
5392
5393 /*
5394 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5395 * command that has been completed.
5396 */
5397 scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
5398 ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp);
5399
5400 if (scp == NULL) {
5401 ASC_PRINT("asc_isr_callback: scp is NULL\n");
5402 return;
5403 }
5404 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5405
27c868c2 5406 shost = scp->device->host;
27c868c2
MW
5407 ASC_STATS(shost, callback);
5408 ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
5409
5410 /*
5411 * If the request isn't found on the active queue, it may
5412 * have been removed to handle a reset request.
5413 * Display a message and return.
5414 */
5415 boardp = ASC_BOARDP(shost);
5416 ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
5417 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5418 ASC_PRINT2
5419 ("asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
5420 boardp->id, (ulong)scp);
5421 return;
5422 }
1da177e4 5423
27c868c2
MW
5424 /*
5425 * 'qdonep' contains the command's ending status.
5426 */
5427 switch (qdonep->d3.done_stat) {
5428 case QD_NO_ERROR:
5429 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
5430 scp->result = 0;
1da177e4 5431
27c868c2
MW
5432 /*
5433 * If an INQUIRY command completed successfully, then call
5434 * the AscInquiryHandling() function to set-up the device.
5435 */
5436 if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 &&
5437 (scp->request_bufflen - qdonep->remain_bytes) >= 8) {
5438 AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7,
5439 (ASC_SCSI_INQUIRY *)scp->
5440 request_buffer);
5441 }
1da177e4 5442
27c868c2
MW
5443 /*
5444 * Check for an underrun condition.
5445 *
5446 * If there was no error and an underrun condition, then
5447 * then return the number of underrun bytes.
5448 */
5449 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
5450 qdonep->remain_bytes <= scp->request_bufflen) {
5451 ASC_DBG1(1,
5452 "asc_isr_callback: underrun condition %u bytes\n",
5453 (unsigned)qdonep->remain_bytes);
5454 scp->resid = qdonep->remain_bytes;
5455 }
5456 break;
5457
5458 case QD_WITH_ERROR:
5459 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
5460 switch (qdonep->d3.host_stat) {
5461 case QHSTA_NO_ERROR:
5462 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
5463 ASC_DBG(2,
5464 "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5465 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5466 sizeof(scp->sense_buffer));
5467 /*
5468 * Note: The 'status_byte()' macro used by target drivers
5469 * defined in scsi.h shifts the status byte returned by
5470 * host drivers right by 1 bit. This is why target drivers
5471 * also use right shifted status byte definitions. For
5472 * instance target drivers use CHECK_CONDITION, defined to
5473 * 0x1, instead of the SCSI defined check condition value
5474 * of 0x2. Host drivers are supposed to return the status
5475 * byte as it is defined by SCSI.
5476 */
5477 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5478 STATUS_BYTE(qdonep->d3.scsi_stat);
5479 } else {
5480 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
5481 }
5482 break;
5483
5484 default:
5485 /* QHSTA error occurred */
5486 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
5487 qdonep->d3.host_stat);
5488 scp->result = HOST_BYTE(DID_BAD_TARGET);
5489 break;
5490 }
5491 break;
5492
5493 case QD_ABORTED_BY_HOST:
5494 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
5495 scp->result =
5496 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
5497 scsi_msg) |
5498 STATUS_BYTE(qdonep->d3.scsi_stat);
5499 break;
5500
5501 default:
5502 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n",
5503 qdonep->d3.done_stat);
5504 scp->result =
5505 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
5506 scsi_msg) |
5507 STATUS_BYTE(qdonep->d3.scsi_stat);
5508 break;
5509 }
1da177e4 5510
27c868c2
MW
5511 /*
5512 * If the 'init_tidmask' bit isn't already set for the target and the
5513 * current request finished normally, then set the bit for the target
5514 * to indicate that a device is present.
5515 */
5516 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5517 qdonep->d3.done_stat == QD_NO_ERROR &&
5518 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
5519 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5520 }
1da177e4 5521
27c868c2
MW
5522 /*
5523 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5524 * function, add the command to the end of the board's done queue.
5525 * The done function for the command will be called from
5526 * advansys_interrupt().
5527 */
5528 asc_enqueue(&boardp->done, scp, ASC_BACK);
1da177e4 5529
27c868c2 5530 return;
1da177e4
LT
5531}
5532
5533/*
5534 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
5535 *
5536 * Callback function for the Wide SCSI Adv Library.
5537 */
27c868c2 5538static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
1da177e4 5539{
27c868c2
MW
5540 asc_board_t *boardp;
5541 adv_req_t *reqp;
5542 adv_sgblk_t *sgblkp;
5543 struct scsi_cmnd *scp;
5544 struct Scsi_Host *shost;
27c868c2
MW
5545 ADV_DCNT resid_cnt;
5546
5547 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
5548 (ulong)adv_dvc_varp, (ulong)scsiqp);
5549 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5550
5551 /*
5552 * Get the adv_req_t structure for the command that has been
5553 * completed. The adv_req_t structure actually contains the
5554 * completed ADV_SCSI_REQ_Q structure.
5555 */
5556 reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
5557 ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp);
5558 if (reqp == NULL) {
5559 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
5560 return;
5561 }
1da177e4 5562
27c868c2
MW
5563 /*
5564 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5565 * command that has been completed.
5566 *
5567 * Note: The adv_req_t request structure and adv_sgblk_t structure,
5568 * if any, are dropped, because a board structure pointer can not be
5569 * determined.
5570 */
5571 scp = reqp->cmndp;
5572 ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp);
5573 if (scp == NULL) {
5574 ASC_PRINT
5575 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
5576 return;
5577 }
5578 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5579
27c868c2 5580 shost = scp->device->host;
27c868c2
MW
5581 ASC_STATS(shost, callback);
5582 ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
5583
5584 /*
5585 * If the request isn't found on the active queue, it may have been
5586 * removed to handle a reset request. Display a message and return.
5587 *
5588 * Note: Because the structure may still be in use don't attempt
5589 * to free the adv_req_t and adv_sgblk_t, if any, structures.
5590 */
5591 boardp = ASC_BOARDP(shost);
5592 ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
5593 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5594 ASC_PRINT2
5595 ("adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
5596 boardp->id, (ulong)scp);
5597 return;
5598 }
1da177e4 5599
27c868c2
MW
5600 /*
5601 * 'done_status' contains the command's ending status.
5602 */
5603 switch (scsiqp->done_status) {
5604 case QD_NO_ERROR:
5605 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
5606 scp->result = 0;
1da177e4 5607
27c868c2
MW
5608 /*
5609 * Check for an underrun condition.
5610 *
5611 * If there was no error and an underrun condition, then
5612 * then return the number of underrun bytes.
5613 */
5614 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
5615 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
5616 resid_cnt <= scp->request_bufflen) {
5617 ASC_DBG1(1,
5618 "adv_isr_callback: underrun condition %lu bytes\n",
5619 (ulong)resid_cnt);
5620 scp->resid = resid_cnt;
5621 }
5622 break;
5623
5624 case QD_WITH_ERROR:
5625 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
5626 switch (scsiqp->host_status) {
5627 case QHSTA_NO_ERROR:
5628 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
5629 ASC_DBG(2,
5630 "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5631 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5632 sizeof(scp->sense_buffer));
5633 /*
5634 * Note: The 'status_byte()' macro used by target drivers
5635 * defined in scsi.h shifts the status byte returned by
5636 * host drivers right by 1 bit. This is why target drivers
5637 * also use right shifted status byte definitions. For
5638 * instance target drivers use CHECK_CONDITION, defined to
5639 * 0x1, instead of the SCSI defined check condition value
5640 * of 0x2. Host drivers are supposed to return the status
5641 * byte as it is defined by SCSI.
5642 */
5643 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5644 STATUS_BYTE(scsiqp->scsi_status);
5645 } else {
5646 scp->result = STATUS_BYTE(scsiqp->scsi_status);
5647 }
5648 break;
5649
5650 default:
5651 /* Some other QHSTA error occurred. */
5652 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
5653 scsiqp->host_status);
5654 scp->result = HOST_BYTE(DID_BAD_TARGET);
5655 break;
5656 }
5657 break;
5658
5659 case QD_ABORTED_BY_HOST:
5660 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
5661 scp->result =
5662 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
5663 break;
5664
5665 default:
5666 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n",
5667 scsiqp->done_status);
5668 scp->result =
5669 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
5670 break;
5671 }
1da177e4 5672
27c868c2
MW
5673 /*
5674 * If the 'init_tidmask' bit isn't already set for the target and the
5675 * current request finished normally, then set the bit for the target
5676 * to indicate that a device is present.
5677 */
5678 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5679 scsiqp->done_status == QD_NO_ERROR &&
5680 scsiqp->host_status == QHSTA_NO_ERROR) {
5681 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5682 }
1da177e4 5683
27c868c2
MW
5684 /*
5685 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5686 * function, add the command to the end of the board's done queue.
5687 * The done function for the command will be called from
5688 * advansys_interrupt().
5689 */
5690 asc_enqueue(&boardp->done, scp, ASC_BACK);
5691
5692 /*
5693 * Free all 'adv_sgblk_t' structures allocated for the request.
5694 */
5695 while ((sgblkp = reqp->sgblkp) != NULL) {
5696 /* Remove 'sgblkp' from the request list. */
5697 reqp->sgblkp = sgblkp->next_sgblkp;
5698
5699 /* Add 'sgblkp' to the board free list. */
5700 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5701 boardp->adv_sgblkp = sgblkp;
5702 }
1da177e4 5703
27c868c2
MW
5704 /*
5705 * Free the adv_req_t structure used with the command by adding
5706 * it back to the board free list.
5707 */
5708 reqp->next_reqp = boardp->adv_reqp;
5709 boardp->adv_reqp = reqp;
1da177e4 5710
27c868c2 5711 ASC_DBG(1, "adv_isr_callback: done\n");
1da177e4 5712
27c868c2 5713 return;
1da177e4
LT
5714}
5715
5716/*
5717 * adv_async_callback() - Adv Library asynchronous event callback function.
5718 */
27c868c2 5719static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
1da177e4 5720{
27c868c2
MW
5721 switch (code) {
5722 case ADV_ASYNC_SCSI_BUS_RESET_DET:
5723 /*
5724 * The firmware detected a SCSI Bus reset.
5725 */
5726 ASC_DBG(0,
5727 "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
5728 break;
5729
5730 case ADV_ASYNC_RDMA_FAILURE:
5731 /*
5732 * Handle RDMA failure by resetting the SCSI Bus and
5733 * possibly the chip if it is unresponsive. Log the error
5734 * with a unique code.
5735 */
5736 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
5737 AdvResetChipAndSB(adv_dvc_varp);
5738 break;
5739
5740 case ADV_HOST_SCSI_BUS_RESET:
5741 /*
5742 * Host generated SCSI bus reset occurred.
5743 */
5744 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
5745 break;
5746
5747 default:
5748 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
5749 break;
5750 }
1da177e4
LT
5751}
5752
5753/*
5754 * Add a 'REQP' to the end of specified queue. Set 'tidmask'
5755 * to indicate a command is queued for the device.
5756 *
5757 * 'flag' may be either ASC_FRONT or ASC_BACK.
5758 *
5759 * 'REQPNEXT(reqp)' returns reqp's next pointer.
5760 */
27c868c2 5761static void asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
1da177e4 5762{
27c868c2
MW
5763 int tid;
5764
5765 ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
5766 (ulong)ascq, (ulong)reqp, flag);
5767 ASC_ASSERT(reqp != NULL);
5768 ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
5769 tid = REQPTID(reqp);
5770 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5771 if (flag == ASC_FRONT) {
5772 reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
5773 ascq->q_first[tid] = reqp;
5774 /* If the queue was empty, set the last pointer. */
5775 if (ascq->q_last[tid] == NULL) {
5776 ascq->q_last[tid] = reqp;
5777 }
5778 } else { /* ASC_BACK */
5779 if (ascq->q_last[tid] != NULL) {
5780 ascq->q_last[tid]->host_scribble =
5781 (unsigned char *)reqp;
5782 }
5783 ascq->q_last[tid] = reqp;
5784 reqp->host_scribble = NULL;
5785 /* If the queue was empty, set the first pointer. */
5786 if (ascq->q_first[tid] == NULL) {
5787 ascq->q_first[tid] = reqp;
5788 }
5789 }
5790 /* The queue has at least one entry, set its bit. */
5791 ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
1da177e4 5792#ifdef ADVANSYS_STATS
27c868c2
MW
5793 /* Maintain request queue statistics. */
5794 ascq->q_tot_cnt[tid]++;
5795 ascq->q_cur_cnt[tid]++;
5796 if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
5797 ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
5798 ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
5799 tid, ascq->q_max_cnt[tid]);
5800 }
5801 REQPTIME(reqp) = REQTIMESTAMP();
1da177e4 5802#endif /* ADVANSYS_STATS */
27c868c2
MW
5803 ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong)reqp);
5804 return;
1da177e4
LT
5805}
5806
5807/*
5808 * Return first queued 'REQP' on the specified queue for
5809 * the specified target device. Clear the 'tidmask' bit for
5810 * the device if no more commands are left queued for it.
5811 *
5812 * 'REQPNEXT(reqp)' returns reqp's next pointer.
5813 */
27c868c2 5814static REQP asc_dequeue(asc_queue_t *ascq, int tid)
1da177e4 5815{
27c868c2
MW
5816 REQP reqp;
5817
5818 ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5819 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5820 if ((reqp = ascq->q_first[tid]) != NULL) {
5821 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
5822 ascq->q_first[tid] = REQPNEXT(reqp);
5823 /* If the queue is empty, clear its bit and the last pointer. */
5824 if (ascq->q_first[tid] == NULL) {
5825 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5826 ASC_ASSERT(ascq->q_last[tid] == reqp);
5827 ascq->q_last[tid] = NULL;
5828 }
1da177e4 5829#ifdef ADVANSYS_STATS
27c868c2
MW
5830 /* Maintain request queue statistics. */
5831 ascq->q_cur_cnt[tid]--;
5832 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
5833 REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
1da177e4 5834#endif /* ADVANSYS_STATS */
27c868c2
MW
5835 }
5836 ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong)reqp);
5837 return reqp;
1da177e4
LT
5838}
5839
5840/*
5841 * Return a pointer to a singly linked list of all the requests queued
5842 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
5843 *
5844 * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
5845 * the last request returned in the singly linked list.
5846 *
5847 * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
5848 * then all queued requests are concatenated into one list and
5849 * returned.
5850 *
5851 * Note: If 'lastpp' is used to append a new list to the end of
5852 * an old list, only change the old list last pointer if '*lastpp'
5853 * (or the function return value) is not NULL, i.e. use a temporary
5854 * variable for 'lastpp' and check its value after the function return
5855 * before assigning it to the list last pointer.
5856 *
5857 * Unfortunately collecting queuing time statistics adds overhead to
5858 * the function that isn't inherent to the function's algorithm.
5859 */
27c868c2 5860static REQP asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
1da177e4 5861{
27c868c2
MW
5862 REQP firstp, lastp;
5863 int i;
5864
5865 ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5866 ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
5867
5868 /*
5869 * If 'tid' is not ASC_TID_ALL, return requests only for
5870 * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
5871 * requests for all tids.
5872 */
5873 if (tid != ASC_TID_ALL) {
5874 /* Return all requests for the specified 'tid'. */
5875 if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
5876 /* List is empty; Set first and last return pointers to NULL. */
5877 firstp = lastp = NULL;
5878 } else {
5879 firstp = ascq->q_first[tid];
5880 lastp = ascq->q_last[tid];
5881 ascq->q_first[tid] = ascq->q_last[tid] = NULL;
5882 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
1da177e4 5883#ifdef ADVANSYS_STATS
27c868c2
MW
5884 {
5885 REQP reqp;
5886 ascq->q_cur_cnt[tid] = 0;
5887 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
5888 REQTIMESTAT("asc_dequeue_list", ascq,
5889 reqp, tid);
5890 }
5891 }
1da177e4 5892#endif /* ADVANSYS_STATS */
27c868c2
MW
5893 }
5894 } else {
5895 /* Return all requests for all tids. */
5896 firstp = lastp = NULL;
5897 for (i = 0; i <= ADV_MAX_TID; i++) {
5898 if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
5899 if (firstp == NULL) {
5900 firstp = ascq->q_first[i];
5901 lastp = ascq->q_last[i];
5902 } else {
5903 ASC_ASSERT(lastp != NULL);
5904 lastp->host_scribble =
5905 (unsigned char *)ascq->q_first[i];
5906 lastp = ascq->q_last[i];
5907 }
5908 ascq->q_first[i] = ascq->q_last[i] = NULL;
5909 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
1da177e4 5910#ifdef ADVANSYS_STATS
27c868c2 5911 ascq->q_cur_cnt[i] = 0;
1da177e4 5912#endif /* ADVANSYS_STATS */
27c868c2
MW
5913 }
5914 }
1da177e4 5915#ifdef ADVANSYS_STATS
27c868c2
MW
5916 {
5917 REQP reqp;
5918 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
5919 REQTIMESTAT("asc_dequeue_list", ascq, reqp,
5920 reqp->device->id);
5921 }
5922 }
1da177e4 5923#endif /* ADVANSYS_STATS */
27c868c2
MW
5924 }
5925 if (lastpp) {
5926 *lastpp = lastp;
5927 }
5928 ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong)firstp);
5929 return firstp;
1da177e4
LT
5930}
5931
5932/*
5933 * Remove the specified 'REQP' from the specified queue for
5934 * the specified target device. Clear the 'tidmask' bit for the
5935 * device if no more commands are left queued for it.
5936 *
5937 * 'REQPNEXT(reqp)' returns reqp's the next pointer.
5938 *
5939 * Return ASC_TRUE if the command was found and removed,
5940 * otherwise return ASC_FALSE.
5941 */
27c868c2 5942static int asc_rmqueue(asc_queue_t *ascq, REQP reqp)
1da177e4 5943{
27c868c2
MW
5944 REQP currp, prevp;
5945 int tid;
5946 int ret = ASC_FALSE;
5947
5948 ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
5949 (ulong)ascq, (ulong)reqp);
5950 ASC_ASSERT(reqp != NULL);
5951
5952 tid = REQPTID(reqp);
5953 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5954
5955 /*
5956 * Handle the common case of 'reqp' being the first
5957 * entry on the queue.
5958 */
5959 if (reqp == ascq->q_first[tid]) {
5960 ret = ASC_TRUE;
5961 ascq->q_first[tid] = REQPNEXT(reqp);
5962 /* If the queue is now empty, clear its bit and the last pointer. */
5963 if (ascq->q_first[tid] == NULL) {
5964 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5965 ASC_ASSERT(ascq->q_last[tid] == reqp);
5966 ascq->q_last[tid] = NULL;
5967 }
5968 } else if (ascq->q_first[tid] != NULL) {
5969 ASC_ASSERT(ascq->q_last[tid] != NULL);
5970 /*
5971 * Because the case of 'reqp' being the first entry has been
5972 * handled above and it is known the queue is not empty, if
5973 * 'reqp' is found on the queue it is guaranteed the queue will
5974 * not become empty and that 'q_first[tid]' will not be changed.
5975 *
5976 * Set 'prevp' to the first entry, 'currp' to the second entry,
5977 * and search for 'reqp'.
5978 */
5979 for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
5980 currp; prevp = currp, currp = REQPNEXT(currp)) {
5981 if (currp == reqp) {
5982 ret = ASC_TRUE;
5983 prevp->host_scribble =
5984 (unsigned char *)REQPNEXT(currp);
5985 reqp->host_scribble = NULL;
5986 if (ascq->q_last[tid] == reqp) {
5987 ascq->q_last[tid] = prevp;
5988 }
5989 break;
5990 }
5991 }
5992 }
1da177e4 5993#ifdef ADVANSYS_STATS
27c868c2
MW
5994 /* Maintain request queue statistics. */
5995 if (ret == ASC_TRUE) {
5996 ascq->q_cur_cnt[tid]--;
5997 REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
5998 }
5999 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
1da177e4 6000#endif /* ADVANSYS_STATS */
27c868c2
MW
6001 ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong)reqp, ret);
6002 return ret;
1da177e4
LT
6003}
6004
6005/*
6006 * Execute as many queued requests as possible for the specified queue.
6007 *
6008 * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd.
6009 */
27c868c2 6010static void asc_execute_queue(asc_queue_t *ascq)
1da177e4 6011{
27c868c2
MW
6012 ADV_SCSI_BIT_ID_TYPE scan_tidmask;
6013 REQP reqp;
6014 int i;
6015
6016 ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong)ascq);
6017 /*
6018 * Execute queued commands for devices attached to
6019 * the current board in round-robin fashion.
6020 */
6021 scan_tidmask = ascq->q_tidmask;
6022 do {
6023 for (i = 0; i <= ADV_MAX_TID; i++) {
6024 if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
6025 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
6026 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
6027 } else
6028 if (asc_execute_scsi_cmnd
6029 ((struct scsi_cmnd *)reqp)
6030 == ASC_BUSY) {
6031 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
6032 /*
6033 * The request returned ASC_BUSY. Enqueue at the front of
6034 * target's waiting list to maintain correct ordering.
6035 */
6036 asc_enqueue(ascq, reqp, ASC_FRONT);
6037 }
6038 }
6039 }
6040 } while (scan_tidmask);
6041 return;
1da177e4
LT
6042}
6043
6044#ifdef CONFIG_PROC_FS
6045/*
6046 * asc_prt_board_devices()
6047 *
6048 * Print driver information for devices attached to the board.
6049 *
6050 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6051 * cf. asc_prt_line().
6052 *
6053 * Return the number of characters copied into 'cp'. No more than
6054 * 'cplen' characters will be copied to 'cp'.
6055 */
27c868c2 6056static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6057{
27c868c2
MW
6058 asc_board_t *boardp;
6059 int leftlen;
6060 int totlen;
6061 int len;
6062 int chip_scsi_id;
6063 int i;
6064
6065 boardp = ASC_BOARDP(shost);
6066 leftlen = cplen;
6067 totlen = len = 0;
6068
6069 len = asc_prt_line(cp, leftlen,
6070 "\nDevice Information for AdvanSys SCSI Host %d:\n",
6071 shost->host_no);
6072 ASC_PRT_NEXT();
6073
6074 if (ASC_NARROW_BOARD(boardp)) {
6075 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6076 } else {
6077 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6078 }
1da177e4 6079
27c868c2
MW
6080 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
6081 ASC_PRT_NEXT();
6082 for (i = 0; i <= ADV_MAX_TID; i++) {
6083 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
6084 len = asc_prt_line(cp, leftlen, " %X,", i);
6085 ASC_PRT_NEXT();
6086 }
6087 }
6088 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
6089 ASC_PRT_NEXT();
1da177e4 6090
27c868c2 6091 return totlen;
1da177e4
LT
6092}
6093
6094/*
6095 * Display Wide Board BIOS Information.
6096 */
27c868c2 6097static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6098{
27c868c2
MW
6099 asc_board_t *boardp;
6100 int leftlen;
6101 int totlen;
6102 int len;
6103 ushort major, minor, letter;
6104
6105 boardp = ASC_BOARDP(shost);
6106 leftlen = cplen;
6107 totlen = len = 0;
6108
6109 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
6110 ASC_PRT_NEXT();
6111
6112 /*
6113 * If the BIOS saved a valid signature, then fill in
6114 * the BIOS code segment base address.
6115 */
6116 if (boardp->bios_signature != 0x55AA) {
6117 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
6118 ASC_PRT_NEXT();
6119 len = asc_prt_line(cp, leftlen,
6120 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
6121 ASC_PRT_NEXT();
6122 len = asc_prt_line(cp, leftlen,
6123 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
6124 ASC_PRT_NEXT();
6125 } else {
6126 major = (boardp->bios_version >> 12) & 0xF;
6127 minor = (boardp->bios_version >> 8) & 0xF;
6128 letter = (boardp->bios_version & 0xFF);
1da177e4 6129
27c868c2
MW
6130 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
6131 major, minor,
6132 letter >= 26 ? '?' : letter + 'A');
6133 ASC_PRT_NEXT();
1da177e4 6134
27c868c2
MW
6135 /*
6136 * Current available ROM BIOS release is 3.1I for UW
6137 * and 3.2I for U2W. This code doesn't differentiate
6138 * UW and U2W boards.
6139 */
6140 if (major < 3 || (major <= 3 && minor < 1) ||
6141 (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
6142 len = asc_prt_line(cp, leftlen,
6143 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
6144 ASC_PRT_NEXT();
6145 len = asc_prt_line(cp, leftlen,
6146 "ftp://ftp.connectcom.net/pub\n");
6147 ASC_PRT_NEXT();
6148 }
6149 }
1da177e4 6150
27c868c2 6151 return totlen;
1da177e4
LT
6152}
6153
6154/*
6155 * Add serial number to information bar if signature AAh
6156 * is found in at bit 15-9 (7 bits) of word 1.
6157 *
6158 * Serial Number consists fo 12 alpha-numeric digits.
6159 *
6160 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
6161 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
6162 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
6163 * 5 - Product revision (A-J) Word0: " "
6164 *
6165 * Signature Word1: 15-9 (7 bits)
6166 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
6167 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
6168 *
6169 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
6170 *
6171 * Note 1: Only production cards will have a serial number.
6172 *
6173 * Note 2: Signature is most significant 7 bits (0xFE).
6174 *
6175 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
6176 */
27c868c2 6177static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
1da177e4 6178{
27c868c2
MW
6179 ushort w, num;
6180
6181 if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
6182 return ASC_FALSE;
6183 } else {
6184 /*
6185 * First word - 6 digits.
6186 */
6187 w = serialnum[0];
6188
6189 /* Product type - 1st digit. */
6190 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
6191 /* Product type is P=Prototype */
6192 *cp += 0x8;
6193 }
6194 cp++;
6195
6196 /* Manufacturing location - 2nd digit. */
6197 *cp++ = 'A' + ((w & 0x1C00) >> 10);
6198
6199 /* Product ID - 3rd, 4th digits. */
6200 num = w & 0x3FF;
6201 *cp++ = '0' + (num / 100);
6202 num %= 100;
6203 *cp++ = '0' + (num / 10);
6204
6205 /* Product revision - 5th digit. */
6206 *cp++ = 'A' + (num % 10);
6207
6208 /*
6209 * Second word
6210 */
6211 w = serialnum[1];
6212
6213 /*
6214 * Year - 6th digit.
6215 *
6216 * If bit 15 of third word is set, then the
6217 * last digit of the year is greater than 7.
6218 */
6219 if (serialnum[2] & 0x8000) {
6220 *cp++ = '8' + ((w & 0x1C0) >> 6);
6221 } else {
6222 *cp++ = '0' + ((w & 0x1C0) >> 6);
6223 }
6224
6225 /* Week of year - 7th, 8th digits. */
6226 num = w & 0x003F;
6227 *cp++ = '0' + num / 10;
6228 num %= 10;
6229 *cp++ = '0' + num;
6230
6231 /*
6232 * Third word
6233 */
6234 w = serialnum[2] & 0x7FFF;
6235
6236 /* Serial number - 9th digit. */
6237 *cp++ = 'A' + (w / 1000);
6238
6239 /* 10th, 11th, 12th digits. */
6240 num = w % 1000;
6241 *cp++ = '0' + num / 100;
6242 num %= 100;
6243 *cp++ = '0' + num / 10;
6244 num %= 10;
6245 *cp++ = '0' + num;
6246
6247 *cp = '\0'; /* Null Terminate the string. */
6248 return ASC_TRUE;
6249 }
1da177e4
LT
6250}
6251
6252/*
6253 * asc_prt_asc_board_eeprom()
6254 *
6255 * Print board EEPROM configuration.
6256 *
6257 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6258 * cf. asc_prt_line().
6259 *
6260 * Return the number of characters copied into 'cp'. No more than
6261 * 'cplen' characters will be copied to 'cp'.
6262 */
27c868c2 6263static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6264{
27c868c2
MW
6265 asc_board_t *boardp;
6266 ASC_DVC_VAR *asc_dvc_varp;
6267 int leftlen;
6268 int totlen;
6269 int len;
6270 ASCEEP_CONFIG *ep;
6271 int i;
1da177e4 6272#ifdef CONFIG_ISA
27c868c2 6273 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
1da177e4 6274#endif /* CONFIG_ISA */
27c868c2
MW
6275 uchar serialstr[13];
6276
6277 boardp = ASC_BOARDP(shost);
6278 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6279 ep = &boardp->eep_config.asc_eep;
6280
6281 leftlen = cplen;
6282 totlen = len = 0;
6283
6284 len = asc_prt_line(cp, leftlen,
6285 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6286 shost->host_no);
6287 ASC_PRT_NEXT();
6288
6289 if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
6290 == ASC_TRUE) {
6291 len =
6292 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6293 serialstr);
6294 ASC_PRT_NEXT();
6295 } else {
6296 if (ep->adapter_info[5] == 0xBB) {
6297 len = asc_prt_line(cp, leftlen,
6298 " Default Settings Used for EEPROM-less Adapter.\n");
6299 ASC_PRT_NEXT();
6300 } else {
6301 len = asc_prt_line(cp, leftlen,
6302 " Serial Number Signature Not Present.\n");
6303 ASC_PRT_NEXT();
6304 }
6305 }
1da177e4 6306
27c868c2
MW
6307 len = asc_prt_line(cp, leftlen,
6308 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6309 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
6310 ep->max_tag_qng);
6311 ASC_PRT_NEXT();
6312
6313 len = asc_prt_line(cp, leftlen,
6314 " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
6315 ASC_PRT_NEXT();
6316
6317 len = asc_prt_line(cp, leftlen, " Target ID: ");
6318 ASC_PRT_NEXT();
6319 for (i = 0; i <= ASC_MAX_TID; i++) {
6320 len = asc_prt_line(cp, leftlen, " %d", i);
6321 ASC_PRT_NEXT();
6322 }
6323 len = asc_prt_line(cp, leftlen, "\n");
6324 ASC_PRT_NEXT();
6325
6326 len = asc_prt_line(cp, leftlen, " Disconnects: ");
6327 ASC_PRT_NEXT();
6328 for (i = 0; i <= ASC_MAX_TID; i++) {
6329 len = asc_prt_line(cp, leftlen, " %c",
6330 (ep->
6331 disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6332 'N');
6333 ASC_PRT_NEXT();
6334 }
6335 len = asc_prt_line(cp, leftlen, "\n");
6336 ASC_PRT_NEXT();
6337
6338 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
6339 ASC_PRT_NEXT();
6340 for (i = 0; i <= ASC_MAX_TID; i++) {
6341 len = asc_prt_line(cp, leftlen, " %c",
6342 (ep->
6343 use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6344 'N');
6345 ASC_PRT_NEXT();
6346 }
6347 len = asc_prt_line(cp, leftlen, "\n");
6348 ASC_PRT_NEXT();
6349
6350 len = asc_prt_line(cp, leftlen, " Start Motor: ");
6351 ASC_PRT_NEXT();
6352 for (i = 0; i <= ASC_MAX_TID; i++) {
6353 len = asc_prt_line(cp, leftlen, " %c",
6354 (ep->
6355 start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6356 'N');
6357 ASC_PRT_NEXT();
6358 }
6359 len = asc_prt_line(cp, leftlen, "\n");
6360 ASC_PRT_NEXT();
6361
6362 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6363 ASC_PRT_NEXT();
6364 for (i = 0; i <= ASC_MAX_TID; i++) {
6365 len = asc_prt_line(cp, leftlen, " %c",
6366 (ep->
6367 init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6368 'N');
6369 ASC_PRT_NEXT();
6370 }
6371 len = asc_prt_line(cp, leftlen, "\n");
6372 ASC_PRT_NEXT();
1da177e4
LT
6373
6374#ifdef CONFIG_ISA
27c868c2
MW
6375 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
6376 len = asc_prt_line(cp, leftlen,
6377 " Host ISA DMA speed: %d MB/S\n",
6378 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
6379 ASC_PRT_NEXT();
6380 }
1da177e4
LT
6381#endif /* CONFIG_ISA */
6382
27c868c2 6383 return totlen;
1da177e4
LT
6384}
6385
6386/*
6387 * asc_prt_adv_board_eeprom()
6388 *
6389 * Print board EEPROM configuration.
6390 *
6391 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6392 * cf. asc_prt_line().
6393 *
6394 * Return the number of characters copied into 'cp'. No more than
6395 * 'cplen' characters will be copied to 'cp'.
6396 */
27c868c2 6397static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6398{
27c868c2
MW
6399 asc_board_t *boardp;
6400 ADV_DVC_VAR *adv_dvc_varp;
6401 int leftlen;
6402 int totlen;
6403 int len;
6404 int i;
6405 char *termstr;
6406 uchar serialstr[13];
6407 ADVEEP_3550_CONFIG *ep_3550 = NULL;
6408 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
6409 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
6410 ushort word;
6411 ushort *wordp;
6412 ushort sdtr_speed = 0;
6413
6414 boardp = ASC_BOARDP(shost);
6415 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6416 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6417 ep_3550 = &boardp->eep_config.adv_3550_eep;
6418 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6419 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
6420 } else {
6421 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
6422 }
1da177e4 6423
27c868c2
MW
6424 leftlen = cplen;
6425 totlen = len = 0;
1da177e4 6426
27c868c2
MW
6427 len = asc_prt_line(cp, leftlen,
6428 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6429 shost->host_no);
6430 ASC_PRT_NEXT();
1da177e4 6431
27c868c2
MW
6432 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6433 wordp = &ep_3550->serial_number_word1;
6434 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6435 wordp = &ep_38C0800->serial_number_word1;
6436 } else {
6437 wordp = &ep_38C1600->serial_number_word1;
6438 }
1da177e4 6439
27c868c2
MW
6440 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
6441 len =
6442 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6443 serialstr);
6444 ASC_PRT_NEXT();
6445 } else {
6446 len = asc_prt_line(cp, leftlen,
6447 " Serial Number Signature Not Present.\n");
6448 ASC_PRT_NEXT();
6449 }
1da177e4 6450
27c868c2
MW
6451 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6452 len = asc_prt_line(cp, leftlen,
6453 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6454 ep_3550->adapter_scsi_id,
6455 ep_3550->max_host_qng, ep_3550->max_dvc_qng);
6456 ASC_PRT_NEXT();
6457 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6458 len = asc_prt_line(cp, leftlen,
6459 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6460 ep_38C0800->adapter_scsi_id,
6461 ep_38C0800->max_host_qng,
6462 ep_38C0800->max_dvc_qng);
6463 ASC_PRT_NEXT();
6464 } else {
6465 len = asc_prt_line(cp, leftlen,
6466 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6467 ep_38C1600->adapter_scsi_id,
6468 ep_38C1600->max_host_qng,
6469 ep_38C1600->max_dvc_qng);
6470 ASC_PRT_NEXT();
6471 }
6472 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6473 word = ep_3550->termination;
6474 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6475 word = ep_38C0800->termination_lvd;
6476 } else {
6477 word = ep_38C1600->termination_lvd;
6478 }
6479 switch (word) {
6480 case 1:
6481 termstr = "Low Off/High Off";
6482 break;
6483 case 2:
6484 termstr = "Low Off/High On";
6485 break;
6486 case 3:
6487 termstr = "Low On/High On";
6488 break;
6489 default:
6490 case 0:
6491 termstr = "Automatic";
6492 break;
6493 }
1da177e4 6494
27c868c2
MW
6495 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6496 len = asc_prt_line(cp, leftlen,
6497 " termination: %u (%s), bios_ctrl: 0x%x\n",
6498 ep_3550->termination, termstr,
6499 ep_3550->bios_ctrl);
6500 ASC_PRT_NEXT();
6501 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6502 len = asc_prt_line(cp, leftlen,
6503 " termination: %u (%s), bios_ctrl: 0x%x\n",
6504 ep_38C0800->termination_lvd, termstr,
6505 ep_38C0800->bios_ctrl);
6506 ASC_PRT_NEXT();
6507 } else {
6508 len = asc_prt_line(cp, leftlen,
6509 " termination: %u (%s), bios_ctrl: 0x%x\n",
6510 ep_38C1600->termination_lvd, termstr,
6511 ep_38C1600->bios_ctrl);
6512 ASC_PRT_NEXT();
6513 }
1da177e4 6514
27c868c2
MW
6515 len = asc_prt_line(cp, leftlen, " Target ID: ");
6516 ASC_PRT_NEXT();
6517 for (i = 0; i <= ADV_MAX_TID; i++) {
6518 len = asc_prt_line(cp, leftlen, " %X", i);
6519 ASC_PRT_NEXT();
6520 }
6521 len = asc_prt_line(cp, leftlen, "\n");
6522 ASC_PRT_NEXT();
1da177e4 6523
27c868c2
MW
6524 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6525 word = ep_3550->disc_enable;
6526 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6527 word = ep_38C0800->disc_enable;
6528 } else {
6529 word = ep_38C1600->disc_enable;
6530 }
6531 len = asc_prt_line(cp, leftlen, " Disconnects: ");
6532 ASC_PRT_NEXT();
6533 for (i = 0; i <= ADV_MAX_TID; i++) {
6534 len = asc_prt_line(cp, leftlen, " %c",
6535 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6536 ASC_PRT_NEXT();
6537 }
6538 len = asc_prt_line(cp, leftlen, "\n");
6539 ASC_PRT_NEXT();
1da177e4 6540
27c868c2
MW
6541 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6542 word = ep_3550->tagqng_able;
6543 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6544 word = ep_38C0800->tagqng_able;
6545 } else {
6546 word = ep_38C1600->tagqng_able;
6547 }
6548 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
6549 ASC_PRT_NEXT();
6550 for (i = 0; i <= ADV_MAX_TID; i++) {
6551 len = asc_prt_line(cp, leftlen, " %c",
6552 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6553 ASC_PRT_NEXT();
6554 }
6555 len = asc_prt_line(cp, leftlen, "\n");
6556 ASC_PRT_NEXT();
6557
6558 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6559 word = ep_3550->start_motor;
6560 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6561 word = ep_38C0800->start_motor;
6562 } else {
6563 word = ep_38C1600->start_motor;
6564 }
6565 len = asc_prt_line(cp, leftlen, " Start Motor: ");
6566 ASC_PRT_NEXT();
6567 for (i = 0; i <= ADV_MAX_TID; i++) {
6568 len = asc_prt_line(cp, leftlen, " %c",
6569 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6570 ASC_PRT_NEXT();
6571 }
6572 len = asc_prt_line(cp, leftlen, "\n");
6573 ASC_PRT_NEXT();
6574
6575 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6576 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6577 ASC_PRT_NEXT();
6578 for (i = 0; i <= ADV_MAX_TID; i++) {
6579 len = asc_prt_line(cp, leftlen, " %c",
6580 (ep_3550->
6581 sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
6582 'Y' : 'N');
6583 ASC_PRT_NEXT();
6584 }
6585 len = asc_prt_line(cp, leftlen, "\n");
6586 ASC_PRT_NEXT();
6587 }
6588
6589 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6590 len = asc_prt_line(cp, leftlen, " Ultra Transfer: ");
6591 ASC_PRT_NEXT();
6592 for (i = 0; i <= ADV_MAX_TID; i++) {
6593 len = asc_prt_line(cp, leftlen, " %c",
6594 (ep_3550->
6595 ultra_able & ADV_TID_TO_TIDMASK(i))
6596 ? 'Y' : 'N');
6597 ASC_PRT_NEXT();
6598 }
6599 len = asc_prt_line(cp, leftlen, "\n");
6600 ASC_PRT_NEXT();
6601 }
6602
6603 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6604 word = ep_3550->wdtr_able;
6605 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6606 word = ep_38C0800->wdtr_able;
6607 } else {
6608 word = ep_38C1600->wdtr_able;
6609 }
6610 len = asc_prt_line(cp, leftlen, " Wide Transfer: ");
6611 ASC_PRT_NEXT();
6612 for (i = 0; i <= ADV_MAX_TID; i++) {
6613 len = asc_prt_line(cp, leftlen, " %c",
6614 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6615 ASC_PRT_NEXT();
6616 }
6617 len = asc_prt_line(cp, leftlen, "\n");
6618 ASC_PRT_NEXT();
6619
6620 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
6621 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
6622 len = asc_prt_line(cp, leftlen,
6623 " Synchronous Transfer Speed (Mhz):\n ");
6624 ASC_PRT_NEXT();
6625 for (i = 0; i <= ADV_MAX_TID; i++) {
6626 char *speed_str;
6627
6628 if (i == 0) {
6629 sdtr_speed = adv_dvc_varp->sdtr_speed1;
6630 } else if (i == 4) {
6631 sdtr_speed = adv_dvc_varp->sdtr_speed2;
6632 } else if (i == 8) {
6633 sdtr_speed = adv_dvc_varp->sdtr_speed3;
6634 } else if (i == 12) {
6635 sdtr_speed = adv_dvc_varp->sdtr_speed4;
6636 }
6637 switch (sdtr_speed & ADV_MAX_TID) {
6638 case 0:
6639 speed_str = "Off";
6640 break;
6641 case 1:
6642 speed_str = " 5";
6643 break;
6644 case 2:
6645 speed_str = " 10";
6646 break;
6647 case 3:
6648 speed_str = " 20";
6649 break;
6650 case 4:
6651 speed_str = " 40";
6652 break;
6653 case 5:
6654 speed_str = " 80";
6655 break;
6656 default:
6657 speed_str = "Unk";
6658 break;
6659 }
6660 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
6661 ASC_PRT_NEXT();
6662 if (i == 7) {
6663 len = asc_prt_line(cp, leftlen, "\n ");
6664 ASC_PRT_NEXT();
6665 }
6666 sdtr_speed >>= 4;
6667 }
6668 len = asc_prt_line(cp, leftlen, "\n");
6669 ASC_PRT_NEXT();
6670 }
6671
6672 return totlen;
6673}
6674
6675/*
6676 * asc_prt_driver_conf()
6677 *
6678 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6679 * cf. asc_prt_line().
1da177e4
LT
6680 *
6681 * Return the number of characters copied into 'cp'. No more than
6682 * 'cplen' characters will be copied to 'cp'.
6683 */
27c868c2 6684static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6685{
27c868c2
MW
6686 asc_board_t *boardp;
6687 int leftlen;
6688 int totlen;
6689 int len;
6690 int chip_scsi_id;
6691
6692 boardp = ASC_BOARDP(shost);
6693
6694 leftlen = cplen;
6695 totlen = len = 0;
6696
6697 len = asc_prt_line(cp, leftlen,
6698 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
6699 shost->host_no);
6700 ASC_PRT_NEXT();
6701
6702 len = asc_prt_line(cp, leftlen,
6703 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
6704 shost->host_busy, shost->last_reset, shost->max_id,
6705 shost->max_lun, shost->max_channel);
6706 ASC_PRT_NEXT();
6707
6708 len = asc_prt_line(cp, leftlen,
6709 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
6710 shost->unique_id, shost->can_queue, shost->this_id,
6711 shost->sg_tablesize, shost->cmd_per_lun);
6712 ASC_PRT_NEXT();
6713
6714 len = asc_prt_line(cp, leftlen,
6715 " unchecked_isa_dma %d, use_clustering %d\n",
6716 shost->unchecked_isa_dma, shost->use_clustering);
6717 ASC_PRT_NEXT();
6718
6719 len = asc_prt_line(cp, leftlen,
6720 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
6721 boardp->flags, boardp->last_reset, jiffies,
6722 boardp->asc_n_io_port);
6723 ASC_PRT_NEXT();
6724
6725 /* 'shost->n_io_port' may be truncated because it is only one byte. */
6726 len = asc_prt_line(cp, leftlen,
6727 " io_port 0x%x, n_io_port 0x%x\n",
6728 shost->io_port, shost->n_io_port);
6729 ASC_PRT_NEXT();
6730
6731 if (ASC_NARROW_BOARD(boardp)) {
6732 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6733 } else {
6734 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6735 }
1da177e4 6736
27c868c2 6737 return totlen;
1da177e4
LT
6738}
6739
6740/*
6741 * asc_prt_asc_board_info()
6742 *
6743 * Print dynamic board configuration information.
6744 *
6745 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6746 * cf. asc_prt_line().
6747 *
6748 * Return the number of characters copied into 'cp'. No more than
6749 * 'cplen' characters will be copied to 'cp'.
6750 */
27c868c2 6751static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6752{
27c868c2
MW
6753 asc_board_t *boardp;
6754 int chip_scsi_id;
6755 int leftlen;
6756 int totlen;
6757 int len;
6758 ASC_DVC_VAR *v;
6759 ASC_DVC_CFG *c;
6760 int i;
6761 int renegotiate = 0;
6762
6763 boardp = ASC_BOARDP(shost);
6764 v = &boardp->dvc_var.asc_dvc_var;
6765 c = &boardp->dvc_cfg.asc_dvc_cfg;
6766 chip_scsi_id = c->chip_scsi_id;
6767
6768 leftlen = cplen;
6769 totlen = len = 0;
6770
6771 len = asc_prt_line(cp, leftlen,
6772 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6773 shost->host_no);
6774 ASC_PRT_NEXT();
6775
6776 len = asc_prt_line(cp, leftlen,
6777 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
6778 c->chip_version, c->lib_version, c->lib_serial_no,
6779 c->mcode_date);
6780 ASC_PRT_NEXT();
6781
6782 len = asc_prt_line(cp, leftlen,
6783 " mcode_version 0x%x, err_code %u\n",
6784 c->mcode_version, v->err_code);
6785 ASC_PRT_NEXT();
6786
6787 /* Current number of commands waiting for the host. */
6788 len = asc_prt_line(cp, leftlen,
6789 " Total Command Pending: %d\n", v->cur_total_qng);
6790 ASC_PRT_NEXT();
6791
6792 len = asc_prt_line(cp, leftlen, " Command Queuing:");
6793 ASC_PRT_NEXT();
6794 for (i = 0; i <= ASC_MAX_TID; i++) {
6795 if ((chip_scsi_id == i) ||
6796 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6797 continue;
6798 }
6799 len = asc_prt_line(cp, leftlen, " %X:%c",
6800 i,
6801 (v->
6802 use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
6803 'Y' : 'N');
6804 ASC_PRT_NEXT();
6805 }
6806 len = asc_prt_line(cp, leftlen, "\n");
6807 ASC_PRT_NEXT();
6808
6809 /* Current number of commands waiting for a device. */
6810 len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
6811 ASC_PRT_NEXT();
6812 for (i = 0; i <= ASC_MAX_TID; i++) {
6813 if ((chip_scsi_id == i) ||
6814 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6815 continue;
6816 }
6817 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
6818 ASC_PRT_NEXT();
6819 }
6820 len = asc_prt_line(cp, leftlen, "\n");
6821 ASC_PRT_NEXT();
6822
6823 /* Current limit on number of commands that can be sent to a device. */
6824 len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
6825 ASC_PRT_NEXT();
6826 for (i = 0; i <= ASC_MAX_TID; i++) {
6827 if ((chip_scsi_id == i) ||
6828 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6829 continue;
6830 }
6831 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
6832 ASC_PRT_NEXT();
6833 }
6834 len = asc_prt_line(cp, leftlen, "\n");
6835 ASC_PRT_NEXT();
6836
6837 /* Indicate whether the device has returned queue full status. */
6838 len = asc_prt_line(cp, leftlen, " Command Queue Full:");
6839 ASC_PRT_NEXT();
6840 for (i = 0; i <= ASC_MAX_TID; i++) {
6841 if ((chip_scsi_id == i) ||
6842 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6843 continue;
6844 }
6845 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
6846 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
6847 i, boardp->queue_full_cnt[i]);
6848 } else {
6849 len = asc_prt_line(cp, leftlen, " %X:N", i);
6850 }
6851 ASC_PRT_NEXT();
6852 }
6853 len = asc_prt_line(cp, leftlen, "\n");
6854 ASC_PRT_NEXT();
6855
6856 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6857 ASC_PRT_NEXT();
6858 for (i = 0; i <= ASC_MAX_TID; i++) {
6859 if ((chip_scsi_id == i) ||
6860 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6861 continue;
6862 }
6863 len = asc_prt_line(cp, leftlen, " %X:%c",
6864 i,
6865 (v->
6866 sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6867 'N');
6868 ASC_PRT_NEXT();
6869 }
6870 len = asc_prt_line(cp, leftlen, "\n");
6871 ASC_PRT_NEXT();
6872
6873 for (i = 0; i <= ASC_MAX_TID; i++) {
6874 uchar syn_period_ix;
6875
6876 if ((chip_scsi_id == i) ||
6877 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
6878 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
6879 continue;
6880 }
6881
6882 len = asc_prt_line(cp, leftlen, " %X:", i);
6883 ASC_PRT_NEXT();
6884
6885 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
6886 len = asc_prt_line(cp, leftlen, " Asynchronous");
6887 ASC_PRT_NEXT();
6888 } else {
6889 syn_period_ix =
6890 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
6891 1);
6892
6893 len = asc_prt_line(cp, leftlen,
6894 " Transfer Period Factor: %d (%d.%d Mhz),",
6895 v->sdtr_period_tbl[syn_period_ix],
6896 250 /
6897 v->sdtr_period_tbl[syn_period_ix],
6898 ASC_TENTHS(250,
6899 v->
6900 sdtr_period_tbl
6901 [syn_period_ix]));
6902 ASC_PRT_NEXT();
6903
6904 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
6905 boardp->
6906 sdtr_data[i] & ASC_SYN_MAX_OFFSET);
6907 ASC_PRT_NEXT();
6908 }
6909
6910 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
6911 len = asc_prt_line(cp, leftlen, "*\n");
6912 renegotiate = 1;
6913 } else {
6914 len = asc_prt_line(cp, leftlen, "\n");
6915 }
6916 ASC_PRT_NEXT();
6917 }
1da177e4 6918
27c868c2
MW
6919 if (renegotiate) {
6920 len = asc_prt_line(cp, leftlen,
6921 " * = Re-negotiation pending before next command.\n");
6922 ASC_PRT_NEXT();
6923 }
1da177e4 6924
27c868c2 6925 return totlen;
1da177e4
LT
6926}
6927
6928/*
6929 * asc_prt_adv_board_info()
6930 *
6931 * Print dynamic board configuration information.
6932 *
6933 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6934 * cf. asc_prt_line().
6935 *
6936 * Return the number of characters copied into 'cp'. No more than
6937 * 'cplen' characters will be copied to 'cp'.
6938 */
27c868c2 6939static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6940{
27c868c2
MW
6941 asc_board_t *boardp;
6942 int leftlen;
6943 int totlen;
6944 int len;
6945 int i;
6946 ADV_DVC_VAR *v;
6947 ADV_DVC_CFG *c;
6948 AdvPortAddr iop_base;
6949 ushort chip_scsi_id;
6950 ushort lramword;
6951 uchar lrambyte;
6952 ushort tagqng_able;
6953 ushort sdtr_able, wdtr_able;
6954 ushort wdtr_done, sdtr_done;
6955 ushort period = 0;
6956 int renegotiate = 0;
6957
6958 boardp = ASC_BOARDP(shost);
6959 v = &boardp->dvc_var.adv_dvc_var;
6960 c = &boardp->dvc_cfg.adv_dvc_cfg;
6961 iop_base = v->iop_base;
6962 chip_scsi_id = v->chip_scsi_id;
6963
6964 leftlen = cplen;
6965 totlen = len = 0;
6966
6967 len = asc_prt_line(cp, leftlen,
6968 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6969 shost->host_no);
6970 ASC_PRT_NEXT();
6971
6972 len = asc_prt_line(cp, leftlen,
6973 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
6974 v->iop_base,
6975 AdvReadWordRegister(iop_base,
6976 IOPW_SCSI_CFG1) & CABLE_DETECT,
6977 v->err_code);
6978 ASC_PRT_NEXT();
6979
6980 len = asc_prt_line(cp, leftlen,
6981 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
6982 c->chip_version, c->lib_version, c->mcode_date,
6983 c->mcode_version);
6984 ASC_PRT_NEXT();
6985
6986 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
6987 len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
6988 ASC_PRT_NEXT();
6989 for (i = 0; i <= ADV_MAX_TID; i++) {
6990 if ((chip_scsi_id == i) ||
6991 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6992 continue;
6993 }
6994
6995 len = asc_prt_line(cp, leftlen, " %X:%c",
6996 i,
6997 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6998 'N');
6999 ASC_PRT_NEXT();
7000 }
7001 len = asc_prt_line(cp, leftlen, "\n");
7002 ASC_PRT_NEXT();
7003
7004 len = asc_prt_line(cp, leftlen, " Queue Limit:");
7005 ASC_PRT_NEXT();
7006 for (i = 0; i <= ADV_MAX_TID; i++) {
7007 if ((chip_scsi_id == i) ||
7008 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7009 continue;
7010 }
7011
7012 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
7013 lrambyte);
7014
7015 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
7016 ASC_PRT_NEXT();
7017 }
7018 len = asc_prt_line(cp, leftlen, "\n");
7019 ASC_PRT_NEXT();
7020
7021 len = asc_prt_line(cp, leftlen, " Command Pending:");
7022 ASC_PRT_NEXT();
7023 for (i = 0; i <= ADV_MAX_TID; i++) {
7024 if ((chip_scsi_id == i) ||
7025 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7026 continue;
7027 }
7028
7029 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
7030 lrambyte);
7031
7032 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
7033 ASC_PRT_NEXT();
7034 }
7035 len = asc_prt_line(cp, leftlen, "\n");
7036 ASC_PRT_NEXT();
7037
7038 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7039 len = asc_prt_line(cp, leftlen, " Wide Enabled:");
7040 ASC_PRT_NEXT();
7041 for (i = 0; i <= ADV_MAX_TID; i++) {
7042 if ((chip_scsi_id == i) ||
7043 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7044 continue;
7045 }
7046
7047 len = asc_prt_line(cp, leftlen, " %X:%c",
7048 i,
7049 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7050 'N');
7051 ASC_PRT_NEXT();
7052 }
7053 len = asc_prt_line(cp, leftlen, "\n");
7054 ASC_PRT_NEXT();
7055
7056 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
7057 len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
7058 ASC_PRT_NEXT();
7059 for (i = 0; i <= ADV_MAX_TID; i++) {
7060 if ((chip_scsi_id == i) ||
7061 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7062 continue;
7063 }
7064
7065 AdvReadWordLram(iop_base,
7066 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7067 lramword);
7068
7069 len = asc_prt_line(cp, leftlen, " %X:%d",
7070 i, (lramword & 0x8000) ? 16 : 8);
7071 ASC_PRT_NEXT();
7072
7073 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
7074 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7075 len = asc_prt_line(cp, leftlen, "*");
7076 ASC_PRT_NEXT();
7077 renegotiate = 1;
7078 }
7079 }
7080 len = asc_prt_line(cp, leftlen, "\n");
7081 ASC_PRT_NEXT();
7082
7083 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7084 len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
7085 ASC_PRT_NEXT();
7086 for (i = 0; i <= ADV_MAX_TID; i++) {
7087 if ((chip_scsi_id == i) ||
7088 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7089 continue;
7090 }
7091
7092 len = asc_prt_line(cp, leftlen, " %X:%c",
7093 i,
7094 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7095 'N');
7096 ASC_PRT_NEXT();
7097 }
7098 len = asc_prt_line(cp, leftlen, "\n");
7099 ASC_PRT_NEXT();
7100
7101 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
7102 for (i = 0; i <= ADV_MAX_TID; i++) {
7103
7104 AdvReadWordLram(iop_base,
7105 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7106 lramword);
7107 lramword &= ~0x8000;
7108
7109 if ((chip_scsi_id == i) ||
7110 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
7111 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
7112 continue;
7113 }
7114
7115 len = asc_prt_line(cp, leftlen, " %X:", i);
7116 ASC_PRT_NEXT();
7117
7118 if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */
7119 len = asc_prt_line(cp, leftlen, " Asynchronous");
7120 ASC_PRT_NEXT();
7121 } else {
7122 len =
7123 asc_prt_line(cp, leftlen,
7124 " Transfer Period Factor: ");
7125 ASC_PRT_NEXT();
7126
7127 if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */
7128 len =
7129 asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
7130 ASC_PRT_NEXT();
7131 } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */
7132 len =
7133 asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
7134 ASC_PRT_NEXT();
7135 } else { /* 20 Mhz or below. */
7136
7137 period = (((lramword >> 8) * 25) + 50) / 4;
7138
7139 if (period == 0) { /* Should never happen. */
7140 len =
7141 asc_prt_line(cp, leftlen,
7142 "%d (? Mhz), ");
7143 ASC_PRT_NEXT();
7144 } else {
7145 len = asc_prt_line(cp, leftlen,
7146 "%d (%d.%d Mhz),",
7147 period, 250 / period,
7148 ASC_TENTHS(250,
7149 period));
7150 ASC_PRT_NEXT();
7151 }
7152 }
7153
7154 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
7155 lramword & 0x1F);
7156 ASC_PRT_NEXT();
7157 }
7158
7159 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7160 len = asc_prt_line(cp, leftlen, "*\n");
7161 renegotiate = 1;
7162 } else {
7163 len = asc_prt_line(cp, leftlen, "\n");
7164 }
7165 ASC_PRT_NEXT();
7166 }
1da177e4 7167
27c868c2
MW
7168 if (renegotiate) {
7169 len = asc_prt_line(cp, leftlen,
7170 " * = Re-negotiation pending before next command.\n");
7171 ASC_PRT_NEXT();
7172 }
1da177e4 7173
27c868c2 7174 return totlen;
1da177e4
LT
7175}
7176
7177/*
7178 * asc_proc_copy()
7179 *
7180 * Copy proc information to a read buffer taking into account the current
7181 * read offset in the file and the remaining space in the read buffer.
7182 */
27c868c2 7183static int
1da177e4 7184asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
27c868c2 7185 char *cp, int cplen)
1da177e4 7186{
27c868c2
MW
7187 int cnt = 0;
7188
7189 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
7190 (unsigned)offset, (unsigned)advoffset, cplen);
7191 if (offset <= advoffset) {
7192 /* Read offset below current offset, copy everything. */
7193 cnt = min(cplen, leftlen);
7194 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7195 (ulong)curbuf, (ulong)cp, cnt);
7196 memcpy(curbuf, cp, cnt);
7197 } else if (offset < advoffset + cplen) {
7198 /* Read offset within current range, partial copy. */
7199 cnt = (advoffset + cplen) - offset;
7200 cp = (cp + cplen) - cnt;
7201 cnt = min(cnt, leftlen);
7202 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7203 (ulong)curbuf, (ulong)cp, cnt);
7204 memcpy(curbuf, cp, cnt);
7205 }
7206 return cnt;
1da177e4
LT
7207}
7208
7209/*
7210 * asc_prt_line()
7211 *
7212 * If 'cp' is NULL print to the console, otherwise print to a buffer.
7213 *
7214 * Return 0 if printing to the console, otherwise return the number of
7215 * bytes written to the buffer.
7216 *
7217 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
7218 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
7219 */
27c868c2 7220static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
1da177e4 7221{
27c868c2
MW
7222 va_list args;
7223 int ret;
7224 char s[ASC_PRTLINE_SIZE];
7225
7226 va_start(args, fmt);
7227 ret = vsprintf(s, fmt, args);
7228 ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
7229 if (buf == NULL) {
7230 (void)printk(s);
7231 ret = 0;
7232 } else {
7233 ret = min(buflen, ret);
7234 memcpy(buf, s, ret);
7235 }
7236 va_end(args);
7237 return ret;
1da177e4
LT
7238}
7239#endif /* CONFIG_PROC_FS */
7240
1da177e4
LT
7241/*
7242 * --- Functions Required by the Asc Library
7243 */
7244
7245/*
7246 * Delay for 'n' milliseconds. Don't use the 'jiffies'
7247 * global variable which is incremented once every 5 ms
7248 * from a timer interrupt, because this function may be
7249 * called when interrupts are disabled.
7250 */
27c868c2 7251static void DvcSleepMilliSecond(ADV_DCNT n)
1da177e4 7252{
27c868c2
MW
7253 ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong)n);
7254 mdelay(n);
1da177e4
LT
7255}
7256
7257/*
7258 * Currently and inline noop but leave as a placeholder.
7259 * Leave DvcEnterCritical() as a noop placeholder.
7260 */
27c868c2 7261static inline ulong DvcEnterCritical(void)
1da177e4 7262{
27c868c2 7263 return 0;
1da177e4
LT
7264}
7265
7266/*
7267 * Critical sections are all protected by the board spinlock.
7268 * Leave DvcLeaveCritical() as a noop placeholder.
7269 */
27c868c2 7270static inline void DvcLeaveCritical(ulong flags)
1da177e4 7271{
27c868c2 7272 return;
1da177e4
LT
7273}
7274
7275/*
7276 * void
7277 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7278 *
7279 * Calling/Exit State:
7280 * none
7281 *
7282 * Description:
7283 * Output an ASC_SCSI_Q structure to the chip
7284 */
27c868c2 7285static void
1da177e4
LT
7286DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7287{
27c868c2
MW
7288 int i;
7289
7290 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
7291 AscSetChipLramAddr(iop_base, s_addr);
7292 for (i = 0; i < 2 * words; i += 2) {
7293 if (i == 4 || i == 20) {
7294 continue;
7295 }
7296 outpw(iop_base + IOP_RAM_DATA,
7297 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
7298 }
1da177e4
LT
7299}
7300
7301/*
7302 * void
7303 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7304 *
7305 * Calling/Exit State:
7306 * none
7307 *
7308 * Description:
7309 * Input an ASC_QDONE_INFO structure from the chip
7310 */
27c868c2 7311static void
1da177e4
LT
7312DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7313{
27c868c2
MW
7314 int i;
7315 ushort word;
7316
7317 AscSetChipLramAddr(iop_base, s_addr);
7318 for (i = 0; i < 2 * words; i += 2) {
7319 if (i == 10) {
7320 continue;
7321 }
7322 word = inpw(iop_base + IOP_RAM_DATA);
7323 inbuf[i] = word & 0xff;
7324 inbuf[i + 1] = (word >> 8) & 0xff;
7325 }
7326 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
1da177e4
LT
7327}
7328
7329/*
7330 * Read a PCI configuration byte.
7331 */
78e77d8b 7332static uchar __devinit DvcReadPCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset)
1da177e4
LT
7333{
7334#ifdef CONFIG_PCI
27c868c2
MW
7335 uchar byte_data;
7336 pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
7337 return byte_data;
1da177e4 7338#else /* !defined(CONFIG_PCI) */
27c868c2 7339 return 0;
1da177e4
LT
7340#endif /* !defined(CONFIG_PCI) */
7341}
7342
7343/*
7344 * Write a PCI configuration byte.
7345 */
78e77d8b 7346static void __devinit
27c868c2 7347DvcWritePCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset, uchar byte_data)
1da177e4
LT
7348{
7349#ifdef CONFIG_PCI
27c868c2 7350 pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
1da177e4
LT
7351#endif /* CONFIG_PCI */
7352}
7353
7354/*
7355 * Return the BIOS address of the adapter at the specified
7356 * I/O port and with the specified bus type.
7357 */
78e77d8b 7358static ushort __devinit AscGetChipBiosAddress(PortAddr iop_base, ushort bus_type)
1da177e4 7359{
27c868c2
MW
7360 ushort cfg_lsw;
7361 ushort bios_addr;
7362
7363 /*
7364 * The PCI BIOS is re-located by the motherboard BIOS. Because
7365 * of this the driver can not determine where a PCI BIOS is
7366 * loaded and executes.
7367 */
7368 if (bus_type & ASC_IS_PCI) {
7369 return (0);
7370 }
1da177e4 7371#ifdef CONFIG_ISA
27c868c2
MW
7372 if ((bus_type & ASC_IS_EISA) != 0) {
7373 cfg_lsw = AscGetEisaChipCfg(iop_base);
7374 cfg_lsw &= 0x000F;
7375 bios_addr = (ushort)(ASC_BIOS_MIN_ADDR +
7376 (cfg_lsw * ASC_BIOS_BANK_SIZE));
7377 return (bios_addr);
7378 } /* if */
1da177e4
LT
7379#endif /* CONFIG_ISA */
7380
27c868c2 7381 cfg_lsw = AscGetChipCfgLsw(iop_base);
1da177e4 7382
27c868c2
MW
7383 /*
7384 * ISA PnP uses the top bit as the 32K BIOS flag
7385 */
7386 if (bus_type == ASC_IS_ISAPNP) {
7387 cfg_lsw &= 0x7FFF;
7388 }
7389 /* if */
7390 bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
7391 ASC_BIOS_MIN_ADDR);
7392 return (bios_addr);
1da177e4
LT
7393}
7394
1da177e4
LT
7395/*
7396 * --- Functions Required by the Adv Library
7397 */
7398
7399/*
7400 * DvcGetPhyAddr()
7401 *
7402 * Return the physical address of 'vaddr' and set '*lenp' to the
7403 * number of physically contiguous bytes that follow 'vaddr'.
7404 * 'flag' indicates the type of structure whose physical address
7405 * is being translated.
7406 *
7407 * Note: Because Linux currently doesn't page the kernel and all
7408 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
7409 */
7410ADV_PADDR
7411DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
27c868c2 7412 uchar *vaddr, ADV_SDCNT *lenp, int flag)
1da177e4 7413{
27c868c2 7414 ADV_PADDR paddr;
1da177e4 7415
27c868c2 7416 paddr = virt_to_bus(vaddr);
1da177e4 7417
27c868c2
MW
7418 ASC_DBG4(4,
7419 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
7420 (ulong)vaddr, (ulong)lenp, (ulong)*((ulong *)lenp),
7421 (ulong)paddr);
1da177e4 7422
27c868c2 7423 return paddr;
1da177e4
LT
7424}
7425
7426/*
7427 * Read a PCI configuration byte.
7428 */
78e77d8b 7429static uchar __devinit DvcAdvReadPCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset)
1da177e4
LT
7430{
7431#ifdef CONFIG_PCI
27c868c2
MW
7432 uchar byte_data;
7433 pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
7434 return byte_data;
1da177e4 7435#else /* CONFIG_PCI */
27c868c2 7436 return 0;
1da177e4
LT
7437#endif /* CONFIG_PCI */
7438}
7439
7440/*
7441 * Write a PCI configuration byte.
7442 */
78e77d8b 7443static void __devinit
27c868c2 7444DvcAdvWritePCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset, uchar byte_data)
1da177e4
LT
7445{
7446#ifdef CONFIG_PCI
27c868c2 7447 pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
1da177e4 7448#else /* CONFIG_PCI */
27c868c2 7449 return;
1da177e4
LT
7450#endif /* CONFIG_PCI */
7451}
7452
7453/*
7454 * --- Tracing and Debugging Functions
7455 */
7456
7457#ifdef ADVANSYS_STATS
7458#ifdef CONFIG_PROC_FS
7459/*
7460 * asc_prt_board_stats()
7461 *
7462 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7463 * cf. asc_prt_line().
7464 *
7465 * Return the number of characters copied into 'cp'. No more than
7466 * 'cplen' characters will be copied to 'cp'.
7467 */
27c868c2 7468static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 7469{
27c868c2
MW
7470 int leftlen;
7471 int totlen;
7472 int len;
7473 struct asc_stats *s;
7474 asc_board_t *boardp;
1da177e4 7475
27c868c2
MW
7476 leftlen = cplen;
7477 totlen = len = 0;
7478
7479 boardp = ASC_BOARDP(shost);
7480 s = &boardp->asc_stats;
7481
7482 len = asc_prt_line(cp, leftlen,
7483 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
7484 shost->host_no);
7485 ASC_PRT_NEXT();
7486
7487 len = asc_prt_line(cp, leftlen,
7488 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
7489 s->queuecommand, s->reset, s->biosparam,
7490 s->interrupt);
7491 ASC_PRT_NEXT();
7492
7493 len = asc_prt_line(cp, leftlen,
7494 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
7495 s->callback, s->done, s->build_error,
7496 s->adv_build_noreq, s->adv_build_nosg);
7497 ASC_PRT_NEXT();
7498
7499 len = asc_prt_line(cp, leftlen,
7500 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
7501 s->exe_noerror, s->exe_busy, s->exe_error,
7502 s->exe_unknown);
7503 ASC_PRT_NEXT();
7504
7505 /*
7506 * Display data transfer statistics.
7507 */
7508 if (s->cont_cnt > 0) {
7509 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
7510 ASC_PRT_NEXT();
7511
7512 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
7513 s->cont_xfer / 2,
7514 ASC_TENTHS(s->cont_xfer, 2));
7515 ASC_PRT_NEXT();
7516
7517 /* Contiguous transfer average size */
7518 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
7519 (s->cont_xfer / 2) / s->cont_cnt,
7520 ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
7521 ASC_PRT_NEXT();
7522 }
1da177e4 7523
27c868c2 7524 if (s->sg_cnt > 0) {
1da177e4 7525
27c868c2
MW
7526 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
7527 s->sg_cnt, s->sg_elem);
7528 ASC_PRT_NEXT();
1da177e4 7529
27c868c2
MW
7530 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
7531 s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
7532 ASC_PRT_NEXT();
1da177e4 7533
27c868c2
MW
7534 /* Scatter gather transfer statistics */
7535 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
7536 s->sg_elem / s->sg_cnt,
7537 ASC_TENTHS(s->sg_elem, s->sg_cnt));
7538 ASC_PRT_NEXT();
1da177e4 7539
27c868c2
MW
7540 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
7541 (s->sg_xfer / 2) / s->sg_elem,
7542 ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
7543 ASC_PRT_NEXT();
1da177e4 7544
27c868c2
MW
7545 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
7546 (s->sg_xfer / 2) / s->sg_cnt,
7547 ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
7548 ASC_PRT_NEXT();
7549 }
1da177e4 7550
27c868c2
MW
7551 /*
7552 * Display request queuing statistics.
7553 */
7554 len = asc_prt_line(cp, leftlen,
7555 " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
7556 HZ);
7557 ASC_PRT_NEXT();
1da177e4 7558
27c868c2 7559 return totlen;
1da177e4
LT
7560}
7561
7562/*
7563 * asc_prt_target_stats()
7564 *
7565 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7566 * cf. asc_prt_line().
7567 *
7568 * This is separated from asc_prt_board_stats because a full set
7569 * of targets will overflow ASC_PRTBUF_SIZE.
7570 *
7571 * Return the number of characters copied into 'cp'. No more than
7572 * 'cplen' characters will be copied to 'cp'.
7573 */
27c868c2
MW
7574static int
7575asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen)
1da177e4 7576{
27c868c2
MW
7577 int leftlen;
7578 int totlen;
7579 int len;
7580 struct asc_stats *s;
7581 ushort chip_scsi_id;
7582 asc_board_t *boardp;
7583 asc_queue_t *active;
7584 asc_queue_t *waiting;
1da177e4 7585
27c868c2
MW
7586 leftlen = cplen;
7587 totlen = len = 0;
7588
7589 boardp = ASC_BOARDP(shost);
7590 s = &boardp->asc_stats;
7591
7592 active = &ASC_BOARDP(shost)->active;
7593 waiting = &ASC_BOARDP(shost)->waiting;
7594
7595 if (ASC_NARROW_BOARD(boardp)) {
7596 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7597 } else {
7598 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7599 }
7600
7601 if ((chip_scsi_id == tgt_id) ||
7602 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
7603 return 0;
7604 }
1da177e4 7605
27c868c2
MW
7606 do {
7607 if (active->q_tot_cnt[tgt_id] > 0
7608 || waiting->q_tot_cnt[tgt_id] > 0) {
7609 len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
7610 ASC_PRT_NEXT();
7611
7612 len = asc_prt_line(cp, leftlen,
7613 " active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
7614 active->q_cur_cnt[tgt_id],
7615 active->q_max_cnt[tgt_id],
7616 active->q_tot_cnt[tgt_id],
7617 active->q_min_tim[tgt_id],
7618 active->q_max_tim[tgt_id],
7619 (active->q_tot_cnt[tgt_id] ==
7620 0) ? 0 : (active->
7621 q_tot_tim[tgt_id] /
7622 active->
7623 q_tot_cnt[tgt_id]),
7624 (active->q_tot_cnt[tgt_id] ==
7625 0) ? 0 : ASC_TENTHS(active->
7626 q_tot_tim
7627 [tgt_id],
7628 active->
7629 q_tot_cnt
7630 [tgt_id]));
7631 ASC_PRT_NEXT();
7632
7633 len = asc_prt_line(cp, leftlen,
7634 " waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
7635 waiting->q_cur_cnt[tgt_id],
7636 waiting->q_max_cnt[tgt_id],
7637 waiting->q_tot_cnt[tgt_id],
7638 waiting->q_min_tim[tgt_id],
7639 waiting->q_max_tim[tgt_id],
7640 (waiting->q_tot_cnt[tgt_id] ==
7641 0) ? 0 : (waiting->
7642 q_tot_tim[tgt_id] /
7643 waiting->
7644 q_tot_cnt[tgt_id]),
7645 (waiting->q_tot_cnt[tgt_id] ==
7646 0) ? 0 : ASC_TENTHS(waiting->
7647 q_tot_tim
7648 [tgt_id],
7649 waiting->
7650 q_tot_cnt
7651 [tgt_id]));
7652 ASC_PRT_NEXT();
7653 }
7654 } while (0);
7655
7656 return totlen;
1da177e4
LT
7657}
7658#endif /* CONFIG_PROC_FS */
7659#endif /* ADVANSYS_STATS */
7660
7661#ifdef ADVANSYS_DEBUG
7662/*
7663 * asc_prt_scsi_host()
7664 */
27c868c2 7665static void asc_prt_scsi_host(struct Scsi_Host *s)
1da177e4 7666{
27c868c2
MW
7667 asc_board_t *boardp;
7668
7669 boardp = ASC_BOARDP(s);
7670
7671 printk("Scsi_Host at addr 0x%lx\n", (ulong)s);
7672 printk(" host_busy %u, host_no %d, last_reset %d,\n",
7673 s->host_busy, s->host_no, (unsigned)s->last_reset);
7674
7675 printk(" base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
7676 (ulong)s->base, (ulong)s->io_port, s->n_io_port, s->irq);
7677
7678 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
7679 s->dma_channel, s->this_id, s->can_queue);
7680
7681 printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
7682 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
7683
7684 if (ASC_NARROW_BOARD(boardp)) {
7685 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
7686 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
7687 } else {
7688 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
7689 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
7690 }
1da177e4
LT
7691}
7692
7693/*
7694 * asc_prt_scsi_cmnd()
7695 */
27c868c2 7696static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
1da177e4 7697{
27c868c2 7698 printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s);
1da177e4 7699
27c868c2
MW
7700 printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
7701 (ulong)s->device->host, (ulong)s->device, s->device->id,
7702 s->device->lun, s->device->channel);
1da177e4 7703
27c868c2 7704 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
1da177e4 7705
27c868c2
MW
7706 printk("sc_data_direction %u, resid %d\n",
7707 s->sc_data_direction, s->resid);
1da177e4 7708
27c868c2 7709 printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len);
1da177e4 7710
27c868c2
MW
7711 printk(" serial_number 0x%x, retries %d, allowed %d\n",
7712 (unsigned)s->serial_number, s->retries, s->allowed);
1da177e4 7713
27c868c2 7714 printk(" timeout_per_command %d\n", s->timeout_per_command);
1da177e4 7715
27c868c2
MW
7716 printk
7717 (" scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
7718 (ulong)s->scsi_done, (ulong)s->done, (ulong)s->host_scribble,
7719 s->result);
1da177e4 7720
27c868c2 7721 printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
1da177e4
LT
7722}
7723
7724/*
7725 * asc_prt_asc_dvc_var()
7726 */
27c868c2 7727static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
1da177e4 7728{
27c868c2
MW
7729 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
7730
7731 printk
7732 (" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n",
7733 h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
7734
7735 printk
7736 (" bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n",
7737 h->bus_type, (ulong)h->isr_callback, (ulong)h->exe_callback,
7738 (unsigned)h->init_sdtr);
7739
7740 printk
7741 (" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n",
7742 (unsigned)h->sdtr_done, (unsigned)h->use_tagged_qng,
7743 (unsigned)h->unit_not_ready, (unsigned)h->chip_no);
7744
7745 printk
7746 (" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n",
7747 (unsigned)h->queue_full_or_busy, (unsigned)h->start_motor,
7748 (unsigned)h->scsi_reset_wait);
7749
7750 printk
7751 (" is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n",
7752 (unsigned)h->is_in_int, (unsigned)h->max_total_qng,
7753 (unsigned)h->cur_total_qng, (unsigned)h->in_critical_cnt);
7754
7755 printk
7756 (" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n",
7757 (unsigned)h->last_q_shortage, (unsigned)h->init_state,
7758 (unsigned)h->no_scam, (unsigned)h->pci_fix_asyn_xfer);
7759
7760 printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no);
1da177e4
LT
7761}
7762
7763/*
7764 * asc_prt_asc_dvc_cfg()
7765 */
27c868c2 7766static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
1da177e4 7767{
27c868c2
MW
7768 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
7769
7770 printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
7771 h->can_tagged_qng, h->cmd_qng_enabled);
7772 printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
7773 h->disc_enable, h->sdtr_enable);
7774
7775 printk
7776 (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
7777 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
7778 h->chip_version);
7779
7780 printk
7781 (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
7782 to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
7783 h->mcode_date);
7784
7785 printk(" mcode_version %d, overrun_buf 0x%lx\n",
7786 h->mcode_version, (ulong)h->overrun_buf);
1da177e4
LT
7787}
7788
7789/*
7790 * asc_prt_asc_scsi_q()
7791 */
27c868c2 7792static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
1da177e4 7793{
27c868c2
MW
7794 ASC_SG_HEAD *sgp;
7795 int i;
7796
7797 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
7798
7799 printk
7800 (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
7801 q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
7802 q->q2.tag_code);
7803
7804 printk
7805 (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7806 (ulong)le32_to_cpu(q->q1.data_addr),
7807 (ulong)le32_to_cpu(q->q1.data_cnt),
7808 (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
7809
7810 printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
7811 (ulong)q->cdbptr, q->q2.cdb_len,
7812 (ulong)q->sg_head, q->q1.sg_queue_cnt);
7813
7814 if (q->sg_head) {
7815 sgp = q->sg_head;
7816 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
7817 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
7818 sgp->queue_cnt);
7819 for (i = 0; i < sgp->entry_cnt; i++) {
7820 printk(" [%u]: addr 0x%lx, bytes %lu\n",
7821 i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
7822 (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
7823 }
1da177e4 7824
27c868c2 7825 }
1da177e4
LT
7826}
7827
7828/*
7829 * asc_prt_asc_qdone_info()
7830 */
27c868c2 7831static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
1da177e4 7832{
27c868c2
MW
7833 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
7834 printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
7835 (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
7836 q->d2.tag_code);
7837 printk
7838 (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
7839 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
1da177e4
LT
7840}
7841
7842/*
7843 * asc_prt_adv_dvc_var()
7844 *
7845 * Display an ADV_DVC_VAR structure.
7846 */
27c868c2 7847static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
1da177e4 7848{
27c868c2
MW
7849 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
7850
7851 printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
7852 (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
7853
7854 printk(" isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
7855 (ulong)h->isr_callback, (unsigned)h->sdtr_able,
7856 (unsigned)h->wdtr_able);
7857
7858 printk(" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
7859 (unsigned)h->start_motor,
7860 (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no);
7861
7862 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
7863 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
7864 (ulong)h->carr_freelist);
7865
7866 printk(" icq_sp 0x%lx, irq_sp 0x%lx\n",
7867 (ulong)h->icq_sp, (ulong)h->irq_sp);
7868
7869 printk(" no_scam 0x%x, tagqng_able 0x%x\n",
7870 (unsigned)h->no_scam, (unsigned)h->tagqng_able);
7871
7872 printk(" chip_scsi_id 0x%x, cfg 0x%lx\n",
7873 (unsigned)h->chip_scsi_id, (ulong)h->cfg);
1da177e4
LT
7874}
7875
7876/*
7877 * asc_prt_adv_dvc_cfg()
7878 *
7879 * Display an ADV_DVC_CFG structure.
7880 */
27c868c2 7881static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
1da177e4 7882{
27c868c2 7883 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
1da177e4 7884
27c868c2
MW
7885 printk(" disc_enable 0x%x, termination 0x%x\n",
7886 h->disc_enable, h->termination);
1da177e4 7887
27c868c2
MW
7888 printk(" chip_version 0x%x, mcode_date 0x%x\n",
7889 h->chip_version, h->mcode_date);
1da177e4 7890
27c868c2
MW
7891 printk(" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
7892 h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
1da177e4 7893
27c868c2
MW
7894 printk(" control_flag 0x%x, pci_slot_info 0x%x\n",
7895 h->control_flag, h->pci_slot_info);
1da177e4
LT
7896}
7897
7898/*
7899 * asc_prt_adv_scsi_req_q()
7900 *
7901 * Display an ADV_SCSI_REQ_Q structure.
7902 */
27c868c2 7903static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
1da177e4 7904{
27c868c2
MW
7905 int sg_blk_cnt;
7906 struct asc_sg_block *sg_ptr;
7907
7908 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
7909
7910 printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
7911 q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
7912
7913 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
7914 q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
7915
7916 printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7917 (ulong)le32_to_cpu(q->data_cnt),
7918 (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
7919
7920 printk
7921 (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
7922 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
7923
7924 printk(" sg_working_ix 0x%x, target_cmd %u\n",
7925 q->sg_working_ix, q->target_cmd);
7926
7927 printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
7928 (ulong)le32_to_cpu(q->scsiq_rptr),
7929 (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
7930
7931 /* Display the request's ADV_SG_BLOCK structures. */
7932 if (q->sg_list_ptr != NULL) {
7933 sg_blk_cnt = 0;
7934 while (1) {
7935 /*
7936 * 'sg_ptr' is a physical address. Convert it to a virtual
7937 * address by indexing 'sg_blk_cnt' into the virtual address
7938 * array 'sg_list_ptr'.
7939 *
7940 * XXX - Assumes all SG physical blocks are virtually contiguous.
7941 */
7942 sg_ptr =
7943 &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
7944 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
7945 if (sg_ptr->sg_ptr == 0) {
7946 break;
7947 }
7948 sg_blk_cnt++;
7949 }
7950 }
1da177e4
LT
7951}
7952
7953/*
7954 * asc_prt_adv_sgblock()
7955 *
7956 * Display an ADV_SG_BLOCK structure.
7957 */
27c868c2 7958static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
1da177e4 7959{
27c868c2
MW
7960 int i;
7961
7962 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
7963 (ulong)b, sgblockno);
7964 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
7965 b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
7966 ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
7967 if (b->sg_ptr != 0) {
7968 ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
7969 }
7970 for (i = 0; i < b->sg_cnt; i++) {
7971 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
7972 i, (ulong)b->sg_list[i].sg_addr,
7973 (ulong)b->sg_list[i].sg_count);
7974 }
1da177e4
LT
7975}
7976
7977/*
7978 * asc_prt_hex()
7979 *
7980 * Print hexadecimal output in 4 byte groupings 32 bytes
7981 * or 8 double-words per line.
7982 */
27c868c2 7983static void asc_prt_hex(char *f, uchar *s, int l)
1da177e4 7984{
27c868c2
MW
7985 int i;
7986 int j;
7987 int k;
7988 int m;
7989
7990 printk("%s: (%d bytes)\n", f, l);
7991
7992 for (i = 0; i < l; i += 32) {
7993
7994 /* Display a maximum of 8 double-words per line. */
7995 if ((k = (l - i) / 4) >= 8) {
7996 k = 8;
7997 m = 0;
7998 } else {
7999 m = (l - i) % 4;
8000 }
8001
8002 for (j = 0; j < k; j++) {
8003 printk(" %2.2X%2.2X%2.2X%2.2X",
8004 (unsigned)s[i + (j * 4)],
8005 (unsigned)s[i + (j * 4) + 1],
8006 (unsigned)s[i + (j * 4) + 2],
8007 (unsigned)s[i + (j * 4) + 3]);
8008 }
8009
8010 switch (m) {
8011 case 0:
8012 default:
8013 break;
8014 case 1:
8015 printk(" %2.2X", (unsigned)s[i + (j * 4)]);
8016 break;
8017 case 2:
8018 printk(" %2.2X%2.2X",
8019 (unsigned)s[i + (j * 4)],
8020 (unsigned)s[i + (j * 4) + 1]);
8021 break;
8022 case 3:
8023 printk(" %2.2X%2.2X%2.2X",
8024 (unsigned)s[i + (j * 4) + 1],
8025 (unsigned)s[i + (j * 4) + 2],
8026 (unsigned)s[i + (j * 4) + 3]);
8027 break;
8028 }
8029
8030 printk("\n");
8031 }
1da177e4
LT
8032}
8033#endif /* ADVANSYS_DEBUG */
8034
8035/*
8036 * --- Asc Library Functions
8037 */
8038
78e77d8b 8039static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
1da177e4 8040{
27c868c2 8041 PortAddr eisa_cfg_iop;
1da177e4 8042
27c868c2
MW
8043 eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8044 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
8045 return (inpw(eisa_cfg_iop));
1da177e4
LT
8046}
8047
78e77d8b 8048static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
1da177e4 8049{
27c868c2 8050 ushort cfg_lsw;
1da177e4 8051
27c868c2
MW
8052 if (AscGetChipScsiID(iop_base) == new_host_id) {
8053 return (new_host_id);
8054 }
8055 cfg_lsw = AscGetChipCfgLsw(iop_base);
8056 cfg_lsw &= 0xF8FF;
8057 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
8058 AscSetChipCfgLsw(iop_base, cfg_lsw);
8059 return (AscGetChipScsiID(iop_base));
1da177e4
LT
8060}
8061
78e77d8b 8062static uchar __devinit AscGetChipScsiCtrl(PortAddr iop_base)
1da177e4 8063{
27c868c2 8064 uchar sc;
1da177e4 8065
27c868c2
MW
8066 AscSetBank(iop_base, 1);
8067 sc = inp(iop_base + IOP_REG_SC);
8068 AscSetBank(iop_base, 0);
8069 return (sc);
1da177e4
LT
8070}
8071
78e77d8b 8072static uchar __devinit AscGetChipVersion(PortAddr iop_base, ushort bus_type)
1da177e4 8073{
27c868c2
MW
8074 if ((bus_type & ASC_IS_EISA) != 0) {
8075 PortAddr eisa_iop;
8076 uchar revision;
8077 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8078 (PortAddr) ASC_EISA_REV_IOP_MASK;
8079 revision = inp(eisa_iop);
8080 return ((uchar)((ASC_CHIP_MIN_VER_EISA - 1) + revision));
8081 }
8082 return (AscGetChipVerNo(iop_base));
1da177e4
LT
8083}
8084
78e77d8b 8085static ushort __devinit AscGetChipBusType(PortAddr iop_base)
1da177e4 8086{
27c868c2
MW
8087 ushort chip_ver;
8088
8089 chip_ver = AscGetChipVerNo(iop_base);
8090 if ((chip_ver >= ASC_CHIP_MIN_VER_VL)
8091 && (chip_ver <= ASC_CHIP_MAX_VER_VL)
8092 ) {
8093 if (((iop_base & 0x0C30) == 0x0C30)
8094 || ((iop_base & 0x0C50) == 0x0C50)
8095 ) {
8096 return (ASC_IS_EISA);
8097 }
8098 return (ASC_IS_VL);
8099 }
8100 if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
8101 (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
8102 if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
8103 return (ASC_IS_ISAPNP);
8104 }
8105 return (ASC_IS_ISA);
8106 } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
8107 (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
8108 return (ASC_IS_PCI);
8109 }
8110 return (0);
1da177e4
LT
8111}
8112
27c868c2
MW
8113static ASC_DCNT
8114AscLoadMicroCode(PortAddr iop_base,
8115 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
1da177e4 8116{
27c868c2
MW
8117 ASC_DCNT chksum;
8118 ushort mcode_word_size;
8119 ushort mcode_chksum;
8120
8121 /* Write the microcode buffer starting at LRAM address 0. */
8122 mcode_word_size = (ushort)(mcode_size >> 1);
8123 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
8124 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
8125
8126 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
8127 ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum);
8128 mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
8129 (ushort)ASC_CODE_SEC_BEG,
8130 (ushort)((mcode_size -
8131 s_addr - (ushort)
8132 ASC_CODE_SEC_BEG) /
8133 2));
8134 ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
8135 (ulong)mcode_chksum);
8136 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
8137 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
8138 return (chksum);
1da177e4
LT
8139}
8140
27c868c2 8141static int AscFindSignature(PortAddr iop_base)
1da177e4 8142{
27c868c2
MW
8143 ushort sig_word;
8144
8145 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
8146 iop_base, AscGetChipSignatureByte(iop_base));
8147 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
8148 ASC_DBG2(1,
8149 "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
8150 iop_base, AscGetChipSignatureWord(iop_base));
8151 sig_word = AscGetChipSignatureWord(iop_base);
8152 if ((sig_word == (ushort)ASC_1000_ID0W) ||
8153 (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
8154 return (1);
8155 }
8156 }
8157 return (0);
1da177e4
LT
8158}
8159
78e77d8b 8160static void __devinit AscToggleIRQAct(PortAddr iop_base)
1da177e4 8161{
27c868c2
MW
8162 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
8163 AscSetChipStatus(iop_base, 0);
8164 return;
1da177e4
LT
8165}
8166
78e77d8b 8167static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
1da177e4 8168{
27c868c2
MW
8169 ushort cfg_lsw;
8170 uchar chip_irq;
8171
8172 if ((bus_type & ASC_IS_EISA) != 0) {
8173 cfg_lsw = AscGetEisaChipCfg(iop_base);
8174 chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10);
8175 if ((chip_irq == 13) || (chip_irq > 15)) {
8176 return (0);
8177 }
8178 return (chip_irq);
8179 }
8180 if ((bus_type & ASC_IS_VL) != 0) {
8181 cfg_lsw = AscGetChipCfgLsw(iop_base);
8182 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07));
8183 if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) {
8184 return (0);
8185 }
8186 return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1)));
8187 }
8188 cfg_lsw = AscGetChipCfgLsw(iop_base);
8189 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03));
8190 if (chip_irq == 3)
8191 chip_irq += (uchar)2;
8192 return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
1da177e4
LT
8193}
8194
78e77d8b 8195static uchar __devinit
27c868c2 8196AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
1da177e4 8197{
27c868c2
MW
8198 ushort cfg_lsw;
8199
8200 if ((bus_type & ASC_IS_VL) != 0) {
8201 if (irq_no != 0) {
8202 if ((irq_no < ASC_MIN_IRQ_NO)
8203 || (irq_no > ASC_MAX_IRQ_NO)) {
8204 irq_no = 0;
8205 } else {
8206 irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1));
8207 }
8208 }
8209 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3);
8210 cfg_lsw |= (ushort)0x0010;
8211 AscSetChipCfgLsw(iop_base, cfg_lsw);
8212 AscToggleIRQAct(iop_base);
8213 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0);
8214 cfg_lsw |= (ushort)((irq_no & 0x07) << 2);
8215 AscSetChipCfgLsw(iop_base, cfg_lsw);
8216 AscToggleIRQAct(iop_base);
8217 return (AscGetChipIRQ(iop_base, bus_type));
8218 }
8219 if ((bus_type & (ASC_IS_ISA)) != 0) {
8220 if (irq_no == 15)
8221 irq_no -= (uchar)2;
8222 irq_no -= (uchar)ASC_MIN_IRQ_NO;
8223 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3);
8224 cfg_lsw |= (ushort)((irq_no & 0x03) << 2);
8225 AscSetChipCfgLsw(iop_base, cfg_lsw);
8226 return (AscGetChipIRQ(iop_base, bus_type));
8227 }
8228 return (0);
1da177e4
LT
8229}
8230
8231#ifdef CONFIG_ISA
78e77d8b 8232static void __devinit AscEnableIsaDma(uchar dma_channel)
1da177e4 8233{
27c868c2
MW
8234 if (dma_channel < 4) {
8235 outp(0x000B, (ushort)(0xC0 | dma_channel));
8236 outp(0x000A, dma_channel);
8237 } else if (dma_channel < 8) {
8238 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
8239 outp(0x00D4, (ushort)(dma_channel - 4));
8240 }
8241 return;
1da177e4
LT
8242}
8243#endif /* CONFIG_ISA */
8244
27c868c2 8245static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
1da177e4 8246{
27c868c2
MW
8247 EXT_MSG ext_msg;
8248 EXT_MSG out_msg;
8249 ushort halt_q_addr;
8250 int sdtr_accept;
8251 ushort int_halt_code;
8252 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8253 ASC_SCSI_BIT_ID_TYPE target_id;
8254 PortAddr iop_base;
8255 uchar tag_code;
8256 uchar q_status;
8257 uchar halt_qp;
8258 uchar sdtr_data;
8259 uchar target_ix;
8260 uchar q_cntl, tid_no;
8261 uchar cur_dvc_qng;
8262 uchar asyn_sdtr;
8263 uchar scsi_status;
8264 asc_board_t *boardp;
8265
8266 ASC_ASSERT(asc_dvc->drv_ptr != NULL);
8267 boardp = asc_dvc->drv_ptr;
8268
8269 iop_base = asc_dvc->iop_base;
8270 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
8271
8272 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
8273 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
8274 target_ix = AscReadLramByte(iop_base,
8275 (ushort)(halt_q_addr +
8276 (ushort)ASC_SCSIQ_B_TARGET_IX));
8277 q_cntl =
8278 AscReadLramByte(iop_base,
8279 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8280 tid_no = ASC_TIX_TO_TID(target_ix);
8281 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
8282 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8283 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
8284 } else {
8285 asyn_sdtr = 0;
8286 }
8287 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
8288 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8289 AscSetChipSDTR(iop_base, 0, tid_no);
8290 boardp->sdtr_data[tid_no] = 0;
8291 }
8292 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8293 return (0);
8294 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
8295 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8296 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8297 boardp->sdtr_data[tid_no] = asyn_sdtr;
8298 }
8299 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8300 return (0);
8301 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
8302
8303 AscMemWordCopyPtrFromLram(iop_base,
8304 ASCV_MSGIN_BEG,
8305 (uchar *)&ext_msg,
8306 sizeof(EXT_MSG) >> 1);
8307
8308 if (ext_msg.msg_type == MS_EXTEND &&
8309 ext_msg.msg_req == MS_SDTR_CODE &&
8310 ext_msg.msg_len == MS_SDTR_LEN) {
8311 sdtr_accept = TRUE;
8312 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
8313
8314 sdtr_accept = FALSE;
8315 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
8316 }
8317 if ((ext_msg.xfer_period <
8318 asc_dvc->sdtr_period_tbl[asc_dvc->
8319 host_init_sdtr_index])
8320 || (ext_msg.xfer_period >
8321 asc_dvc->sdtr_period_tbl[asc_dvc->
8322 max_sdtr_index])) {
8323 sdtr_accept = FALSE;
8324 ext_msg.xfer_period =
8325 asc_dvc->sdtr_period_tbl[asc_dvc->
8326 host_init_sdtr_index];
8327 }
8328 if (sdtr_accept) {
8329 sdtr_data =
8330 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
8331 ext_msg.req_ack_offset);
8332 if ((sdtr_data == 0xFF)) {
8333
8334 q_cntl |= QC_MSG_OUT;
8335 asc_dvc->init_sdtr &= ~target_id;
8336 asc_dvc->sdtr_done &= ~target_id;
8337 AscSetChipSDTR(iop_base, asyn_sdtr,
8338 tid_no);
8339 boardp->sdtr_data[tid_no] = asyn_sdtr;
8340 }
8341 }
8342 if (ext_msg.req_ack_offset == 0) {
8343
8344 q_cntl &= ~QC_MSG_OUT;
8345 asc_dvc->init_sdtr &= ~target_id;
8346 asc_dvc->sdtr_done &= ~target_id;
8347 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8348 } else {
8349 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
8350
8351 q_cntl &= ~QC_MSG_OUT;
8352 asc_dvc->sdtr_done |= target_id;
8353 asc_dvc->init_sdtr |= target_id;
8354 asc_dvc->pci_fix_asyn_xfer &=
8355 ~target_id;
8356 sdtr_data =
8357 AscCalSDTRData(asc_dvc,
8358 ext_msg.xfer_period,
8359 ext_msg.
8360 req_ack_offset);
8361 AscSetChipSDTR(iop_base, sdtr_data,
8362 tid_no);
8363 boardp->sdtr_data[tid_no] = sdtr_data;
8364 } else {
8365
8366 q_cntl |= QC_MSG_OUT;
8367 AscMsgOutSDTR(asc_dvc,
8368 ext_msg.xfer_period,
8369 ext_msg.req_ack_offset);
8370 asc_dvc->pci_fix_asyn_xfer &=
8371 ~target_id;
8372 sdtr_data =
8373 AscCalSDTRData(asc_dvc,
8374 ext_msg.xfer_period,
8375 ext_msg.
8376 req_ack_offset);
8377 AscSetChipSDTR(iop_base, sdtr_data,
8378 tid_no);
8379 boardp->sdtr_data[tid_no] = sdtr_data;
8380 asc_dvc->sdtr_done |= target_id;
8381 asc_dvc->init_sdtr |= target_id;
8382 }
8383 }
8384
8385 AscWriteLramByte(iop_base,
8386 (ushort)(halt_q_addr +
8387 (ushort)ASC_SCSIQ_B_CNTL),
8388 q_cntl);
8389 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8390 return (0);
8391 } else if (ext_msg.msg_type == MS_EXTEND &&
8392 ext_msg.msg_req == MS_WDTR_CODE &&
8393 ext_msg.msg_len == MS_WDTR_LEN) {
8394
8395 ext_msg.wdtr_width = 0;
8396 AscMemWordCopyPtrToLram(iop_base,
8397 ASCV_MSGOUT_BEG,
8398 (uchar *)&ext_msg,
8399 sizeof(EXT_MSG) >> 1);
8400 q_cntl |= QC_MSG_OUT;
8401 AscWriteLramByte(iop_base,
8402 (ushort)(halt_q_addr +
8403 (ushort)ASC_SCSIQ_B_CNTL),
8404 q_cntl);
8405 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8406 return (0);
8407 } else {
8408
8409 ext_msg.msg_type = MESSAGE_REJECT;
8410 AscMemWordCopyPtrToLram(iop_base,
8411 ASCV_MSGOUT_BEG,
8412 (uchar *)&ext_msg,
8413 sizeof(EXT_MSG) >> 1);
8414 q_cntl |= QC_MSG_OUT;
8415 AscWriteLramByte(iop_base,
8416 (ushort)(halt_q_addr +
8417 (ushort)ASC_SCSIQ_B_CNTL),
8418 q_cntl);
8419 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8420 return (0);
8421 }
8422 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
8423
8424 q_cntl |= QC_REQ_SENSE;
8425
8426 if ((asc_dvc->init_sdtr & target_id) != 0) {
8427
8428 asc_dvc->sdtr_done &= ~target_id;
8429
8430 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8431 q_cntl |= QC_MSG_OUT;
8432 AscMsgOutSDTR(asc_dvc,
8433 asc_dvc->
8434 sdtr_period_tbl[(sdtr_data >> 4) &
8435 (uchar)(asc_dvc->
8436 max_sdtr_index -
8437 1)],
8438 (uchar)(sdtr_data & (uchar)
8439 ASC_SYN_MAX_OFFSET));
8440 }
8441
8442 AscWriteLramByte(iop_base,
8443 (ushort)(halt_q_addr +
8444 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8445
8446 tag_code = AscReadLramByte(iop_base,
8447 (ushort)(halt_q_addr + (ushort)
8448 ASC_SCSIQ_B_TAG_CODE));
8449 tag_code &= 0xDC;
8450 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
8451 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
8452 ) {
8453
8454 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
8455 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
8456
8457 }
8458 AscWriteLramByte(iop_base,
8459 (ushort)(halt_q_addr +
8460 (ushort)ASC_SCSIQ_B_TAG_CODE),
8461 tag_code);
8462
8463 q_status = AscReadLramByte(iop_base,
8464 (ushort)(halt_q_addr + (ushort)
8465 ASC_SCSIQ_B_STATUS));
8466 q_status |= (QS_READY | QS_BUSY);
8467 AscWriteLramByte(iop_base,
8468 (ushort)(halt_q_addr +
8469 (ushort)ASC_SCSIQ_B_STATUS),
8470 q_status);
8471
8472 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
8473 scsi_busy &= ~target_id;
8474 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8475
8476 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8477 return (0);
8478 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
8479
8480 AscMemWordCopyPtrFromLram(iop_base,
8481 ASCV_MSGOUT_BEG,
8482 (uchar *)&out_msg,
8483 sizeof(EXT_MSG) >> 1);
8484
8485 if ((out_msg.msg_type == MS_EXTEND) &&
8486 (out_msg.msg_len == MS_SDTR_LEN) &&
8487 (out_msg.msg_req == MS_SDTR_CODE)) {
8488
8489 asc_dvc->init_sdtr &= ~target_id;
8490 asc_dvc->sdtr_done &= ~target_id;
8491 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8492 boardp->sdtr_data[tid_no] = asyn_sdtr;
8493 }
8494 q_cntl &= ~QC_MSG_OUT;
8495 AscWriteLramByte(iop_base,
8496 (ushort)(halt_q_addr +
8497 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8498 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8499 return (0);
8500 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
8501
8502 scsi_status = AscReadLramByte(iop_base,
8503 (ushort)((ushort)halt_q_addr +
8504 (ushort)
8505 ASC_SCSIQ_SCSI_STATUS));
8506 cur_dvc_qng =
8507 AscReadLramByte(iop_base,
8508 (ushort)((ushort)ASC_QADR_BEG +
8509 (ushort)target_ix));
8510 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
8511
8512 scsi_busy = AscReadLramByte(iop_base,
8513 (ushort)ASCV_SCSIBUSY_B);
8514 scsi_busy |= target_id;
8515 AscWriteLramByte(iop_base,
8516 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8517 asc_dvc->queue_full_or_busy |= target_id;
8518
8519 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
8520 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
8521 cur_dvc_qng -= 1;
8522 asc_dvc->max_dvc_qng[tid_no] =
8523 cur_dvc_qng;
8524
8525 AscWriteLramByte(iop_base,
8526 (ushort)((ushort)
8527 ASCV_MAX_DVC_QNG_BEG
8528 + (ushort)
8529 tid_no),
8530 cur_dvc_qng);
8531
8532 /*
8533 * Set the device queue depth to the number of
8534 * active requests when the QUEUE FULL condition
8535 * was encountered.
8536 */
8537 boardp->queue_full |= target_id;
8538 boardp->queue_full_cnt[tid_no] =
8539 cur_dvc_qng;
8540 }
8541 }
8542 }
8543 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8544 return (0);
8545 }
1da177e4 8546#if CC_VERY_LONG_SG_LIST
27c868c2
MW
8547 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
8548 uchar q_no;
8549 ushort q_addr;
8550 uchar sg_wk_q_no;
8551 uchar first_sg_wk_q_no;
8552 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
8553 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
8554 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
8555 ushort sg_list_dwords;
8556 ushort sg_entry_cnt;
8557 uchar next_qp;
8558 int i;
8559
8560 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
8561 if (q_no == ASC_QLINK_END) {
8562 return (0);
8563 }
8564
8565 q_addr = ASC_QNO_TO_QADDR(q_no);
8566
8567 /*
8568 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
8569 * structure pointer using a macro provided by the driver.
8570 * The ASC_SCSI_REQ pointer provides a pointer to the
8571 * host ASC_SG_HEAD structure.
8572 */
8573 /* Read request's SRB pointer. */
8574 scsiq = (ASC_SCSI_Q *)
8575 ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
8576 (ushort)
8577 (q_addr +
8578 ASC_SCSIQ_D_SRBPTR))));
8579
8580 /*
8581 * Get request's first and working SG queue.
8582 */
8583 sg_wk_q_no = AscReadLramByte(iop_base,
8584 (ushort)(q_addr +
8585 ASC_SCSIQ_B_SG_WK_QP));
8586
8587 first_sg_wk_q_no = AscReadLramByte(iop_base,
8588 (ushort)(q_addr +
8589 ASC_SCSIQ_B_FIRST_SG_WK_QP));
8590
8591 /*
8592 * Reset request's working SG queue back to the
8593 * first SG queue.
8594 */
8595 AscWriteLramByte(iop_base,
8596 (ushort)(q_addr +
8597 (ushort)ASC_SCSIQ_B_SG_WK_QP),
8598 first_sg_wk_q_no);
8599
8600 sg_head = scsiq->sg_head;
8601
8602 /*
8603 * Set sg_entry_cnt to the number of SG elements
8604 * that will be completed on this interrupt.
8605 *
8606 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
8607 * SG elements. The data_cnt and data_addr fields which
8608 * add 1 to the SG element capacity are not used when
8609 * restarting SG handling after a halt.
8610 */
8611 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
8612 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
8613
8614 /*
8615 * Keep track of remaining number of SG elements that will
8616 * need to be handled on the next interrupt.
8617 */
8618 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
8619 } else {
8620 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
8621 scsiq->remain_sg_entry_cnt = 0;
8622 }
8623
8624 /*
8625 * Copy SG elements into the list of allocated SG queues.
8626 *
8627 * Last index completed is saved in scsiq->next_sg_index.
8628 */
8629 next_qp = first_sg_wk_q_no;
8630 q_addr = ASC_QNO_TO_QADDR(next_qp);
8631 scsi_sg_q.sg_head_qp = q_no;
8632 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
8633 for (i = 0; i < sg_head->queue_cnt; i++) {
8634 scsi_sg_q.seq_no = i + 1;
8635 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
8636 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
8637 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
8638 /*
8639 * After very first SG queue RISC FW uses next
8640 * SG queue first element then checks sg_list_cnt
8641 * against zero and then decrements, so set
8642 * sg_list_cnt 1 less than number of SG elements
8643 * in each SG queue.
8644 */
8645 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
8646 scsi_sg_q.sg_cur_list_cnt =
8647 ASC_SG_LIST_PER_Q - 1;
8648 } else {
8649 /*
8650 * This is the last SG queue in the list of
8651 * allocated SG queues. If there are more
8652 * SG elements than will fit in the allocated
8653 * queues, then set the QCSG_SG_XFER_MORE flag.
8654 */
8655 if (scsiq->remain_sg_entry_cnt != 0) {
8656 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
8657 } else {
8658 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
8659 }
8660 /* equals sg_entry_cnt * 2 */
8661 sg_list_dwords = sg_entry_cnt << 1;
8662 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
8663 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
8664 sg_entry_cnt = 0;
8665 }
8666
8667 scsi_sg_q.q_no = next_qp;
8668 AscMemWordCopyPtrToLram(iop_base,
8669 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
8670 (uchar *)&scsi_sg_q,
8671 sizeof(ASC_SG_LIST_Q) >> 1);
8672
8673 AscMemDWordCopyPtrToLram(iop_base,
8674 q_addr + ASC_SGQ_LIST_BEG,
8675 (uchar *)&sg_head->
8676 sg_list[scsiq->next_sg_index],
8677 sg_list_dwords);
8678
8679 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
8680
8681 /*
8682 * If the just completed SG queue contained the
8683 * last SG element, then no more SG queues need
8684 * to be written.
8685 */
8686 if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
8687 break;
8688 }
8689
8690 next_qp = AscReadLramByte(iop_base,
8691 (ushort)(q_addr +
8692 ASC_SCSIQ_B_FWD));
8693 q_addr = ASC_QNO_TO_QADDR(next_qp);
8694 }
8695
8696 /*
8697 * Clear the halt condition so the RISC will be restarted
8698 * after the return.
8699 */
8700 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8701 return (0);
8702 }
1da177e4 8703#endif /* CC_VERY_LONG_SG_LIST */
27c868c2 8704 return (0);
1da177e4
LT
8705}
8706
27c868c2
MW
8707static uchar
8708_AscCopyLramScsiDoneQ(PortAddr iop_base,
8709 ushort q_addr,
8710 ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
1da177e4 8711{
27c868c2
MW
8712 ushort _val;
8713 uchar sg_queue_cnt;
8714
8715 DvcGetQinfo(iop_base,
8716 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
8717 (uchar *)scsiq,
8718 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
8719
8720 _val = AscReadLramWord(iop_base,
8721 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
8722 scsiq->q_status = (uchar)_val;
8723 scsiq->q_no = (uchar)(_val >> 8);
8724 _val = AscReadLramWord(iop_base,
8725 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8726 scsiq->cntl = (uchar)_val;
8727 sg_queue_cnt = (uchar)(_val >> 8);
8728 _val = AscReadLramWord(iop_base,
8729 (ushort)(q_addr +
8730 (ushort)ASC_SCSIQ_B_SENSE_LEN));
8731 scsiq->sense_len = (uchar)_val;
8732 scsiq->extra_bytes = (uchar)(_val >> 8);
8733
8734 /*
8735 * Read high word of remain bytes from alternate location.
8736 */
8737 scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
8738 (ushort)(q_addr +
8739 (ushort)
8740 ASC_SCSIQ_W_ALT_DC1)))
8741 << 16);
8742 /*
8743 * Read low word of remain bytes from original location.
8744 */
8745 scsiq->remain_bytes += AscReadLramWord(iop_base,
8746 (ushort)(q_addr + (ushort)
8747 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
8748
8749 scsiq->remain_bytes &= max_dma_count;
8750 return (sg_queue_cnt);
1da177e4
LT
8751}
8752
27c868c2 8753static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
1da177e4 8754{
27c868c2
MW
8755 uchar next_qp;
8756 uchar n_q_used;
8757 uchar sg_list_qp;
8758 uchar sg_queue_cnt;
8759 uchar q_cnt;
8760 uchar done_q_tail;
8761 uchar tid_no;
8762 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8763 ASC_SCSI_BIT_ID_TYPE target_id;
8764 PortAddr iop_base;
8765 ushort q_addr;
8766 ushort sg_q_addr;
8767 uchar cur_target_qng;
8768 ASC_QDONE_INFO scsiq_buf;
8769 ASC_QDONE_INFO *scsiq;
8770 int false_overrun;
8771 ASC_ISR_CALLBACK asc_isr_callback;
8772
8773 iop_base = asc_dvc->iop_base;
8774 asc_isr_callback = asc_dvc->isr_callback;
8775 n_q_used = 1;
8776 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
8777 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
8778 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
8779 next_qp = AscReadLramByte(iop_base,
8780 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
8781 if (next_qp != ASC_QLINK_END) {
8782 AscPutVarDoneQTail(iop_base, next_qp);
8783 q_addr = ASC_QNO_TO_QADDR(next_qp);
8784 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
8785 asc_dvc->max_dma_count);
8786 AscWriteLramByte(iop_base,
8787 (ushort)(q_addr +
8788 (ushort)ASC_SCSIQ_B_STATUS),
8789 (uchar)(scsiq->
8790 q_status & (uchar)~(QS_READY |
8791 QS_ABORTED)));
8792 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
8793 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
8794 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
8795 sg_q_addr = q_addr;
8796 sg_list_qp = next_qp;
8797 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
8798 sg_list_qp = AscReadLramByte(iop_base,
8799 (ushort)(sg_q_addr
8800 + (ushort)
8801 ASC_SCSIQ_B_FWD));
8802 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
8803 if (sg_list_qp == ASC_QLINK_END) {
8804 AscSetLibErrorCode(asc_dvc,
8805 ASCQ_ERR_SG_Q_LINKS);
8806 scsiq->d3.done_stat = QD_WITH_ERROR;
8807 scsiq->d3.host_stat =
8808 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
8809 goto FATAL_ERR_QDONE;
8810 }
8811 AscWriteLramByte(iop_base,
8812 (ushort)(sg_q_addr + (ushort)
8813 ASC_SCSIQ_B_STATUS),
8814 QS_FREE);
8815 }
8816 n_q_used = sg_queue_cnt + 1;
8817 AscPutVarDoneQTail(iop_base, sg_list_qp);
8818 }
8819 if (asc_dvc->queue_full_or_busy & target_id) {
8820 cur_target_qng = AscReadLramByte(iop_base,
8821 (ushort)((ushort)
8822 ASC_QADR_BEG
8823 + (ushort)
8824 scsiq->d2.
8825 target_ix));
8826 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
8827 scsi_busy = AscReadLramByte(iop_base, (ushort)
8828 ASCV_SCSIBUSY_B);
8829 scsi_busy &= ~target_id;
8830 AscWriteLramByte(iop_base,
8831 (ushort)ASCV_SCSIBUSY_B,
8832 scsi_busy);
8833 asc_dvc->queue_full_or_busy &= ~target_id;
8834 }
8835 }
8836 if (asc_dvc->cur_total_qng >= n_q_used) {
8837 asc_dvc->cur_total_qng -= n_q_used;
8838 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
8839 asc_dvc->cur_dvc_qng[tid_no]--;
8840 }
8841 } else {
8842 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
8843 scsiq->d3.done_stat = QD_WITH_ERROR;
8844 goto FATAL_ERR_QDONE;
8845 }
8846 if ((scsiq->d2.srb_ptr == 0UL) ||
8847 ((scsiq->q_status & QS_ABORTED) != 0)) {
8848 return (0x11);
8849 } else if (scsiq->q_status == QS_DONE) {
8850 false_overrun = FALSE;
8851 if (scsiq->extra_bytes != 0) {
8852 scsiq->remain_bytes +=
8853 (ADV_DCNT)scsiq->extra_bytes;
8854 }
8855 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
8856 if (scsiq->d3.host_stat ==
8857 QHSTA_M_DATA_OVER_RUN) {
8858 if ((scsiq->
8859 cntl & (QC_DATA_IN | QC_DATA_OUT))
8860 == 0) {
8861 scsiq->d3.done_stat =
8862 QD_NO_ERROR;
8863 scsiq->d3.host_stat =
8864 QHSTA_NO_ERROR;
8865 } else if (false_overrun) {
8866 scsiq->d3.done_stat =
8867 QD_NO_ERROR;
8868 scsiq->d3.host_stat =
8869 QHSTA_NO_ERROR;
8870 }
8871 } else if (scsiq->d3.host_stat ==
8872 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
8873 AscStopChip(iop_base);
8874 AscSetChipControl(iop_base,
8875 (uchar)(CC_SCSI_RESET
8876 | CC_HALT));
8877 DvcDelayNanoSecond(asc_dvc, 60000);
8878 AscSetChipControl(iop_base, CC_HALT);
8879 AscSetChipStatus(iop_base,
8880 CIW_CLR_SCSI_RESET_INT);
8881 AscSetChipStatus(iop_base, 0);
8882 AscSetChipControl(iop_base, 0);
8883 }
8884 }
8885 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
8886 (*asc_isr_callback) (asc_dvc, scsiq);
8887 } else {
8888 if ((AscReadLramByte(iop_base,
8889 (ushort)(q_addr + (ushort)
8890 ASC_SCSIQ_CDB_BEG))
8891 == START_STOP)) {
8892 asc_dvc->unit_not_ready &= ~target_id;
8893 if (scsiq->d3.done_stat != QD_NO_ERROR) {
8894 asc_dvc->start_motor &=
8895 ~target_id;
8896 }
8897 }
8898 }
8899 return (1);
8900 } else {
8901 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
8902 FATAL_ERR_QDONE:
8903 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
8904 (*asc_isr_callback) (asc_dvc, scsiq);
8905 }
8906 return (0x80);
8907 }
8908 }
8909 return (0);
1da177e4
LT
8910}
8911
27c868c2 8912static int AscISR(ASC_DVC_VAR *asc_dvc)
1da177e4 8913{
27c868c2
MW
8914 ASC_CS_TYPE chipstat;
8915 PortAddr iop_base;
8916 ushort saved_ram_addr;
8917 uchar ctrl_reg;
8918 uchar saved_ctrl_reg;
8919 int int_pending;
8920 int status;
8921 uchar host_flag;
8922
8923 iop_base = asc_dvc->iop_base;
8924 int_pending = FALSE;
8925
8926 if (AscIsIntPending(iop_base) == 0) {
8927 return int_pending;
8928 }
1da177e4 8929
27c868c2
MW
8930 if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
8931 || (asc_dvc->isr_callback == 0)
8932 ) {
8933 return (ERR);
8934 }
8935 if (asc_dvc->in_critical_cnt != 0) {
8936 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
8937 return (ERR);
8938 }
8939 if (asc_dvc->is_in_int) {
8940 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
8941 return (ERR);
8942 }
8943 asc_dvc->is_in_int = TRUE;
8944 ctrl_reg = AscGetChipControl(iop_base);
8945 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
8946 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
8947 chipstat = AscGetChipStatus(iop_base);
8948 if (chipstat & CSW_SCSI_RESET_LATCH) {
8949 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
8950 int i = 10;
8951 int_pending = TRUE;
8952 asc_dvc->sdtr_done = 0;
8953 saved_ctrl_reg &= (uchar)(~CC_HALT);
8954 while ((AscGetChipStatus(iop_base) &
8955 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
8956 DvcSleepMilliSecond(100);
8957 }
8958 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
8959 AscSetChipControl(iop_base, CC_HALT);
8960 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
8961 AscSetChipStatus(iop_base, 0);
8962 chipstat = AscGetChipStatus(iop_base);
8963 }
8964 }
8965 saved_ram_addr = AscGetChipLramAddr(iop_base);
8966 host_flag = AscReadLramByte(iop_base,
8967 ASCV_HOST_FLAG_B) &
8968 (uchar)(~ASC_HOST_FLAG_IN_ISR);
8969 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
8970 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
8971 if ((chipstat & CSW_INT_PENDING)
8972 || (int_pending)
8973 ) {
8974 AscAckInterrupt(iop_base);
8975 int_pending = TRUE;
8976 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
8977 if (AscIsrChipHalted(asc_dvc) == ERR) {
8978 goto ISR_REPORT_QDONE_FATAL_ERROR;
8979 } else {
8980 saved_ctrl_reg &= (uchar)(~CC_HALT);
8981 }
8982 } else {
8983 ISR_REPORT_QDONE_FATAL_ERROR:
8984 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
8985 while (((status =
8986 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
8987 }
8988 } else {
8989 do {
8990 if ((status =
8991 AscIsrQDone(asc_dvc)) == 1) {
8992 break;
8993 }
8994 } while (status == 0x11);
8995 }
8996 if ((status & 0x80) != 0)
8997 int_pending = ERR;
8998 }
8999 }
9000 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
9001 AscSetChipLramAddr(iop_base, saved_ram_addr);
9002 AscSetChipControl(iop_base, saved_ctrl_reg);
9003 asc_dvc->is_in_int = FALSE;
9004 return (int_pending);
1da177e4
LT
9005}
9006
9007/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
9008static uchar _asc_mcode_buf[] = {
9009 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9010 0x00, 0x00, 0x00, 0x00,
9011 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00,
9012 0x00, 0x00, 0x00, 0x00,
9013 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9014 0x00, 0x00, 0x00, 0x00,
9015 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9016 0x00, 0x00, 0x00, 0x00,
9017 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00,
9018 0x00, 0xFF, 0x00, 0x00,
9019 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00,
9020 0x00, 0x00, 0x00, 0x00,
9021 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
9022 0x00, 0x00, 0x00, 0x00,
9023 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88,
9024 0x00, 0x00, 0x00, 0x00,
9025 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73,
9026 0x03, 0x23, 0x36, 0x40,
9027 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
9028 0xC2, 0x00, 0x92, 0x80,
9029 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60,
9030 0xB6, 0x00, 0x92, 0x80,
9031 0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00,
9032 0x92, 0x80, 0x80, 0x62,
9033 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
9034 0xCD, 0x04, 0x4D, 0x00,
9035 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01,
9036 0xE6, 0x84, 0xD2, 0xC1,
9037 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97,
9038 0xC6, 0x81, 0xC2, 0x88,
9039 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
9040 0x84, 0x97, 0x07, 0xA6,
9041 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE,
9042 0xC2, 0x88, 0xCE, 0x00,
9043 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01,
9044 0x80, 0x63, 0x07, 0xA6,
9045 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
9046 0x34, 0x01, 0x00, 0x33,
9047 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23,
9048 0x68, 0x98, 0x4D, 0x04,
9049 0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23,
9050 0xF8, 0x88, 0xFB, 0x23,
9051 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
9052 0x00, 0x33, 0x0A, 0x00,
9053 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00,
9054 0xC2, 0x88, 0xCD, 0x04,
9055 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81,
9056 0x06, 0xAB, 0x82, 0x01,
9057 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
9058 0x3C, 0x01, 0x00, 0x05,
9059 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01,
9060 0x15, 0x23, 0xA1, 0x01,
9061 0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00,
9062 0x06, 0x61, 0x00, 0xA0,
9063 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
9064 0xC2, 0x88, 0x06, 0x23,
9065 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01,
9066 0x57, 0x60, 0x00, 0xA0,
9067 0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73,
9068 0x4B, 0x00, 0x06, 0x61,
9069 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
9070 0x4F, 0x00, 0x84, 0x97,
9071 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97,
9072 0x48, 0x04, 0x84, 0x80,
9073 0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00,
9074 0x81, 0x73, 0x06, 0x29,
9075 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
9076 0x04, 0x98, 0xF0, 0x80,
9077 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6,
9078 0x34, 0x02, 0x03, 0xA6,
9079 0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96,
9080 0x46, 0x82, 0xFE, 0x95,
9081 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
9082 0x07, 0xA6, 0x5A, 0x02,
9083 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95,
9084 0x48, 0x82, 0x60, 0x96,
9085 0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84,
9086 0x04, 0x01, 0x0C, 0xDC,
9087 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
9088 0x6F, 0x00, 0xA5, 0x01,
9089 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01,
9090 0x02, 0xA6, 0xAA, 0x02,
9091 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04,
9092 0x01, 0xA6, 0xB4, 0x02,
9093 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
9094 0x80, 0x63, 0x00, 0x43,
9095 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23,
9096 0x04, 0x61, 0x84, 0x01,
9097 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F,
9098 0x00, 0x00, 0xEA, 0x82,
9099 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
9100 0x00, 0x33, 0x1F, 0x00,
9101 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98,
9102 0xB6, 0x2D, 0x01, 0xA6,
9103 0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6,
9104 0x10, 0x03, 0x03, 0xA6,
9105 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
9106 0x7C, 0x95, 0xEE, 0x82,
9107 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4,
9108 0x04, 0x01, 0x2D, 0xC8,
9109 0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01,
9110 0x05, 0x05, 0x86, 0x98,
9111 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
9112 0x3C, 0x04, 0x06, 0xA6,
9113 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88,
9114 0x7C, 0x95, 0x32, 0x83,
9115 0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05,
9116 0xEB, 0x04, 0x00, 0x33,
9117 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
9118 0xFF, 0xA2, 0x7A, 0x03,
9119 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01,
9120 0x00, 0xA2, 0x9A, 0x03,
9121 0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00,
9122 0x01, 0xA6, 0x96, 0x03,
9123 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
9124 0xA4, 0x03, 0x00, 0xA6,
9125 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03,
9126 0x07, 0xA6, 0xB2, 0x03,
9127 0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88,
9128 0xA8, 0x98, 0x80, 0x42,
9129 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
9130 0xC0, 0x83, 0x00, 0x33,
9131 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23,
9132 0xA0, 0x01, 0x12, 0x23,
9133 0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B,
9134 0x80, 0x67, 0x05, 0x23,
9135 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
9136 0x06, 0xA6, 0x0A, 0x04,
9137 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96,
9138 0xF4, 0x83, 0x20, 0x84,
9139 0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
9140 0x83, 0x03, 0x80, 0x63,
9141 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
9142 0x38, 0x04, 0x00, 0x33,
9143 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84,
9144 0x1D, 0x01, 0x06, 0xCC,
9145 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62,
9146 0xA2, 0x0D, 0x80, 0x63,
9147 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
9148 0x80, 0x63, 0xA3, 0x01,
9149 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0,
9150 0x76, 0x04, 0xE0, 0x00,
9151 0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00,
9152 0x00, 0x33, 0x1E, 0x00,
9153 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
9154 0x08, 0x23, 0x22, 0xA3,
9155 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3,
9156 0xC4, 0x04, 0x42, 0x23,
9157 0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23,
9158 0xF8, 0x88, 0x04, 0x98,
9159 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
9160 0x81, 0x62, 0xE8, 0x81,
9161 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98,
9162 0x00, 0x33, 0x00, 0x81,
9163 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23,
9164 0xF8, 0x88, 0x04, 0x23,
9165 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
9166 0xF4, 0x04, 0x00, 0x33,
9167 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01,
9168 0x04, 0x23, 0xA0, 0x01,
9169 0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00,
9170 0x00, 0xA3, 0x22, 0x05,
9171 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
9172 0x46, 0x97, 0xCD, 0x04,
9173 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23,
9174 0x82, 0x01, 0x34, 0x85,
9175 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05,
9176 0x1D, 0x01, 0x04, 0xD6,
9177 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
9178 0x49, 0x00, 0x81, 0x01,
9179 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01,
9180 0x49, 0x04, 0x80, 0x01,
9181 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04,
9182 0x01, 0x23, 0xEA, 0x00,
9183 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
9184 0x07, 0xA4, 0xF8, 0x05,
9185 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00,
9186 0xC2, 0x88, 0x04, 0xA0,
9187 0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61,
9188 0x00, 0xA2, 0xA4, 0x05,
9189 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
9190 0x62, 0x97, 0x04, 0x85,
9191 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05,
9192 0xF4, 0x85, 0x03, 0xA0,
9193 0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63,
9194 0xCC, 0x86, 0x07, 0xA0,
9195 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
9196 0x80, 0x67, 0x80, 0x63,
9197 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23,
9198 0xF8, 0x88, 0x07, 0x23,
9199 0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00,
9200 0x00, 0x63, 0x4A, 0x00,
9201 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
9202 0x07, 0x41, 0x83, 0x03,
9203 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88,
9204 0x1D, 0x01, 0x01, 0xD6,
9205 0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00,
9206 0x07, 0xA6, 0x7C, 0x05,
9207 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
9208 0x52, 0x00, 0x06, 0x61,
9209 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41,
9210 0x00, 0x63, 0x1D, 0x01,
9211 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23,
9212 0x07, 0x41, 0x00, 0x63,
9213 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
9214 0xDF, 0x00, 0x06, 0xA6,
9215 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33,
9216 0x00, 0x40, 0xC0, 0x20,
9217 0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63,
9218 0x06, 0xA6, 0x94, 0x06,
9219 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
9220 0x40, 0x0E, 0x80, 0x63,
9221 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E,
9222 0x80, 0x63, 0x00, 0x43,
9223 0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05,
9224 0x80, 0x67, 0x40, 0x0E,
9225 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
9226 0x07, 0xA6, 0xD6, 0x06,
9227 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00,
9228 0x0A, 0x2B, 0x07, 0xA6,
9229 0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2,
9230 0xF4, 0x06, 0xC0, 0x0E,
9231 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
9232 0x81, 0x62, 0x04, 0x01,
9233 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6,
9234 0x8C, 0x06, 0x00, 0x33,
9235 0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03,
9236 0x80, 0x63, 0x06, 0xA6,
9237 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
9238 0x00, 0x00, 0x80, 0x67,
9239 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05,
9240 0xBF, 0x23, 0x04, 0x61,
9241 0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00,
9242 0x00, 0x01, 0xF2, 0x00,
9243 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
9244 0x80, 0x05, 0x81, 0x05,
9245 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00,
9246 0x70, 0x00, 0x81, 0x01,
9247 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04,
9248 0x70, 0x00, 0x80, 0x01,
9249 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
9250 0xF1, 0x00, 0x70, 0x00,
9251 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01,
9252 0x71, 0x04, 0x70, 0x00,
9253 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05,
9254 0xA3, 0x01, 0xA2, 0x01,
9255 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
9256 0xC4, 0x07, 0x00, 0x33,
9257 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8,
9258 0x48, 0x00, 0xB0, 0x01,
9259 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43,
9260 0x00, 0xA2, 0xE4, 0x07,
9261 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
9262 0x05, 0x05, 0x00, 0x63,
9263 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43,
9264 0x76, 0x08, 0x80, 0x02,
9265 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
9266 0x00, 0x02, 0x00, 0xA0,
9267 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
9268 0x00, 0x63, 0xF3, 0x04,
9269 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40,
9270 0x00, 0xA2, 0x44, 0x08,
9271 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1,
9272 0x24, 0x08, 0x04, 0x98,
9273 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
9274 0x5A, 0x88, 0x02, 0x01,
9275 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00,
9276 0x00, 0xA3, 0x64, 0x08,
9277 0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63,
9278 0x06, 0xA6, 0x76, 0x08,
9279 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
9280 0x00, 0x63, 0x38, 0x2B,
9281 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98,
9282 0x05, 0x05, 0xB2, 0x09,
9283 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63,
9284 0x80, 0x32, 0x80, 0x36,
9285 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
9286 0x40, 0x36, 0x40, 0x3A,
9287 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08,
9288 0x5D, 0x00, 0xFE, 0xC3,
9289 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73,
9290 0xFF, 0xFD, 0x80, 0x73,
9291 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
9292 0xA1, 0x23, 0xA1, 0x01,
9293 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2,
9294 0x80, 0x00, 0x03, 0xC2,
9295 0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23,
9296 0xA0, 0x01, 0xE6, 0x84,
1da177e4
LT
9297};
9298
27c868c2
MW
9299static ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
9300static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
1da177e4
LT
9301
9302#define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
27c868c2
MW
9303static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
9304 INQUIRY,
9305 REQUEST_SENSE,
9306 READ_CAPACITY,
9307 READ_TOC,
9308 MODE_SELECT,
9309 MODE_SENSE,
9310 MODE_SELECT_10,
9311 MODE_SENSE_10,
9312 0xFF,
9313 0xFF,
9314 0xFF,
9315 0xFF,
9316 0xFF,
9317 0xFF,
9318 0xFF,
9319 0xFF
1da177e4
LT
9320};
9321
27c868c2 9322static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
1da177e4 9323{
27c868c2
MW
9324 PortAddr iop_base;
9325 ulong last_int_level;
9326 int sta;
9327 int n_q_required;
9328 int disable_syn_offset_one_fix;
9329 int i;
9330 ASC_PADDR addr;
9331 ASC_EXE_CALLBACK asc_exe_callback;
9332 ushort sg_entry_cnt = 0;
9333 ushort sg_entry_cnt_minus_one = 0;
9334 uchar target_ix;
9335 uchar tid_no;
9336 uchar sdtr_data;
9337 uchar extra_bytes;
9338 uchar scsi_cmd;
9339 uchar disable_cmd;
9340 ASC_SG_HEAD *sg_head;
9341 ASC_DCNT data_cnt;
9342
9343 iop_base = asc_dvc->iop_base;
9344 sg_head = scsiq->sg_head;
9345 asc_exe_callback = asc_dvc->exe_callback;
9346 if (asc_dvc->err_code != 0)
9347 return (ERR);
9348 if (scsiq == (ASC_SCSI_Q *)0L) {
9349 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
9350 return (ERR);
9351 }
9352 scsiq->q1.q_no = 0;
9353 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
9354 scsiq->q1.extra_bytes = 0;
9355 }
9356 sta = 0;
9357 target_ix = scsiq->q2.target_ix;
9358 tid_no = ASC_TIX_TO_TID(target_ix);
9359 n_q_required = 1;
9360 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
9361 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
9362 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
9363 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9364 AscMsgOutSDTR(asc_dvc,
9365 asc_dvc->
9366 sdtr_period_tbl[(sdtr_data >> 4) &
9367 (uchar)(asc_dvc->
9368 max_sdtr_index -
9369 1)],
9370 (uchar)(sdtr_data & (uchar)
9371 ASC_SYN_MAX_OFFSET));
9372 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
9373 }
9374 }
9375 last_int_level = DvcEnterCritical();
9376 if (asc_dvc->in_critical_cnt != 0) {
9377 DvcLeaveCritical(last_int_level);
9378 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
9379 return (ERR);
9380 }
9381 asc_dvc->in_critical_cnt++;
9382 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9383 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
9384 asc_dvc->in_critical_cnt--;
9385 DvcLeaveCritical(last_int_level);
9386 return (ERR);
9387 }
1da177e4 9388#if !CC_VERY_LONG_SG_LIST
27c868c2
MW
9389 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9390 asc_dvc->in_critical_cnt--;
9391 DvcLeaveCritical(last_int_level);
9392 return (ERR);
9393 }
1da177e4 9394#endif /* !CC_VERY_LONG_SG_LIST */
27c868c2
MW
9395 if (sg_entry_cnt == 1) {
9396 scsiq->q1.data_addr =
9397 (ADV_PADDR)sg_head->sg_list[0].addr;
9398 scsiq->q1.data_cnt =
9399 (ADV_DCNT)sg_head->sg_list[0].bytes;
9400 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
9401 }
9402 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
9403 }
9404 scsi_cmd = scsiq->cdbptr[0];
9405 disable_syn_offset_one_fix = FALSE;
9406 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
9407 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
9408 if (scsiq->q1.cntl & QC_SG_HEAD) {
9409 data_cnt = 0;
9410 for (i = 0; i < sg_entry_cnt; i++) {
9411 data_cnt +=
9412 (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
9413 bytes);
9414 }
9415 } else {
9416 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
9417 }
9418 if (data_cnt != 0UL) {
9419 if (data_cnt < 512UL) {
9420 disable_syn_offset_one_fix = TRUE;
9421 } else {
9422 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
9423 i++) {
9424 disable_cmd =
9425 _syn_offset_one_disable_cmd[i];
9426 if (disable_cmd == 0xFF) {
9427 break;
9428 }
9429 if (scsi_cmd == disable_cmd) {
9430 disable_syn_offset_one_fix =
9431 TRUE;
9432 break;
9433 }
9434 }
9435 }
9436 }
9437 }
9438 if (disable_syn_offset_one_fix) {
9439 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9440 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
9441 ASC_TAG_FLAG_DISABLE_DISCONNECT);
9442 } else {
9443 scsiq->q2.tag_code &= 0x27;
9444 }
9445 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9446 if (asc_dvc->bug_fix_cntl) {
9447 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9448 if ((scsi_cmd == READ_6) ||
9449 (scsi_cmd == READ_10)) {
9450 addr =
9451 (ADV_PADDR)le32_to_cpu(sg_head->
9452 sg_list
9453 [sg_entry_cnt_minus_one].
9454 addr) +
9455 (ADV_DCNT)le32_to_cpu(sg_head->
9456 sg_list
9457 [sg_entry_cnt_minus_one].
9458 bytes);
9459 extra_bytes =
9460 (uchar)((ushort)addr & 0x0003);
9461 if ((extra_bytes != 0)
9462 &&
9463 ((scsiq->q2.
9464 tag_code &
9465 ASC_TAG_FLAG_EXTRA_BYTES)
9466 == 0)) {
9467 scsiq->q2.tag_code |=
9468 ASC_TAG_FLAG_EXTRA_BYTES;
9469 scsiq->q1.extra_bytes =
9470 extra_bytes;
9471 data_cnt =
9472 le32_to_cpu(sg_head->
9473 sg_list
9474 [sg_entry_cnt_minus_one].
9475 bytes);
9476 data_cnt -=
9477 (ASC_DCNT) extra_bytes;
9478 sg_head->
9479 sg_list
9480 [sg_entry_cnt_minus_one].
9481 bytes =
9482 cpu_to_le32(data_cnt);
9483 }
9484 }
9485 }
9486 }
9487 sg_head->entry_to_copy = sg_head->entry_cnt;
1da177e4 9488#if CC_VERY_LONG_SG_LIST
27c868c2
MW
9489 /*
9490 * Set the sg_entry_cnt to the maximum possible. The rest of
9491 * the SG elements will be copied when the RISC completes the
9492 * SG elements that fit and halts.
9493 */
9494 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9495 sg_entry_cnt = ASC_MAX_SG_LIST;
9496 }
1da177e4 9497#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
9498 n_q_required = AscSgListToQueue(sg_entry_cnt);
9499 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
9500 (uint) n_q_required)
9501 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9502 if ((sta =
9503 AscSendScsiQueue(asc_dvc, scsiq,
9504 n_q_required)) == 1) {
9505 asc_dvc->in_critical_cnt--;
9506 if (asc_exe_callback != 0) {
9507 (*asc_exe_callback) (asc_dvc, scsiq);
9508 }
9509 DvcLeaveCritical(last_int_level);
9510 return (sta);
9511 }
9512 }
9513 } else {
9514 if (asc_dvc->bug_fix_cntl) {
9515 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9516 if ((scsi_cmd == READ_6) ||
9517 (scsi_cmd == READ_10)) {
9518 addr =
9519 le32_to_cpu(scsiq->q1.data_addr) +
9520 le32_to_cpu(scsiq->q1.data_cnt);
9521 extra_bytes =
9522 (uchar)((ushort)addr & 0x0003);
9523 if ((extra_bytes != 0)
9524 &&
9525 ((scsiq->q2.
9526 tag_code &
9527 ASC_TAG_FLAG_EXTRA_BYTES)
9528 == 0)) {
9529 data_cnt =
9530 le32_to_cpu(scsiq->q1.
9531 data_cnt);
9532 if (((ushort)data_cnt & 0x01FF)
9533 == 0) {
9534 scsiq->q2.tag_code |=
9535 ASC_TAG_FLAG_EXTRA_BYTES;
9536 data_cnt -= (ASC_DCNT)
9537 extra_bytes;
9538 scsiq->q1.data_cnt =
9539 cpu_to_le32
9540 (data_cnt);
9541 scsiq->q1.extra_bytes =
9542 extra_bytes;
9543 }
9544 }
9545 }
9546 }
9547 }
9548 n_q_required = 1;
9549 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
9550 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9551 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
9552 n_q_required)) == 1) {
9553 asc_dvc->in_critical_cnt--;
9554 if (asc_exe_callback != 0) {
9555 (*asc_exe_callback) (asc_dvc, scsiq);
9556 }
9557 DvcLeaveCritical(last_int_level);
9558 return (sta);
9559 }
9560 }
9561 }
9562 asc_dvc->in_critical_cnt--;
9563 DvcLeaveCritical(last_int_level);
9564 return (sta);
1da177e4
LT
9565}
9566
27c868c2
MW
9567static int
9568AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
1da177e4 9569{
27c868c2
MW
9570 PortAddr iop_base;
9571 uchar free_q_head;
9572 uchar next_qp;
9573 uchar tid_no;
9574 uchar target_ix;
9575 int sta;
9576
9577 iop_base = asc_dvc->iop_base;
9578 target_ix = scsiq->q2.target_ix;
9579 tid_no = ASC_TIX_TO_TID(target_ix);
9580 sta = 0;
9581 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
9582 if (n_q_required > 1) {
9583 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
9584 free_q_head, (uchar)
9585 (n_q_required)))
9586 != (uchar)ASC_QLINK_END) {
9587 asc_dvc->last_q_shortage = 0;
9588 scsiq->sg_head->queue_cnt = n_q_required - 1;
9589 scsiq->q1.q_no = free_q_head;
9590 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
9591 free_q_head)) == 1) {
9592 AscPutVarFreeQHead(iop_base, next_qp);
9593 asc_dvc->cur_total_qng += (uchar)(n_q_required);
9594 asc_dvc->cur_dvc_qng[tid_no]++;
9595 }
9596 return (sta);
9597 }
9598 } else if (n_q_required == 1) {
9599 if ((next_qp = AscAllocFreeQueue(iop_base,
9600 free_q_head)) !=
9601 ASC_QLINK_END) {
9602 scsiq->q1.q_no = free_q_head;
9603 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
9604 free_q_head)) == 1) {
9605 AscPutVarFreeQHead(iop_base, next_qp);
9606 asc_dvc->cur_total_qng++;
9607 asc_dvc->cur_dvc_qng[tid_no]++;
9608 }
9609 return (sta);
9610 }
9611 }
9612 return (sta);
1da177e4
LT
9613}
9614
27c868c2 9615static int AscSgListToQueue(int sg_list)
1da177e4 9616{
27c868c2 9617 int n_sg_list_qs;
1da177e4 9618
27c868c2
MW
9619 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
9620 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
9621 n_sg_list_qs++;
9622 return (n_sg_list_qs + 1);
1da177e4
LT
9623}
9624
27c868c2
MW
9625static uint
9626AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
1da177e4 9627{
27c868c2
MW
9628 uint cur_used_qs;
9629 uint cur_free_qs;
9630 ASC_SCSI_BIT_ID_TYPE target_id;
9631 uchar tid_no;
9632
9633 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
9634 tid_no = ASC_TIX_TO_TID(target_ix);
9635 if ((asc_dvc->unit_not_ready & target_id) ||
9636 (asc_dvc->queue_full_or_busy & target_id)) {
9637 return (0);
9638 }
9639 if (n_qs == 1) {
9640 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9641 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
9642 } else {
9643 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9644 (uint) ASC_MIN_FREE_Q;
9645 }
9646 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
9647 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
9648 if (asc_dvc->cur_dvc_qng[tid_no] >=
9649 asc_dvc->max_dvc_qng[tid_no]) {
9650 return (0);
9651 }
9652 return (cur_free_qs);
9653 }
9654 if (n_qs > 1) {
9655 if ((n_qs > asc_dvc->last_q_shortage)
9656 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
9657 asc_dvc->last_q_shortage = n_qs;
9658 }
9659 }
9660 return (0);
1da177e4
LT
9661}
9662
27c868c2 9663static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
1da177e4 9664{
27c868c2
MW
9665 ushort q_addr;
9666 uchar tid_no;
9667 uchar sdtr_data;
9668 uchar syn_period_ix;
9669 uchar syn_offset;
9670 PortAddr iop_base;
9671
9672 iop_base = asc_dvc->iop_base;
9673 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
9674 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
9675 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
9676 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9677 syn_period_ix =
9678 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
9679 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
9680 AscMsgOutSDTR(asc_dvc,
9681 asc_dvc->sdtr_period_tbl[syn_period_ix],
9682 syn_offset);
9683 scsiq->q1.cntl |= QC_MSG_OUT;
9684 }
9685 q_addr = ASC_QNO_TO_QADDR(q_no);
9686 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
9687 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9688 }
9689 scsiq->q1.status = QS_FREE;
9690 AscMemWordCopyPtrToLram(iop_base,
9691 q_addr + ASC_SCSIQ_CDB_BEG,
9692 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
9693
9694 DvcPutScsiQ(iop_base,
9695 q_addr + ASC_SCSIQ_CPY_BEG,
9696 (uchar *)&scsiq->q1.cntl,
9697 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
9698 AscWriteLramWord(iop_base,
9699 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
9700 (ushort)(((ushort)scsiq->q1.
9701 q_no << 8) | (ushort)QS_READY));
9702 return (1);
1da177e4
LT
9703}
9704
27c868c2
MW
9705static int
9706AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
1da177e4 9707{
27c868c2
MW
9708 int sta;
9709 int i;
9710 ASC_SG_HEAD *sg_head;
9711 ASC_SG_LIST_Q scsi_sg_q;
9712 ASC_DCNT saved_data_addr;
9713 ASC_DCNT saved_data_cnt;
9714 PortAddr iop_base;
9715 ushort sg_list_dwords;
9716 ushort sg_index;
9717 ushort sg_entry_cnt;
9718 ushort q_addr;
9719 uchar next_qp;
9720
9721 iop_base = asc_dvc->iop_base;
9722 sg_head = scsiq->sg_head;
9723 saved_data_addr = scsiq->q1.data_addr;
9724 saved_data_cnt = scsiq->q1.data_cnt;
9725 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
9726 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
1da177e4 9727#if CC_VERY_LONG_SG_LIST
27c868c2
MW
9728 /*
9729 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
9730 * then not all SG elements will fit in the allocated queues.
9731 * The rest of the SG elements will be copied when the RISC
9732 * completes the SG elements that fit and halts.
9733 */
9734 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9735 /*
9736 * Set sg_entry_cnt to be the number of SG elements that
9737 * will fit in the allocated SG queues. It is minus 1, because
9738 * the first SG element is handled above. ASC_MAX_SG_LIST is
9739 * already inflated by 1 to account for this. For example it
9740 * may be 50 which is 1 + 7 queues * 7 SG elements.
9741 */
9742 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
9743
9744 /*
9745 * Keep track of remaining number of SG elements that will
9746 * need to be handled from a_isr.c.
9747 */
9748 scsiq->remain_sg_entry_cnt =
9749 sg_head->entry_cnt - ASC_MAX_SG_LIST;
9750 } else {
1da177e4 9751#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
9752 /*
9753 * Set sg_entry_cnt to be the number of SG elements that
9754 * will fit in the allocated SG queues. It is minus 1, because
9755 * the first SG element is handled above.
9756 */
9757 sg_entry_cnt = sg_head->entry_cnt - 1;
1da177e4 9758#if CC_VERY_LONG_SG_LIST
27c868c2 9759 }
1da177e4 9760#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
9761 if (sg_entry_cnt != 0) {
9762 scsiq->q1.cntl |= QC_SG_HEAD;
9763 q_addr = ASC_QNO_TO_QADDR(q_no);
9764 sg_index = 1;
9765 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
9766 scsi_sg_q.sg_head_qp = q_no;
9767 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
9768 for (i = 0; i < sg_head->queue_cnt; i++) {
9769 scsi_sg_q.seq_no = i + 1;
9770 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
9771 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
9772 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
9773 if (i == 0) {
9774 scsi_sg_q.sg_list_cnt =
9775 ASC_SG_LIST_PER_Q;
9776 scsi_sg_q.sg_cur_list_cnt =
9777 ASC_SG_LIST_PER_Q;
9778 } else {
9779 scsi_sg_q.sg_list_cnt =
9780 ASC_SG_LIST_PER_Q - 1;
9781 scsi_sg_q.sg_cur_list_cnt =
9782 ASC_SG_LIST_PER_Q - 1;
9783 }
9784 } else {
1da177e4 9785#if CC_VERY_LONG_SG_LIST
27c868c2
MW
9786 /*
9787 * This is the last SG queue in the list of
9788 * allocated SG queues. If there are more
9789 * SG elements than will fit in the allocated
9790 * queues, then set the QCSG_SG_XFER_MORE flag.
9791 */
9792 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9793 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
9794 } else {
1da177e4 9795#endif /* CC_VERY_LONG_SG_LIST */
27c868c2 9796 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
1da177e4 9797#if CC_VERY_LONG_SG_LIST
27c868c2 9798 }
1da177e4 9799#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
9800 sg_list_dwords = sg_entry_cnt << 1;
9801 if (i == 0) {
9802 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
9803 scsi_sg_q.sg_cur_list_cnt =
9804 sg_entry_cnt;
9805 } else {
9806 scsi_sg_q.sg_list_cnt =
9807 sg_entry_cnt - 1;
9808 scsi_sg_q.sg_cur_list_cnt =
9809 sg_entry_cnt - 1;
9810 }
9811 sg_entry_cnt = 0;
9812 }
9813 next_qp = AscReadLramByte(iop_base,
9814 (ushort)(q_addr +
9815 ASC_SCSIQ_B_FWD));
9816 scsi_sg_q.q_no = next_qp;
9817 q_addr = ASC_QNO_TO_QADDR(next_qp);
9818 AscMemWordCopyPtrToLram(iop_base,
9819 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
9820 (uchar *)&scsi_sg_q,
9821 sizeof(ASC_SG_LIST_Q) >> 1);
9822 AscMemDWordCopyPtrToLram(iop_base,
9823 q_addr + ASC_SGQ_LIST_BEG,
9824 (uchar *)&sg_head->
9825 sg_list[sg_index],
9826 sg_list_dwords);
9827 sg_index += ASC_SG_LIST_PER_Q;
9828 scsiq->next_sg_index = sg_index;
9829 }
9830 } else {
9831 scsiq->q1.cntl &= ~QC_SG_HEAD;
9832 }
9833 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
9834 scsiq->q1.data_addr = saved_data_addr;
9835 scsiq->q1.data_cnt = saved_data_cnt;
9836 return (sta);
1da177e4
LT
9837}
9838
27c868c2
MW
9839static int
9840AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
1da177e4 9841{
27c868c2 9842 int sta = FALSE;
1da177e4 9843
27c868c2
MW
9844 if (AscHostReqRiscHalt(iop_base)) {
9845 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9846 AscStartChip(iop_base);
9847 return (sta);
9848 }
9849 return (sta);
1da177e4
LT
9850}
9851
27c868c2 9852static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
1da177e4 9853{
27c868c2
MW
9854 ASC_SCSI_BIT_ID_TYPE org_id;
9855 int i;
9856 int sta = TRUE;
9857
9858 AscSetBank(iop_base, 1);
9859 org_id = AscReadChipDvcID(iop_base);
9860 for (i = 0; i <= ASC_MAX_TID; i++) {
9861 if (org_id == (0x01 << i))
9862 break;
9863 }
9864 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
9865 AscWriteChipDvcID(iop_base, id);
9866 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
9867 AscSetBank(iop_base, 0);
9868 AscSetChipSyn(iop_base, sdtr_data);
9869 if (AscGetChipSyn(iop_base) != sdtr_data) {
9870 sta = FALSE;
9871 }
9872 } else {
9873 sta = FALSE;
9874 }
9875 AscSetBank(iop_base, 1);
9876 AscWriteChipDvcID(iop_base, org_id);
9877 AscSetBank(iop_base, 0);
9878 return (sta);
9879}
1da177e4 9880
27c868c2 9881static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
1da177e4 9882{
27c868c2
MW
9883 uchar i;
9884 ushort s_addr;
9885 PortAddr iop_base;
9886 ushort warn_code;
9887
9888 iop_base = asc_dvc->iop_base;
9889 warn_code = 0;
9890 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
9891 (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
9892 64) >> 1)
9893 );
9894 i = ASC_MIN_ACTIVE_QNO;
9895 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
9896 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9897 (uchar)(i + 1));
9898 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9899 (uchar)(asc_dvc->max_total_qng));
9900 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9901 (uchar)i);
9902 i++;
9903 s_addr += ASC_QBLK_SIZE;
9904 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
9905 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9906 (uchar)(i + 1));
9907 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9908 (uchar)(i - 1));
9909 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9910 (uchar)i);
9911 }
9912 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9913 (uchar)ASC_QLINK_END);
9914 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9915 (uchar)(asc_dvc->max_total_qng - 1));
9916 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9917 (uchar)asc_dvc->max_total_qng);
9918 i++;
9919 s_addr += ASC_QBLK_SIZE;
9920 for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
9921 i++, s_addr += ASC_QBLK_SIZE) {
9922 AscWriteLramByte(iop_base,
9923 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
9924 AscWriteLramByte(iop_base,
9925 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
9926 AscWriteLramByte(iop_base,
9927 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
9928 }
9929 return (warn_code);
1da177e4
LT
9930}
9931
27c868c2 9932static ushort AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
1da177e4 9933{
27c868c2
MW
9934 PortAddr iop_base;
9935 int i;
9936 ushort lram_addr;
9937
9938 iop_base = asc_dvc->iop_base;
9939 AscPutRiscVarFreeQHead(iop_base, 1);
9940 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
9941 AscPutVarFreeQHead(iop_base, 1);
9942 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
9943 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
9944 (uchar)((int)asc_dvc->max_total_qng + 1));
9945 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
9946 (uchar)((int)asc_dvc->max_total_qng + 2));
9947 AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
9948 asc_dvc->max_total_qng);
9949 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
9950 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9951 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
9952 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
9953 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
9954 AscPutQDoneInProgress(iop_base, 0);
9955 lram_addr = ASC_QADR_BEG;
9956 for (i = 0; i < 32; i++, lram_addr += 2) {
9957 AscWriteLramWord(iop_base, lram_addr, 0);
9958 }
9959 return (0);
1da177e4
LT
9960}
9961
27c868c2 9962static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
1da177e4 9963{
27c868c2
MW
9964 if (asc_dvc->err_code == 0) {
9965 asc_dvc->err_code = err_code;
9966 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
9967 err_code);
9968 }
9969 return (err_code);
1da177e4
LT
9970}
9971
27c868c2
MW
9972static uchar
9973AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
1da177e4 9974{
27c868c2
MW
9975 EXT_MSG sdtr_buf;
9976 uchar sdtr_period_index;
9977 PortAddr iop_base;
9978
9979 iop_base = asc_dvc->iop_base;
9980 sdtr_buf.msg_type = MS_EXTEND;
9981 sdtr_buf.msg_len = MS_SDTR_LEN;
9982 sdtr_buf.msg_req = MS_SDTR_CODE;
9983 sdtr_buf.xfer_period = sdtr_period;
9984 sdtr_offset &= ASC_SYN_MAX_OFFSET;
9985 sdtr_buf.req_ack_offset = sdtr_offset;
9986 if ((sdtr_period_index =
9987 AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
9988 asc_dvc->max_sdtr_index) {
9989 AscMemWordCopyPtrToLram(iop_base,
9990 ASCV_MSGOUT_BEG,
9991 (uchar *)&sdtr_buf,
9992 sizeof(EXT_MSG) >> 1);
9993 return ((sdtr_period_index << 4) | sdtr_offset);
9994 } else {
9995
9996 sdtr_buf.req_ack_offset = 0;
9997 AscMemWordCopyPtrToLram(iop_base,
9998 ASCV_MSGOUT_BEG,
9999 (uchar *)&sdtr_buf,
10000 sizeof(EXT_MSG) >> 1);
10001 return (0);
10002 }
1da177e4
LT
10003}
10004
27c868c2
MW
10005static uchar
10006AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
1da177e4 10007{
27c868c2
MW
10008 uchar byte;
10009 uchar sdtr_period_ix;
10010
10011 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
10012 if ((sdtr_period_ix > asc_dvc->max_sdtr_index)
10013 ) {
10014 return (0xFF);
10015 }
10016 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
10017 return (byte);
1da177e4
LT
10018}
10019
27c868c2 10020static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
1da177e4 10021{
27c868c2
MW
10022 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
10023 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
10024 return;
1da177e4
LT
10025}
10026
27c868c2 10027static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
1da177e4 10028{
27c868c2
MW
10029 uchar *period_table;
10030 int max_index;
10031 int min_index;
10032 int i;
10033
10034 period_table = asc_dvc->sdtr_period_tbl;
10035 max_index = (int)asc_dvc->max_sdtr_index;
10036 min_index = (int)asc_dvc->host_init_sdtr_index;
10037 if ((syn_time <= period_table[max_index])) {
10038 for (i = min_index; i < (max_index - 1); i++) {
10039 if (syn_time <= period_table[i]) {
10040 return ((uchar)i);
10041 }
10042 }
10043 return ((uchar)max_index);
10044 } else {
10045 return ((uchar)(max_index + 1));
10046 }
1da177e4
LT
10047}
10048
27c868c2 10049static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
1da177e4 10050{
27c868c2
MW
10051 ushort q_addr;
10052 uchar next_qp;
10053 uchar q_status;
10054
10055 q_addr = ASC_QNO_TO_QADDR(free_q_head);
10056 q_status = (uchar)AscReadLramByte(iop_base,
10057 (ushort)(q_addr +
10058 ASC_SCSIQ_B_STATUS));
10059 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
10060 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
10061 return (next_qp);
10062 }
10063 return (ASC_QLINK_END);
1da177e4
LT
10064}
10065
27c868c2
MW
10066static uchar
10067AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
1da177e4 10068{
27c868c2 10069 uchar i;
1da177e4 10070
27c868c2
MW
10071 for (i = 0; i < n_free_q; i++) {
10072 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
10073 == ASC_QLINK_END) {
10074 return (ASC_QLINK_END);
10075 }
10076 }
10077 return (free_q_head);
1da177e4
LT
10078}
10079
27c868c2 10080static int AscHostReqRiscHalt(PortAddr iop_base)
1da177e4 10081{
27c868c2
MW
10082 int count = 0;
10083 int sta = 0;
10084 uchar saved_stop_code;
10085
10086 if (AscIsChipHalted(iop_base))
10087 return (1);
10088 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
10089 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
10090 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
10091 do {
10092 if (AscIsChipHalted(iop_base)) {
10093 sta = 1;
10094 break;
10095 }
10096 DvcSleepMilliSecond(100);
10097 } while (count++ < 20);
10098 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
10099 return (sta);
1da177e4
LT
10100}
10101
27c868c2 10102static int AscStopQueueExe(PortAddr iop_base)
1da177e4 10103{
27c868c2
MW
10104 int count = 0;
10105
10106 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
10107 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
10108 ASC_STOP_REQ_RISC_STOP);
10109 do {
10110 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
10111 ASC_STOP_ACK_RISC_STOP) {
10112 return (1);
10113 }
10114 DvcSleepMilliSecond(100);
10115 } while (count++ < 20);
10116 }
10117 return (0);
1da177e4
LT
10118}
10119
27c868c2 10120static void DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
1da177e4 10121{
27c868c2 10122 udelay(micro_sec);
1da177e4
LT
10123}
10124
27c868c2 10125static void DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
1da177e4 10126{
27c868c2 10127 udelay((nano_sec + 999) / 1000);
1da177e4
LT
10128}
10129
27c868c2 10130static int AscStartChip(PortAddr iop_base)
1da177e4 10131{
27c868c2
MW
10132 AscSetChipControl(iop_base, 0);
10133 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
10134 return (0);
10135 }
10136 return (1);
1da177e4
LT
10137}
10138
27c868c2 10139static int AscStopChip(PortAddr iop_base)
1da177e4 10140{
27c868c2
MW
10141 uchar cc_val;
10142
10143 cc_val =
10144 AscGetChipControl(iop_base) &
10145 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
10146 AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
10147 AscSetChipIH(iop_base, INS_HALT);
10148 AscSetChipIH(iop_base, INS_RFLAG_WTM);
10149 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
10150 return (0);
10151 }
10152 return (1);
1da177e4
LT
10153}
10154
27c868c2 10155static int AscIsChipHalted(PortAddr iop_base)
1da177e4 10156{
27c868c2
MW
10157 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
10158 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
10159 return (1);
10160 }
10161 }
10162 return (0);
1da177e4
LT
10163}
10164
27c868c2 10165static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
1da177e4 10166{
27c868c2
MW
10167 AscSetBank(iop_base, 1);
10168 AscWriteChipIH(iop_base, ins_code);
10169 AscSetBank(iop_base, 0);
10170 return;
1da177e4
LT
10171}
10172
27c868c2 10173static void AscAckInterrupt(PortAddr iop_base)
1da177e4 10174{
27c868c2
MW
10175 uchar host_flag;
10176 uchar risc_flag;
10177 ushort loop;
10178
10179 loop = 0;
10180 do {
10181 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
10182 if (loop++ > 0x7FFF) {
10183 break;
10184 }
10185 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
10186 host_flag =
10187 AscReadLramByte(iop_base,
10188 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
10189 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10190 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
10191 AscSetChipStatus(iop_base, CIW_INT_ACK);
10192 loop = 0;
10193 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
10194 AscSetChipStatus(iop_base, CIW_INT_ACK);
10195 if (loop++ > 3) {
10196 break;
10197 }
10198 }
10199 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10200 return;
1da177e4
LT
10201}
10202
27c868c2 10203static void AscDisableInterrupt(PortAddr iop_base)
1da177e4 10204{
27c868c2 10205 ushort cfg;
1da177e4 10206
27c868c2
MW
10207 cfg = AscGetChipCfgLsw(iop_base);
10208 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
10209 return;
1da177e4
LT
10210}
10211
27c868c2 10212static void AscEnableInterrupt(PortAddr iop_base)
1da177e4 10213{
27c868c2 10214 ushort cfg;
1da177e4 10215
27c868c2
MW
10216 cfg = AscGetChipCfgLsw(iop_base);
10217 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
10218 return;
1da177e4
LT
10219}
10220
27c868c2 10221static void AscSetBank(PortAddr iop_base, uchar bank)
1da177e4 10222{
27c868c2
MW
10223 uchar val;
10224
10225 val = AscGetChipControl(iop_base) &
10226 (~
10227 (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
10228 CC_CHIP_RESET));
10229 if (bank == 1) {
10230 val |= CC_BANK_ONE;
10231 } else if (bank == 2) {
10232 val |= CC_DIAG | CC_BANK_ONE;
10233 } else {
10234 val &= ~CC_BANK_ONE;
10235 }
10236 AscSetChipControl(iop_base, val);
10237 return;
1da177e4
LT
10238}
10239
27c868c2 10240static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
1da177e4 10241{
27c868c2
MW
10242 PortAddr iop_base;
10243 int i = 10;
1da177e4 10244
27c868c2
MW
10245 iop_base = asc_dvc->iop_base;
10246 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
10247 && (i-- > 0)) {
10248 DvcSleepMilliSecond(100);
10249 }
10250 AscStopChip(iop_base);
10251 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
10252 DvcDelayNanoSecond(asc_dvc, 60000);
10253 AscSetChipIH(iop_base, INS_RFLAG_WTM);
10254 AscSetChipIH(iop_base, INS_HALT);
10255 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
10256 AscSetChipControl(iop_base, CC_HALT);
10257 DvcSleepMilliSecond(200);
10258 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10259 AscSetChipStatus(iop_base, 0);
10260 return (AscIsChipHalted(iop_base));
1da177e4
LT
10261}
10262
78e77d8b 10263static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
1da177e4 10264{
27c868c2
MW
10265 if (bus_type & ASC_IS_ISA)
10266 return (ASC_MAX_ISA_DMA_COUNT);
10267 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
10268 return (ASC_MAX_VL_DMA_COUNT);
10269 return (ASC_MAX_PCI_DMA_COUNT);
1da177e4
LT
10270}
10271
10272#ifdef CONFIG_ISA
78e77d8b 10273static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
1da177e4 10274{
27c868c2
MW
10275 ushort channel;
10276
10277 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
10278 if (channel == 0x03)
10279 return (0);
10280 else if (channel == 0x00)
10281 return (7);
10282 return (channel + 4);
1da177e4
LT
10283}
10284
78e77d8b 10285static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
1da177e4 10286{
27c868c2
MW
10287 ushort cfg_lsw;
10288 uchar value;
10289
10290 if ((dma_channel >= 5) && (dma_channel <= 7)) {
10291 if (dma_channel == 7)
10292 value = 0x00;
10293 else
10294 value = dma_channel - 4;
10295 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
10296 cfg_lsw |= value;
10297 AscSetChipCfgLsw(iop_base, cfg_lsw);
10298 return (AscGetIsaDmaChannel(iop_base));
10299 }
10300 return (0);
1da177e4
LT
10301}
10302
78e77d8b 10303static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
1da177e4 10304{
27c868c2
MW
10305 speed_value &= 0x07;
10306 AscSetBank(iop_base, 1);
10307 AscWriteChipDmaSpeed(iop_base, speed_value);
10308 AscSetBank(iop_base, 0);
10309 return (AscGetIsaDmaSpeed(iop_base));
1da177e4
LT
10310}
10311
78e77d8b 10312static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
1da177e4 10313{
27c868c2 10314 uchar speed_value;
1da177e4 10315
27c868c2
MW
10316 AscSetBank(iop_base, 1);
10317 speed_value = AscReadChipDmaSpeed(iop_base);
10318 speed_value &= 0x07;
10319 AscSetBank(iop_base, 0);
10320 return (speed_value);
1da177e4
LT
10321}
10322#endif /* CONFIG_ISA */
10323
78e77d8b 10324static ushort __devinit
27c868c2 10325AscReadPCIConfigWord(ASC_DVC_VAR *asc_dvc, ushort pci_config_offset)
1da177e4 10326{
27c868c2 10327 uchar lsb, msb;
1da177e4 10328
27c868c2
MW
10329 lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
10330 msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
10331 return ((ushort)((msb << 8) | lsb));
1da177e4
LT
10332}
10333
78e77d8b 10334static ushort __devinit AscInitGetConfig(ASC_DVC_VAR *asc_dvc)
1da177e4 10335{
27c868c2
MW
10336 ushort warn_code;
10337 PortAddr iop_base;
10338 ushort PCIDeviceID;
10339 ushort PCIVendorID;
10340 uchar PCIRevisionID;
10341 uchar prevCmdRegBits;
10342
10343 warn_code = 0;
10344 iop_base = asc_dvc->iop_base;
10345 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
10346 if (asc_dvc->err_code != 0) {
10347 return (UW_ERR);
10348 }
10349 if (asc_dvc->bus_type == ASC_IS_PCI) {
10350 PCIVendorID = AscReadPCIConfigWord(asc_dvc,
10351 AscPCIConfigVendorIDRegister);
10352
10353 PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
10354 AscPCIConfigDeviceIDRegister);
10355
10356 PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
10357 AscPCIConfigRevisionIDRegister);
10358
10359 if (PCIVendorID != PCI_VENDOR_ID_ASP) {
10360 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10361 }
10362 prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
10363 AscPCIConfigCommandRegister);
10364
10365 if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
10366 AscPCICmdRegBits_IOMemBusMaster) {
10367 DvcWritePCIConfigByte(asc_dvc,
10368 AscPCIConfigCommandRegister,
10369 (prevCmdRegBits |
10370 AscPCICmdRegBits_IOMemBusMaster));
10371
10372 if ((DvcReadPCIConfigByte(asc_dvc,
10373 AscPCIConfigCommandRegister)
10374 & AscPCICmdRegBits_IOMemBusMaster)
10375 != AscPCICmdRegBits_IOMemBusMaster) {
10376 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10377 }
10378 }
10379 if ((PCIDeviceID == PCI_DEVICE_ID_ASP_1200A) ||
10380 (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940)) {
10381 DvcWritePCIConfigByte(asc_dvc,
10382 AscPCIConfigLatencyTimer, 0x00);
10383 if (DvcReadPCIConfigByte
10384 (asc_dvc, AscPCIConfigLatencyTimer)
10385 != 0x00) {
10386 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10387 }
10388 } else if (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940U) {
10389 if (DvcReadPCIConfigByte(asc_dvc,
10390 AscPCIConfigLatencyTimer) <
10391 0x20) {
10392 DvcWritePCIConfigByte(asc_dvc,
10393 AscPCIConfigLatencyTimer,
10394 0x20);
10395
10396 if (DvcReadPCIConfigByte(asc_dvc,
10397 AscPCIConfigLatencyTimer)
10398 < 0x20) {
10399 warn_code |=
10400 ASC_WARN_SET_PCI_CONFIG_SPACE;
10401 }
10402 }
10403 }
10404 }
1da177e4 10405
27c868c2
MW
10406 if (AscFindSignature(iop_base)) {
10407 warn_code |= AscInitAscDvcVar(asc_dvc);
10408 warn_code |= AscInitFromEEP(asc_dvc);
10409 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
10410 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
10411 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
10412 }
10413 } else {
10414 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10415 }
10416 return (warn_code);
1da177e4
LT
10417}
10418
78e77d8b 10419static ushort __devinit AscInitSetConfig(ASC_DVC_VAR *asc_dvc)
1da177e4 10420{
27c868c2
MW
10421 ushort warn_code = 0;
10422
10423 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
10424 if (asc_dvc->err_code != 0)
10425 return (UW_ERR);
10426 if (AscFindSignature(asc_dvc->iop_base)) {
10427 warn_code |= AscInitFromAscDvcVar(asc_dvc);
10428 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
10429 } else {
10430 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10431 }
10432 return (warn_code);
1da177e4
LT
10433}
10434
78e77d8b 10435static ushort __devinit AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc)
1da177e4 10436{
27c868c2
MW
10437 PortAddr iop_base;
10438 ushort cfg_msw;
10439 ushort warn_code;
10440 ushort pci_device_id = 0;
1da177e4 10441
27c868c2 10442 iop_base = asc_dvc->iop_base;
1da177e4 10443#ifdef CONFIG_PCI
27c868c2
MW
10444 if (asc_dvc->cfg->dev)
10445 pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device;
1da177e4 10446#endif
27c868c2
MW
10447 warn_code = 0;
10448 cfg_msw = AscGetChipCfgMsw(iop_base);
10449 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10450 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10451 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10452 AscSetChipCfgMsw(iop_base, cfg_msw);
10453 }
10454 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
10455 asc_dvc->cfg->cmd_qng_enabled) {
10456 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
10457 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10458 }
10459 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10460 warn_code |= ASC_WARN_AUTO_CONFIG;
10461 }
10462 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
10463 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
10464 != asc_dvc->irq_no) {
10465 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
10466 }
10467 }
10468 if (asc_dvc->bus_type & ASC_IS_PCI) {
10469 cfg_msw &= 0xFFC0;
10470 AscSetChipCfgMsw(iop_base, cfg_msw);
10471 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
10472 } else {
10473 if ((pci_device_id == PCI_DEVICE_ID_ASP_1200A) ||
10474 (pci_device_id == PCI_DEVICE_ID_ASP_ABP940)) {
10475 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
10476 asc_dvc->bug_fix_cntl |=
10477 ASC_BUG_FIX_ASYN_USE_SYN;
10478 }
10479 }
10480 } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
10481 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
10482 == ASC_CHIP_VER_ASYN_BUG) {
10483 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
10484 }
10485 }
10486 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
10487 asc_dvc->cfg->chip_scsi_id) {
10488 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
10489 }
1da177e4 10490#ifdef CONFIG_ISA
27c868c2
MW
10491 if (asc_dvc->bus_type & ASC_IS_ISA) {
10492 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
10493 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
10494 }
1da177e4 10495#endif /* CONFIG_ISA */
27c868c2 10496 return (warn_code);
1da177e4
LT
10497}
10498
27c868c2 10499static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
1da177e4 10500{
27c868c2
MW
10501 ushort warn_code;
10502 PortAddr iop_base;
10503
10504 iop_base = asc_dvc->iop_base;
10505 warn_code = 0;
10506 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
10507 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
10508 AscResetChipAndScsiBus(asc_dvc);
10509 DvcSleepMilliSecond((ASC_DCNT)
10510 ((ushort)asc_dvc->scsi_reset_wait * 1000));
10511 }
10512 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
10513 if (asc_dvc->err_code != 0)
10514 return (UW_ERR);
10515 if (!AscFindSignature(asc_dvc->iop_base)) {
10516 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10517 return (warn_code);
10518 }
10519 AscDisableInterrupt(iop_base);
10520 warn_code |= AscInitLram(asc_dvc);
10521 if (asc_dvc->err_code != 0)
10522 return (UW_ERR);
10523 ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
10524 (ulong)_asc_mcode_chksum);
10525 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
10526 _asc_mcode_size) != _asc_mcode_chksum) {
10527 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
10528 return (warn_code);
10529 }
10530 warn_code |= AscInitMicroCodeVar(asc_dvc);
10531 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
10532 AscEnableInterrupt(iop_base);
10533 return (warn_code);
1da177e4
LT
10534}
10535
78e77d8b 10536static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
1da177e4 10537{
27c868c2
MW
10538 int i;
10539 PortAddr iop_base;
10540 ushort warn_code;
10541 uchar chip_version;
10542
10543 iop_base = asc_dvc->iop_base;
10544 warn_code = 0;
10545 asc_dvc->err_code = 0;
10546 if ((asc_dvc->bus_type &
10547 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
10548 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
10549 }
10550 AscSetChipControl(iop_base, CC_HALT);
10551 AscSetChipStatus(iop_base, 0);
10552 asc_dvc->bug_fix_cntl = 0;
10553 asc_dvc->pci_fix_asyn_xfer = 0;
10554 asc_dvc->pci_fix_asyn_xfer_always = 0;
10555 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
10556 asc_dvc->sdtr_done = 0;
10557 asc_dvc->cur_total_qng = 0;
10558 asc_dvc->is_in_int = 0;
10559 asc_dvc->in_critical_cnt = 0;
10560 asc_dvc->last_q_shortage = 0;
10561 asc_dvc->use_tagged_qng = 0;
10562 asc_dvc->no_scam = 0;
10563 asc_dvc->unit_not_ready = 0;
10564 asc_dvc->queue_full_or_busy = 0;
10565 asc_dvc->redo_scam = 0;
10566 asc_dvc->res2 = 0;
10567 asc_dvc->host_init_sdtr_index = 0;
10568 asc_dvc->cfg->can_tagged_qng = 0;
10569 asc_dvc->cfg->cmd_qng_enabled = 0;
10570 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
10571 asc_dvc->init_sdtr = 0;
10572 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
10573 asc_dvc->scsi_reset_wait = 3;
10574 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
10575 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
10576 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
10577 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
10578 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
10579 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
10580 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
10581 ASC_LIB_VERSION_MINOR;
10582 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
10583 asc_dvc->cfg->chip_version = chip_version;
10584 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
10585 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
10586 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
10587 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
10588 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
10589 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
10590 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
10591 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
10592 asc_dvc->max_sdtr_index = 7;
10593 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
10594 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
10595 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
10596 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
10597 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
10598 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
10599 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
10600 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
10601 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
10602 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
10603 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
10604 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
10605 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
10606 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
10607 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
10608 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
10609 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
10610 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
10611 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
10612 asc_dvc->max_sdtr_index = 15;
10613 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
10614 AscSetExtraControl(iop_base,
10615 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10616 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
10617 AscSetExtraControl(iop_base,
10618 (SEC_ACTIVE_NEGATE |
10619 SEC_ENABLE_FILTER));
10620 }
10621 }
10622 if (asc_dvc->bus_type == ASC_IS_PCI) {
10623 AscSetExtraControl(iop_base,
10624 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10625 }
1da177e4 10626
27c868c2
MW
10627 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
10628 if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
10629 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
10630 asc_dvc->bus_type = ASC_IS_ISAPNP;
10631 }
1da177e4 10632#ifdef CONFIG_ISA
27c868c2
MW
10633 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
10634 asc_dvc->cfg->isa_dma_channel =
10635 (uchar)AscGetIsaDmaChannel(iop_base);
10636 }
1da177e4 10637#endif /* CONFIG_ISA */
27c868c2
MW
10638 for (i = 0; i <= ASC_MAX_TID; i++) {
10639 asc_dvc->cur_dvc_qng[i] = 0;
10640 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
10641 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
10642 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
10643 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
10644 }
10645 return (warn_code);
1da177e4
LT
10646}
10647
78e77d8b 10648static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
1da177e4 10649{
27c868c2
MW
10650 ASCEEP_CONFIG eep_config_buf;
10651 ASCEEP_CONFIG *eep_config;
10652 PortAddr iop_base;
10653 ushort chksum;
10654 ushort warn_code;
10655 ushort cfg_msw, cfg_lsw;
10656 int i;
10657 int write_eep = 0;
10658
10659 iop_base = asc_dvc->iop_base;
10660 warn_code = 0;
10661 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
10662 AscStopQueueExe(iop_base);
10663 if ((AscStopChip(iop_base) == FALSE) ||
10664 (AscGetChipScsiCtrl(iop_base) != 0)) {
10665 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
10666 AscResetChipAndScsiBus(asc_dvc);
10667 DvcSleepMilliSecond((ASC_DCNT)
10668 ((ushort)asc_dvc->scsi_reset_wait * 1000));
10669 }
10670 if (AscIsChipHalted(iop_base) == FALSE) {
10671 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10672 return (warn_code);
10673 }
10674 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10675 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10676 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10677 return (warn_code);
10678 }
10679 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
10680 cfg_msw = AscGetChipCfgMsw(iop_base);
10681 cfg_lsw = AscGetChipCfgLsw(iop_base);
10682 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10683 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10684 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10685 AscSetChipCfgMsw(iop_base, cfg_msw);
10686 }
10687 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
10688 ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
10689 if (chksum == 0) {
10690 chksum = 0xaa55;
10691 }
10692 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10693 warn_code |= ASC_WARN_AUTO_CONFIG;
10694 if (asc_dvc->cfg->chip_version == 3) {
10695 if (eep_config->cfg_lsw != cfg_lsw) {
10696 warn_code |= ASC_WARN_EEPROM_RECOVER;
10697 eep_config->cfg_lsw =
10698 AscGetChipCfgLsw(iop_base);
10699 }
10700 if (eep_config->cfg_msw != cfg_msw) {
10701 warn_code |= ASC_WARN_EEPROM_RECOVER;
10702 eep_config->cfg_msw =
10703 AscGetChipCfgMsw(iop_base);
10704 }
10705 }
10706 }
10707 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
10708 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
10709 ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
10710 eep_config->chksum);
10711 if (chksum != eep_config->chksum) {
10712 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
10713 ASC_CHIP_VER_PCI_ULTRA_3050) {
10714 ASC_DBG(1,
10715 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
10716 eep_config->init_sdtr = 0xFF;
10717 eep_config->disc_enable = 0xFF;
10718 eep_config->start_motor = 0xFF;
10719 eep_config->use_cmd_qng = 0;
10720 eep_config->max_total_qng = 0xF0;
10721 eep_config->max_tag_qng = 0x20;
10722 eep_config->cntl = 0xBFFF;
10723 ASC_EEP_SET_CHIP_ID(eep_config, 7);
10724 eep_config->no_scam = 0;
10725 eep_config->adapter_info[0] = 0;
10726 eep_config->adapter_info[1] = 0;
10727 eep_config->adapter_info[2] = 0;
10728 eep_config->adapter_info[3] = 0;
10729 eep_config->adapter_info[4] = 0;
10730 /* Indicate EEPROM-less board. */
10731 eep_config->adapter_info[5] = 0xBB;
10732 } else {
10733 ASC_PRINT
10734 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
10735 write_eep = 1;
10736 warn_code |= ASC_WARN_EEPROM_CHKSUM;
10737 }
10738 }
10739 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
10740 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
10741 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
10742 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
10743 asc_dvc->start_motor = eep_config->start_motor;
10744 asc_dvc->dvc_cntl = eep_config->cntl;
10745 asc_dvc->no_scam = eep_config->no_scam;
10746 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
10747 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
10748 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
10749 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
10750 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
10751 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
10752 if (!AscTestExternalLram(asc_dvc)) {
10753 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
10754 ASC_IS_PCI_ULTRA)) {
10755 eep_config->max_total_qng =
10756 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
10757 eep_config->max_tag_qng =
10758 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
10759 } else {
10760 eep_config->cfg_msw |= 0x0800;
10761 cfg_msw |= 0x0800;
10762 AscSetChipCfgMsw(iop_base, cfg_msw);
10763 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
10764 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
10765 }
10766 } else {
10767 }
10768 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
10769 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
10770 }
10771 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
10772 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
10773 }
10774 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
10775 eep_config->max_tag_qng = eep_config->max_total_qng;
10776 }
10777 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
10778 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
10779 }
10780 asc_dvc->max_total_qng = eep_config->max_total_qng;
10781 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
10782 eep_config->use_cmd_qng) {
10783 eep_config->disc_enable = eep_config->use_cmd_qng;
10784 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10785 }
10786 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
10787 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
10788 }
10789 ASC_EEP_SET_CHIP_ID(eep_config,
10790 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
10791 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
10792 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
10793 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
10794 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
10795 }
1da177e4 10796
27c868c2
MW
10797 for (i = 0; i <= ASC_MAX_TID; i++) {
10798 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
10799 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
10800 asc_dvc->cfg->sdtr_period_offset[i] =
10801 (uchar)(ASC_DEF_SDTR_OFFSET |
10802 (asc_dvc->host_init_sdtr_index << 4));
10803 }
10804 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
10805 if (write_eep) {
10806 if ((i =
10807 AscSetEEPConfig(iop_base, eep_config,
10808 asc_dvc->bus_type)) != 0) {
10809 ASC_PRINT1
10810 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
10811 i);
10812 } else {
10813 ASC_PRINT
10814 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
10815 }
10816 }
10817 return (warn_code);
1da177e4
LT
10818}
10819
27c868c2 10820static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
1da177e4 10821{
27c868c2
MW
10822 int i;
10823 ushort warn_code;
10824 PortAddr iop_base;
10825 ASC_PADDR phy_addr;
10826 ASC_DCNT phy_size;
10827
10828 iop_base = asc_dvc->iop_base;
10829 warn_code = 0;
10830 for (i = 0; i <= ASC_MAX_TID; i++) {
10831 AscPutMCodeInitSDTRAtID(iop_base, i,
10832 asc_dvc->cfg->sdtr_period_offset[i]
10833 );
10834 }
1da177e4 10835
27c868c2
MW
10836 AscInitQLinkVar(asc_dvc);
10837 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
10838 asc_dvc->cfg->disc_enable);
10839 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
10840 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
10841
10842 /* Align overrun buffer on an 8 byte boundary. */
10843 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
10844 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
10845 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
10846 (uchar *)&phy_addr, 1);
10847 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
10848 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
10849 (uchar *)&phy_size, 1);
10850
10851 asc_dvc->cfg->mcode_date =
10852 AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
10853 asc_dvc->cfg->mcode_version =
10854 AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
10855
10856 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10857 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10858 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10859 return (warn_code);
10860 }
10861 if (AscStartChip(iop_base) != 1) {
10862 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10863 return (warn_code);
10864 }
1da177e4 10865
27c868c2 10866 return (warn_code);
1da177e4
LT
10867}
10868
78e77d8b 10869static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
1da177e4 10870{
27c868c2
MW
10871 PortAddr iop_base;
10872 ushort q_addr;
10873 ushort saved_word;
10874 int sta;
10875
10876 iop_base = asc_dvc->iop_base;
10877 sta = 0;
10878 q_addr = ASC_QNO_TO_QADDR(241);
10879 saved_word = AscReadLramWord(iop_base, q_addr);
10880 AscSetChipLramAddr(iop_base, q_addr);
10881 AscSetChipLramData(iop_base, 0x55AA);
10882 DvcSleepMilliSecond(10);
10883 AscSetChipLramAddr(iop_base, q_addr);
10884 if (AscGetChipLramData(iop_base) == 0x55AA) {
10885 sta = 1;
10886 AscWriteLramWord(iop_base, q_addr, saved_word);
10887 }
10888 return (sta);
1da177e4
LT
10889}
10890
78e77d8b 10891static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
1da177e4 10892{
27c868c2
MW
10893 uchar read_back;
10894 int retry;
10895
10896 retry = 0;
10897 while (TRUE) {
10898 AscSetChipEEPCmd(iop_base, cmd_reg);
10899 DvcSleepMilliSecond(1);
10900 read_back = AscGetChipEEPCmd(iop_base);
10901 if (read_back == cmd_reg) {
10902 return (1);
10903 }
10904 if (retry++ > ASC_EEP_MAX_RETRY) {
10905 return (0);
10906 }
10907 }
1da177e4
LT
10908}
10909
78e77d8b 10910static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
1da177e4 10911{
27c868c2
MW
10912 ushort read_back;
10913 int retry;
10914
10915 retry = 0;
10916 while (TRUE) {
10917 AscSetChipEEPData(iop_base, data_reg);
10918 DvcSleepMilliSecond(1);
10919 read_back = AscGetChipEEPData(iop_base);
10920 if (read_back == data_reg) {
10921 return (1);
10922 }
10923 if (retry++ > ASC_EEP_MAX_RETRY) {
10924 return (0);
10925 }
10926 }
1da177e4
LT
10927}
10928
78e77d8b 10929static void __devinit AscWaitEEPRead(void)
1da177e4 10930{
27c868c2
MW
10931 DvcSleepMilliSecond(1);
10932 return;
1da177e4
LT
10933}
10934
78e77d8b 10935static void __devinit AscWaitEEPWrite(void)
1da177e4 10936{
27c868c2
MW
10937 DvcSleepMilliSecond(20);
10938 return;
1da177e4
LT
10939}
10940
78e77d8b 10941static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
1da177e4 10942{
27c868c2
MW
10943 ushort read_wval;
10944 uchar cmd_reg;
10945
10946 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
10947 AscWaitEEPRead();
10948 cmd_reg = addr | ASC_EEP_CMD_READ;
10949 AscWriteEEPCmdReg(iop_base, cmd_reg);
10950 AscWaitEEPRead();
10951 read_wval = AscGetChipEEPData(iop_base);
10952 AscWaitEEPRead();
10953 return (read_wval);
1da177e4
LT
10954}
10955
78e77d8b 10956static ushort __devinit
27c868c2 10957AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
1da177e4 10958{
27c868c2
MW
10959 ushort read_wval;
10960
10961 read_wval = AscReadEEPWord(iop_base, addr);
10962 if (read_wval != word_val) {
10963 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
10964 AscWaitEEPRead();
10965 AscWriteEEPDataReg(iop_base, word_val);
10966 AscWaitEEPRead();
10967 AscWriteEEPCmdReg(iop_base,
10968 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
10969 AscWaitEEPWrite();
10970 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
10971 AscWaitEEPRead();
10972 return (AscReadEEPWord(iop_base, addr));
10973 }
10974 return (read_wval);
1da177e4
LT
10975}
10976
78e77d8b 10977static ushort __devinit
27c868c2 10978AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 10979{
27c868c2
MW
10980 ushort wval;
10981 ushort sum;
10982 ushort *wbuf;
10983 int cfg_beg;
10984 int cfg_end;
10985 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
10986 int s_addr;
10987
10988 wbuf = (ushort *)cfg_buf;
10989 sum = 0;
10990 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
10991 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10992 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
10993 sum += *wbuf;
10994 }
10995 if (bus_type & ASC_IS_VL) {
10996 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10997 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10998 } else {
10999 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11000 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11001 }
11002 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11003 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
11004 if (s_addr <= uchar_end_in_config) {
11005 /*
11006 * Swap all char fields - must unswap bytes already swapped
11007 * by AscReadEEPWord().
11008 */
11009 *wbuf = le16_to_cpu(wval);
11010 } else {
11011 /* Don't swap word field at the end - cntl field. */
11012 *wbuf = wval;
11013 }
11014 sum += wval; /* Checksum treats all EEPROM data as words. */
11015 }
11016 /*
11017 * Read the checksum word which will be compared against 'sum'
11018 * by the caller. Word field already swapped.
11019 */
11020 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11021 return (sum);
1da177e4
LT
11022}
11023
78e77d8b 11024static int __devinit
27c868c2 11025AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 11026{
27c868c2
MW
11027 int n_error;
11028 ushort *wbuf;
11029 ushort word;
11030 ushort sum;
11031 int s_addr;
11032 int cfg_beg;
11033 int cfg_end;
11034 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11035
11036 wbuf = (ushort *)cfg_buf;
11037 n_error = 0;
11038 sum = 0;
11039 /* Write two config words; AscWriteEEPWord() will swap bytes. */
11040 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11041 sum += *wbuf;
11042 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11043 n_error++;
11044 }
11045 }
11046 if (bus_type & ASC_IS_VL) {
11047 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11048 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11049 } else {
11050 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11051 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11052 }
11053 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11054 if (s_addr <= uchar_end_in_config) {
11055 /*
11056 * This is a char field. Swap char fields before they are
11057 * swapped again by AscWriteEEPWord().
11058 */
11059 word = cpu_to_le16(*wbuf);
11060 if (word !=
11061 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
11062 n_error++;
11063 }
11064 } else {
11065 /* Don't swap word field at the end - cntl field. */
11066 if (*wbuf !=
11067 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11068 n_error++;
11069 }
11070 }
11071 sum += *wbuf; /* Checksum calculated from word values. */
11072 }
11073 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
11074 *wbuf = sum;
11075 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
11076 n_error++;
11077 }
1da177e4 11078
27c868c2
MW
11079 /* Read EEPROM back again. */
11080 wbuf = (ushort *)cfg_buf;
11081 /*
11082 * Read two config words; Byte-swapping done by AscReadEEPWord().
11083 */
11084 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11085 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
11086 n_error++;
11087 }
11088 }
11089 if (bus_type & ASC_IS_VL) {
11090 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11091 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11092 } else {
11093 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11094 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11095 }
11096 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11097 if (s_addr <= uchar_end_in_config) {
11098 /*
11099 * Swap all char fields. Must unswap bytes already swapped
11100 * by AscReadEEPWord().
11101 */
11102 word =
11103 le16_to_cpu(AscReadEEPWord
11104 (iop_base, (uchar)s_addr));
11105 } else {
11106 /* Don't swap word field at the end - cntl field. */
11107 word = AscReadEEPWord(iop_base, (uchar)s_addr);
11108 }
11109 if (*wbuf != word) {
11110 n_error++;
11111 }
11112 }
11113 /* Read checksum; Byte swapping not needed. */
11114 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
11115 n_error++;
11116 }
11117 return (n_error);
1da177e4
LT
11118}
11119
78e77d8b 11120static int __devinit
27c868c2 11121AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 11122{
27c868c2
MW
11123 int retry;
11124 int n_error;
11125
11126 retry = 0;
11127 while (TRUE) {
11128 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
11129 bus_type)) == 0) {
11130 break;
11131 }
11132 if (++retry > ASC_EEP_MAX_RETRY) {
11133 break;
11134 }
11135 }
11136 return (n_error);
1da177e4
LT
11137}
11138
27c868c2
MW
11139static void
11140AscAsyncFix(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq)
1da177e4 11141{
27c868c2
MW
11142 uchar dvc_type;
11143 ASC_SCSI_BIT_ID_TYPE tid_bits;
11144
11145 dvc_type = ASC_INQ_DVC_TYPE(inq);
11146 tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
11147
11148 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
11149 if (!(asc_dvc->init_sdtr & tid_bits)) {
11150 if ((dvc_type == TYPE_ROM) &&
11151 (AscCompareString((uchar *)inq->vendor_id,
11152 (uchar *)"HP ", 3) == 0)) {
11153 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
11154 }
11155 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
11156 if ((dvc_type == TYPE_PROCESSOR) ||
11157 (dvc_type == TYPE_SCANNER) ||
11158 (dvc_type == TYPE_ROM) || (dvc_type == TYPE_TAPE)) {
11159 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
11160 }
11161
11162 if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
11163 AscSetRunChipSynRegAtID(asc_dvc->iop_base,
11164 tid_no,
11165 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
11166 }
11167 }
11168 }
11169 return;
1da177e4
LT
11170}
11171
27c868c2 11172static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
1da177e4 11173{
27c868c2
MW
11174 if ((inq->add_len >= 32) &&
11175 (AscCompareString((uchar *)inq->vendor_id,
11176 (uchar *)"QUANTUM XP34301", 15) == 0) &&
11177 (AscCompareString((uchar *)inq->product_rev_level,
11178 (uchar *)"1071", 4) == 0)) {
11179 return 0;
11180 }
11181 return 1;
1da177e4
LT
11182}
11183
27c868c2
MW
11184static void
11185AscInquiryHandling(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq)
1da177e4 11186{
27c868c2
MW
11187 ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
11188 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
11189
11190 orig_init_sdtr = asc_dvc->init_sdtr;
11191 orig_use_tagged_qng = asc_dvc->use_tagged_qng;
11192
11193 asc_dvc->init_sdtr &= ~tid_bit;
11194 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
11195 asc_dvc->use_tagged_qng &= ~tid_bit;
11196
11197 if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) {
11198 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) {
11199 asc_dvc->init_sdtr |= tid_bit;
11200 }
11201 if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) &&
11202 ASC_INQ_CMD_QUEUE(inq)) {
11203 if (AscTagQueuingSafe(inq)) {
11204 asc_dvc->use_tagged_qng |= tid_bit;
11205 asc_dvc->cfg->can_tagged_qng |= tid_bit;
11206 }
11207 }
11208 }
11209 if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
11210 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
11211 asc_dvc->cfg->disc_enable);
11212 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
11213 asc_dvc->use_tagged_qng);
11214 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
11215 asc_dvc->cfg->can_tagged_qng);
11216
11217 asc_dvc->max_dvc_qng[tid_no] =
11218 asc_dvc->cfg->max_tag_qng[tid_no];
11219 AscWriteLramByte(asc_dvc->iop_base,
11220 (ushort)(ASCV_MAX_DVC_QNG_BEG + tid_no),
11221 asc_dvc->max_dvc_qng[tid_no]);
11222 }
11223 if (orig_init_sdtr != asc_dvc->init_sdtr) {
11224 AscAsyncFix(asc_dvc, tid_no, inq);
11225 }
11226 return;
1da177e4
LT
11227}
11228
27c868c2 11229static int AscCompareString(uchar *str1, uchar *str2, int len)
1da177e4 11230{
27c868c2
MW
11231 int i;
11232 int diff;
1da177e4 11233
27c868c2
MW
11234 for (i = 0; i < len; i++) {
11235 diff = (int)(str1[i] - str2[i]);
11236 if (diff != 0)
11237 return (diff);
11238 }
11239 return (0);
1da177e4
LT
11240}
11241
27c868c2 11242static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
1da177e4 11243{
27c868c2
MW
11244 uchar byte_data;
11245 ushort word_data;
11246
11247 if (isodd_word(addr)) {
11248 AscSetChipLramAddr(iop_base, addr - 1);
11249 word_data = AscGetChipLramData(iop_base);
11250 byte_data = (uchar)((word_data >> 8) & 0xFF);
11251 } else {
11252 AscSetChipLramAddr(iop_base, addr);
11253 word_data = AscGetChipLramData(iop_base);
11254 byte_data = (uchar)(word_data & 0xFF);
11255 }
11256 return (byte_data);
1da177e4 11257}
27c868c2
MW
11258
11259static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
1da177e4 11260{
27c868c2 11261 ushort word_data;
1da177e4 11262
27c868c2
MW
11263 AscSetChipLramAddr(iop_base, addr);
11264 word_data = AscGetChipLramData(iop_base);
11265 return (word_data);
1da177e4
LT
11266}
11267
11268#if CC_VERY_LONG_SG_LIST
27c868c2 11269static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
1da177e4 11270{
27c868c2
MW
11271 ushort val_low, val_high;
11272 ASC_DCNT dword_data;
11273
11274 AscSetChipLramAddr(iop_base, addr);
11275 val_low = AscGetChipLramData(iop_base);
11276 val_high = AscGetChipLramData(iop_base);
11277 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
11278 return (dword_data);
1da177e4
LT
11279}
11280#endif /* CC_VERY_LONG_SG_LIST */
11281
27c868c2 11282static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
1da177e4 11283{
27c868c2
MW
11284 AscSetChipLramAddr(iop_base, addr);
11285 AscSetChipLramData(iop_base, word_val);
11286 return;
1da177e4
LT
11287}
11288
27c868c2 11289static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
1da177e4 11290{
27c868c2
MW
11291 ushort word_data;
11292
11293 if (isodd_word(addr)) {
11294 addr--;
11295 word_data = AscReadLramWord(iop_base, addr);
11296 word_data &= 0x00FF;
11297 word_data |= (((ushort)byte_val << 8) & 0xFF00);
11298 } else {
11299 word_data = AscReadLramWord(iop_base, addr);
11300 word_data &= 0xFF00;
11301 word_data |= ((ushort)byte_val & 0x00FF);
11302 }
11303 AscWriteLramWord(iop_base, addr, word_data);
11304 return;
1da177e4
LT
11305}
11306
11307/*
11308 * Copy 2 bytes to LRAM.
11309 *
11310 * The source data is assumed to be in little-endian order in memory
11311 * and is maintained in little-endian order when written to LRAM.
11312 */
27c868c2
MW
11313static void
11314AscMemWordCopyPtrToLram(PortAddr iop_base,
11315 ushort s_addr, uchar *s_buffer, int words)
1da177e4 11316{
27c868c2
MW
11317 int i;
11318
11319 AscSetChipLramAddr(iop_base, s_addr);
11320 for (i = 0; i < 2 * words; i += 2) {
11321 /*
11322 * On a little-endian system the second argument below
11323 * produces a little-endian ushort which is written to
11324 * LRAM in little-endian order. On a big-endian system
11325 * the second argument produces a big-endian ushort which
11326 * is "transparently" byte-swapped by outpw() and written
11327 * in little-endian order to LRAM.
11328 */
11329 outpw(iop_base + IOP_RAM_DATA,
11330 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
11331 }
11332 return;
1da177e4
LT
11333}
11334
11335/*
11336 * Copy 4 bytes to LRAM.
11337 *
11338 * The source data is assumed to be in little-endian order in memory
11339 * and is maintained in little-endian order when writen to LRAM.
11340 */
27c868c2
MW
11341static void
11342AscMemDWordCopyPtrToLram(PortAddr iop_base,
11343 ushort s_addr, uchar *s_buffer, int dwords)
1da177e4 11344{
27c868c2
MW
11345 int i;
11346
11347 AscSetChipLramAddr(iop_base, s_addr);
11348 for (i = 0; i < 4 * dwords; i += 4) {
11349 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
11350 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
11351 }
11352 return;
1da177e4
LT
11353}
11354
11355/*
11356 * Copy 2 bytes from LRAM.
11357 *
11358 * The source data is assumed to be in little-endian order in LRAM
11359 * and is maintained in little-endian order when written to memory.
11360 */
27c868c2
MW
11361static void
11362AscMemWordCopyPtrFromLram(PortAddr iop_base,
11363 ushort s_addr, uchar *d_buffer, int words)
1da177e4 11364{
27c868c2
MW
11365 int i;
11366 ushort word;
11367
11368 AscSetChipLramAddr(iop_base, s_addr);
11369 for (i = 0; i < 2 * words; i += 2) {
11370 word = inpw(iop_base + IOP_RAM_DATA);
11371 d_buffer[i] = word & 0xff;
11372 d_buffer[i + 1] = (word >> 8) & 0xff;
11373 }
11374 return;
1da177e4
LT
11375}
11376
27c868c2 11377static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
1da177e4 11378{
27c868c2
MW
11379 ASC_DCNT sum;
11380 int i;
1da177e4 11381
27c868c2
MW
11382 sum = 0L;
11383 for (i = 0; i < words; i++, s_addr += 2) {
11384 sum += AscReadLramWord(iop_base, s_addr);
11385 }
11386 return (sum);
1da177e4
LT
11387}
11388
27c868c2
MW
11389static void
11390AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
1da177e4 11391{
27c868c2 11392 int i;
1da177e4 11393
27c868c2
MW
11394 AscSetChipLramAddr(iop_base, s_addr);
11395 for (i = 0; i < words; i++) {
11396 AscSetChipLramData(iop_base, set_wval);
11397 }
11398 return;
1da177e4
LT
11399}
11400
1da177e4
LT
11401/*
11402 * --- Adv Library Functions
11403 */
11404
11405/* a_mcode.h */
11406
11407/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
11408static unsigned char _adv_asc3550_buf[] = {
11409 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
11410 0x01, 0x00, 0x48, 0xe4,
11411 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff,
11412 0x28, 0x0e, 0x9e, 0xe7,
11413 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7,
11414 0x55, 0xf0, 0x01, 0xf6,
11415 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
11416 0x00, 0xec, 0x85, 0xf0,
11417 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0,
11418 0x86, 0xf0, 0xb4, 0x00,
11419 0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00,
11420 0xaa, 0x18, 0x02, 0x80,
11421 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
11422 0x00, 0x57, 0x01, 0xea,
11423 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80,
11424 0x03, 0xe6, 0xb6, 0x00,
11425 0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12,
11426 0x02, 0x4a, 0xb9, 0x54,
11427 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
11428 0x3e, 0x00, 0x80, 0x00,
11429 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
11430 0x74, 0x01, 0x76, 0x01,
11431 0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13,
11432 0x4c, 0x1c, 0xbb, 0x55,
11433 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
11434 0x03, 0xf7, 0x06, 0xf7,
11435 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08,
11436 0x30, 0x13, 0x64, 0x15,
11437 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c,
11438 0x04, 0xea, 0x5d, 0xf0,
11439 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
11440 0xcc, 0x00, 0x20, 0x01,
11441 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13,
11442 0x40, 0x13, 0x30, 0x1c,
11443 0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
11444 0x59, 0xf0, 0xa7, 0xf0,
11445 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
11446 0xa4, 0x00, 0xb5, 0x00,
11447 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a,
11448 0x14, 0x0e, 0x02, 0x10,
11449 0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13,
11450 0x10, 0x15, 0x14, 0x15,
11451 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
11452 0x91, 0x44, 0x0a, 0x45,
11453 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58,
11454 0x83, 0x59, 0x05, 0xe6,
11455 0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8,
11456 0x02, 0xfa, 0x03, 0xfa,
11457 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
11458 0x9e, 0x00, 0xa8, 0x00,
11459 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01,
11460 0x7a, 0x01, 0xc0, 0x01,
11461 0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08,
11462 0x69, 0x08, 0xba, 0x08,
11463 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
11464 0xf1, 0x10, 0x06, 0x12,
11465 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14,
11466 0x8a, 0x15, 0xc6, 0x17,
11467 0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
11468 0x0e, 0x47, 0x48, 0x47,
11469 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
11470 0x14, 0x56, 0x77, 0x57,
11471 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c,
11472 0xf0, 0x29, 0x02, 0xfe,
11473 0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf,
11474 0xfe, 0x80, 0x01, 0xff,
11475 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
11476 0x00, 0xfe, 0x57, 0x24,
11477 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09,
11478 0x00, 0x00, 0xff, 0x08,
11479 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
11480 0xff, 0xff, 0xff, 0x0f,
11481 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
11482 0xfe, 0x04, 0xf7, 0xcf,
11483 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67,
11484 0x0b, 0x3c, 0x2a, 0xfe,
11485 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0,
11486 0xfe, 0xf0, 0x01, 0xfe,
11487 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
11488 0x02, 0xfe, 0xd4, 0x0c,
11489 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
11490 0x1c, 0x05, 0xfe, 0xa6,
11491 0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48,
11492 0xf0, 0xfe, 0x86, 0x02,
11493 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
11494 0xfe, 0x46, 0xf0, 0xfe,
11495 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
11496 0x44, 0x02, 0xfe, 0x44,
11497 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b,
11498 0xa0, 0x17, 0x06, 0x18,
11499 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
11500 0x1e, 0x1c, 0xfe, 0xe9,
11501 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7,
11502 0x0a, 0x6b, 0x01, 0x9e,
11503 0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b,
11504 0x01, 0x82, 0xfe, 0xbd,
11505 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
11506 0x58, 0x1c, 0x17, 0x06,
11507 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21,
11508 0xfe, 0x94, 0x02, 0xfe,
11509 0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97,
11510 0x01, 0xfe, 0x54, 0x0f,
11511 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
11512 0x69, 0x10, 0x17, 0x06,
11513 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05,
11514 0xf6, 0xc7, 0x01, 0xfe,
11515 0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6,
11516 0x02, 0x29, 0x0a, 0x40,
11517 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
11518 0x58, 0x0a, 0x99, 0x01,
11519 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29,
11520 0x2a, 0x46, 0xfe, 0x02,
11521 0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc,
11522 0x01, 0xfe, 0x07, 0x4b,
11523 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
11524 0xfe, 0x56, 0x03, 0xfe,
11525 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10,
11526 0xfe, 0x9f, 0xf0, 0xfe,
11527 0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48,
11528 0x1c, 0xeb, 0x09, 0x04,
11529 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
11530 0x01, 0x0e, 0xac, 0x75,
11531 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2,
11532 0xfe, 0x82, 0xf0, 0xfe,
11533 0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25,
11534 0x32, 0x1f, 0xfe, 0xb4,
11535 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
11536 0x0a, 0xf0, 0xfe, 0x7a,
11537 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c,
11538 0x01, 0x33, 0x8f, 0xfe,
11539 0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8,
11540 0xf7, 0xfe, 0x48, 0x1c,
11541 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
11542 0x0a, 0xca, 0x01, 0x0e,
11543 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14,
11544 0x2c, 0x01, 0x33, 0x8f,
11545 0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65,
11546 0xfe, 0x3c, 0x04, 0x1f,
11547 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
11548 0x12, 0x2b, 0xff, 0x02,
11549 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f,
11550 0x22, 0x30, 0x2e, 0xd5,
11551 0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c,
11552 0xfe, 0x4c, 0x54, 0x64,
11553 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
11554 0xfe, 0x2a, 0x13, 0x2f,
11555 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
11556 0xd3, 0xfa, 0xef, 0x86,
11557 0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04,
11558 0x1d, 0xfe, 0x1c, 0x12,
11559 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
11560 0x70, 0x0c, 0x02, 0x22,
11561 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92,
11562 0x01, 0x33, 0x02, 0x29,
11563 0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87,
11564 0x80, 0xfe, 0x31, 0xe4,
11565 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
11566 0xfe, 0x70, 0x12, 0x49,
11567 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe,
11568 0x80, 0x05, 0xfe, 0x31,
11569 0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00,
11570 0x28, 0xfe, 0x42, 0x12,
11571 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
11572 0x11, 0xfe, 0xe3, 0x00,
11573 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
11574 0x64, 0x05, 0x83, 0x24,
11575 0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe,
11576 0x09, 0x48, 0x01, 0x08,
11577 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
11578 0x86, 0x24, 0x06, 0x12,
11579 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47,
11580 0x01, 0xa7, 0x14, 0x92,
11581 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c,
11582 0x02, 0x22, 0x05, 0xfe,
11583 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
11584 0x47, 0x01, 0xa7, 0x26,
11585 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f,
11586 0x01, 0xfe, 0xaa, 0x14,
11587 0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00,
11588 0x05, 0x50, 0xb4, 0x0c,
11589 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
11590 0x13, 0x01, 0xfe, 0x14,
11591 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c,
11592 0xff, 0x02, 0x00, 0x57,
11593 0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe,
11594 0x72, 0x06, 0x49, 0x04,
11595 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
11596 0x06, 0x11, 0x9a, 0x01,
11597 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06,
11598 0x01, 0xa7, 0xec, 0x72,
11599 0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32,
11600 0xfe, 0x0a, 0xf0, 0xfe,
11601 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
11602 0x8d, 0x81, 0x02, 0x22,
11603 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00,
11604 0x01, 0x08, 0x15, 0x00,
11605 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15,
11606 0x00, 0x02, 0xfe, 0x32,
11607 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
11608 0xfe, 0x1b, 0x00, 0x01,
11609 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
11610 0x08, 0x15, 0x06, 0x01,
11611 0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe,
11612 0x9a, 0x81, 0x4b, 0x1d,
11613 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
11614 0x45, 0xfe, 0x32, 0x12,
11615 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0,
11616 0xfe, 0x32, 0x07, 0x8d,
11617 0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a,
11618 0x06, 0x15, 0x19, 0x02,
11619 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
11620 0x90, 0x77, 0xfe, 0xca,
11621 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07,
11622 0x10, 0xfe, 0x0e, 0x12,
11623 0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe,
11624 0x83, 0xe7, 0xc4, 0xa1,
11625 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
11626 0x40, 0x12, 0x58, 0x01,
11627 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6,
11628 0x51, 0x83, 0xfb, 0xfe,
11629 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90,
11630 0xfe, 0x40, 0x50, 0xfe,
11631 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
11632 0xfe, 0x2a, 0x12, 0xfe,
11633 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f,
11634 0x85, 0x01, 0xa8, 0xfe,
11635 0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56,
11636 0x18, 0x57, 0xfb, 0xfe,
11637 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
11638 0x0c, 0x39, 0x18, 0x3a,
11639 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e,
11640 0x11, 0x65, 0xfe, 0x48,
11641 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73,
11642 0xdd, 0xb8, 0xfe, 0x80,
11643 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
11644 0xfe, 0x7a, 0x08, 0x8d,
11645 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9,
11646 0x10, 0x61, 0x04, 0x06,
11647 0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68,
11648 0x12, 0xfe, 0x2e, 0x1c,
11649 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
11650 0x52, 0x12, 0xfe, 0x2c,
11651 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe,
11652 0x08, 0xfe, 0x8a, 0x10,
11653 0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe,
11654 0x24, 0x0a, 0xab, 0xfe,
11655 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
11656 0x1c, 0x12, 0xb5, 0xfe,
11657 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb,
11658 0x1c, 0x06, 0x16, 0x9d,
11659 0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b,
11660 0x14, 0x92, 0x01, 0x33,
11661 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
11662 0xfe, 0x74, 0x18, 0x1c,
11663 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b,
11664 0x01, 0xe6, 0x1e, 0x27,
11665 0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a,
11666 0x09, 0x04, 0x6a, 0xfe,
11667 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
11668 0xfe, 0x83, 0x80, 0xfe,
11669 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63,
11670 0x27, 0xfe, 0x40, 0x59,
11671 0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18,
11672 0x7c, 0xbe, 0x54, 0xbf,
11673 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
11674 0x79, 0x56, 0x68, 0x57,
11675 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5,
11676 0xa2, 0x23, 0x0c, 0x7b,
11677 0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19,
11678 0x16, 0xd7, 0x79, 0x39,
11679 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
11680 0xfe, 0x10, 0x58, 0xfe,
11681 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04,
11682 0x19, 0x16, 0xd7, 0x09,
11683 0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f,
11684 0xfe, 0x10, 0x90, 0xfe,
11685 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
11686 0x11, 0x9b, 0x09, 0x04,
11687 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08,
11688 0xfe, 0x0c, 0x58, 0xfe,
11689 0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04,
11690 0x0b, 0xfe, 0x1a, 0x12,
11691 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
11692 0x14, 0x7a, 0x01, 0x33,
11693 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39,
11694 0xfe, 0xed, 0x19, 0xbf,
11695 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff,
11696 0x34, 0xfe, 0x74, 0x10,
11697 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
11698 0x84, 0x05, 0xcb, 0x1c,
11699 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1,
11700 0xf0, 0xfe, 0xc4, 0x0a,
11701 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe,
11702 0xce, 0xf0, 0xfe, 0xca,
11703 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
11704 0x22, 0x00, 0x02, 0x5a,
11705 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a,
11706 0xfe, 0xd0, 0xf0, 0xfe,
11707 0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f,
11708 0x4c, 0xfe, 0x10, 0x10,
11709 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
11710 0x2a, 0x13, 0xfe, 0x4e,
11711 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1,
11712 0x16, 0x32, 0x2a, 0x73,
11713 0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25,
11714 0x32, 0x8c, 0xfe, 0x48,
11715 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
11716 0xdb, 0x10, 0x11, 0xfe,
11717 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0,
11718 0x22, 0x30, 0x2e, 0xd8,
11719 0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1,
11720 0x45, 0x0f, 0xfe, 0x42,
11721 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
11722 0x09, 0x04, 0x0b, 0xfe,
11723 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28,
11724 0x00, 0x21, 0xfe, 0xa6,
11725 0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00,
11726 0xfe, 0xe2, 0x10, 0x01,
11727 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
11728 0x01, 0x6f, 0x02, 0x29,
11729 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10,
11730 0x01, 0x86, 0x3e, 0x0b,
11731 0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3,
11732 0x3e, 0x0b, 0x0f, 0xfe,
11733 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
11734 0xe8, 0x59, 0x11, 0x2d,
11735 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09,
11736 0x04, 0x0b, 0x84, 0x3e,
11737 0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12,
11738 0x09, 0x04, 0x1b, 0xfe,
11739 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
11740 0x1c, 0x1c, 0xfe, 0x9d,
11741 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f,
11742 0xfe, 0x15, 0x00, 0xfe,
11743 0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10,
11744 0x0f, 0xfe, 0x47, 0x00,
11745 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
11746 0xab, 0x70, 0x05, 0x6b,
11747 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe,
11748 0x1c, 0x42, 0x59, 0x01,
11749 0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31,
11750 0x00, 0x37, 0x97, 0x01,
11751 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
11752 0x1d, 0xfe, 0xce, 0x45,
11753 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75,
11754 0x57, 0x05, 0x51, 0xfe,
11755 0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48,
11756 0x46, 0x09, 0x04, 0x1d,
11757 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
11758 0x99, 0x01, 0x0e, 0xfe,
11759 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51,
11760 0xfe, 0xee, 0x14, 0xee,
11761 0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad,
11762 0x13, 0x02, 0x29, 0x1e,
11763 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
11764 0xce, 0x1e, 0x2d, 0x47,
11765 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06,
11766 0x12, 0x4d, 0x01, 0xfe,
11767 0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe,
11768 0xf0, 0x0d, 0xfe, 0x02,
11769 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
11770 0xf6, 0xfe, 0x34, 0x01,
11771 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13,
11772 0xaf, 0xfe, 0x02, 0xea,
11773 0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c,
11774 0x05, 0xfe, 0x38, 0x01,
11775 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
11776 0x0c, 0xfe, 0x62, 0x01,
11777 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06,
11778 0x03, 0x23, 0x03, 0x1e,
11779 0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe,
11780 0x71, 0x13, 0xfe, 0x24,
11781 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
11782 0xdc, 0xfe, 0x73, 0x57,
11783 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe,
11784 0x80, 0x5d, 0x03, 0xfe,
11785 0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6,
11786 0x75, 0x03, 0x09, 0x04,
11787 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
11788 0xfe, 0x1e, 0x80, 0xe1,
11789 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e,
11790 0x90, 0xa3, 0xfe, 0x3c,
11791 0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82,
11792 0x16, 0x2f, 0x07, 0x2d,
11793 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
11794 0xe8, 0x11, 0xfe, 0xe9,
11795 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe,
11796 0x1e, 0x1c, 0xfe, 0x14,
11797 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01,
11798 0x09, 0x04, 0x4f, 0xfe,
11799 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
11800 0x40, 0x12, 0x20, 0x63,
11801 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08,
11802 0x1c, 0x05, 0xfe, 0xac,
11803 0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05,
11804 0xfe, 0xb0, 0x00, 0xfe,
11805 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
11806 0x24, 0x69, 0x12, 0xc9,
11807 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe,
11808 0x90, 0x4d, 0xfe, 0x91,
11809 0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c,
11810 0xfe, 0x90, 0x4d, 0xfe,
11811 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
11812 0x46, 0x1e, 0x20, 0xed,
11813 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea,
11814 0x70, 0xfe, 0x14, 0x1c,
11815 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee,
11816 0xfe, 0x07, 0xe6, 0x1d,
11817 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
11818 0xfa, 0xef, 0xfe, 0x42,
11819 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0,
11820 0xfe, 0x36, 0x12, 0xf0,
11821 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
11822 0x3d, 0x75, 0x07, 0x10,
11823 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
11824 0x10, 0x07, 0x7e, 0x45,
11825 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74,
11826 0xfe, 0x01, 0xec, 0x97,
11827 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76,
11828 0x27, 0x01, 0xda, 0xfe,
11829 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
11830 0xfe, 0x48, 0x12, 0x07,
11831 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16,
11832 0xfe, 0x3e, 0x11, 0x07,
11833 0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8,
11834 0x11, 0x07, 0x19, 0xfe,
11835 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
11836 0x01, 0x08, 0x8c, 0x43,
11837 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11,
11838 0x7e, 0x02, 0x29, 0x2b,
11839 0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe,
11840 0xfc, 0x10, 0x09, 0x04,
11841 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
11842 0xc6, 0x10, 0x1e, 0x58,
11843 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c,
11844 0x54, 0x18, 0x55, 0x23,
11845 0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01,
11846 0xa5, 0xc0, 0x38, 0xc1,
11847 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
11848 0x05, 0xfa, 0x4e, 0xfe,
11849 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56,
11850 0x0c, 0x56, 0x18, 0x57,
11851 0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe,
11852 0x00, 0x56, 0xfe, 0xa1,
11853 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
11854 0x58, 0xfe, 0x1f, 0x40,
11855 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56,
11856 0x31, 0x57, 0xfe, 0x44,
11857 0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe,
11858 0x8a, 0x50, 0x05, 0x39,
11859 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
11860 0x12, 0xcd, 0x02, 0x5b,
11861 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44,
11862 0x2f, 0x07, 0x9b, 0x21,
11863 0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79,
11864 0x39, 0x68, 0x3a, 0xfe,
11865 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
11866 0x51, 0xfe, 0x8e, 0x51,
11867 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b,
11868 0x01, 0x08, 0x25, 0x32,
11869 0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b,
11870 0x3b, 0x02, 0x44, 0x01,
11871 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
11872 0x01, 0x08, 0x1f, 0xa2,
11873 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c,
11874 0x00, 0x28, 0x84, 0x49,
11875 0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06,
11876 0x78, 0x3d, 0xfe, 0xda,
11877 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
11878 0x05, 0xc6, 0x28, 0x84,
11879 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8,
11880 0x14, 0xfe, 0x03, 0x17,
11881 0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01,
11882 0xfe, 0xaa, 0x14, 0x02,
11883 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
11884 0x21, 0x44, 0x01, 0xfe,
11885 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87,
11886 0xfe, 0x4a, 0xf4, 0x0b,
11887 0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a,
11888 0x85, 0x02, 0x5b, 0x05,
11889 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
11890 0xd8, 0x14, 0x02, 0x5c,
11891 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1,
11892 0x01, 0x08, 0x23, 0x72,
11893 0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca,
11894 0x12, 0x5e, 0x2b, 0x01,
11895 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
11896 0x1c, 0xfe, 0xff, 0x7f,
11897 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00,
11898 0x57, 0x48, 0x8b, 0x1c,
11899 0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02,
11900 0x00, 0x57, 0x48, 0x8b,
11901 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
11902 0x03, 0x0a, 0x50, 0x01,
11903 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00,
11904 0x54, 0xfe, 0x00, 0xf4,
11905 0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe,
11906 0x03, 0x7c, 0x63, 0x27,
11907 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
11908 0xfe, 0x82, 0x4a, 0xfe,
11909 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe,
11910 0x42, 0x48, 0x5f, 0x60,
11911 0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08,
11912 0x1f, 0xfe, 0xa2, 0x14,
11913 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
11914 0xcc, 0x12, 0x49, 0x04,
11915 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe,
11916 0xe8, 0x13, 0x3b, 0x13,
11917 0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55,
11918 0xa1, 0xff, 0x02, 0x83,
11919 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
11920 0x13, 0x06, 0xfe, 0x56,
11921 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe,
11922 0x64, 0x00, 0x17, 0x93,
11923 0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe,
11924 0xc8, 0x00, 0x8e, 0xe4,
11925 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
11926 0x01, 0xba, 0xfe, 0x4e,
11927 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0,
11928 0xfe, 0x60, 0x14, 0xfe,
11929 0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01,
11930 0xfe, 0x22, 0x13, 0x1c,
11931 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
11932 0xfe, 0x9c, 0x14, 0xb7,
11933 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba,
11934 0xfe, 0x9c, 0x14, 0xb7,
11935 0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06,
11936 0xfe, 0xb4, 0x56, 0xfe,
11937 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
11938 0xe5, 0x15, 0x0b, 0x01,
11939 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89,
11940 0x49, 0x01, 0x08, 0x03,
11941 0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6,
11942 0x15, 0x06, 0x01, 0x08,
11943 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
11944 0x4a, 0x01, 0x08, 0x03,
11945 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc,
11946 0xfe, 0x49, 0xf4, 0x00,
11947 0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01,
11948 0x08, 0x2f, 0x07, 0xfe,
11949 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
11950 0x01, 0x43, 0x1e, 0xcd,
11951 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e,
11952 0xed, 0x88, 0x07, 0x10,
11953 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a,
11954 0x80, 0x01, 0x0e, 0x88,
11955 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
11956 0x88, 0x03, 0x0a, 0x42,
11957 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e,
11958 0xfe, 0x80, 0x80, 0xf2,
11959 0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51,
11960 0x01, 0x82, 0x03, 0x17,
11961 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
11962 0xfe, 0x24, 0x1c, 0xfe,
11963 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0,
11964 0x91, 0x1d, 0x66, 0xfe,
11965 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe,
11966 0xda, 0x10, 0x17, 0x10,
11967 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
11968 0x05, 0xfe, 0x66, 0x01,
11969 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06,
11970 0xfe, 0x3c, 0x50, 0x66,
11971 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe,
11972 0x40, 0x16, 0xfe, 0xb6,
11973 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
11974 0x10, 0x71, 0xfe, 0x83,
11975 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90,
11976 0xfe, 0x62, 0x16, 0xfe,
11977 0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19,
11978 0xfe, 0x98, 0xe7, 0x00,
11979 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
11980 0xfe, 0x30, 0xbc, 0xfe,
11981 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
11982 0xc5, 0x90, 0xfe, 0x9a,
11983 0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe,
11984 0x42, 0x10, 0xfe, 0x02,
11985 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
11986 0xfe, 0x1d, 0xf7, 0x4f,
11987 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f,
11988 0x47, 0xfe, 0x83, 0x58,
11989 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11,
11990 0xfe, 0xdd, 0x00, 0x63,
11991 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
11992 0x06, 0x37, 0x95, 0xa9,
11993 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e,
11994 0x18, 0x1c, 0x1a, 0x5d,
11995 0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe,
11996 0xe1, 0x10, 0x78, 0x2c,
11997 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
11998 0x13, 0x3c, 0x8a, 0x0a,
11999 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
12000 0xe3, 0xfe, 0x00, 0xcc,
12001 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01,
12002 0x0e, 0xf2, 0x01, 0x6f,
12003 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
12004 0xf6, 0xfe, 0xd6, 0xf0,
12005 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe,
12006 0x15, 0x00, 0x59, 0x76,
12007 0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35,
12008 0x11, 0x2d, 0x01, 0x6f,
12009 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
12010 0xc8, 0xfe, 0x48, 0x55,
12011 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a,
12012 0x99, 0x01, 0x0e, 0xf0,
12013 0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73,
12014 0x75, 0x03, 0x0a, 0x42,
12015 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
12016 0x0e, 0x73, 0x75, 0x03,
12017 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00,
12018 0xfe, 0x3a, 0x45, 0x5b,
12019 0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00,
12020 0xfe, 0x02, 0xe6, 0x1b,
12021 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
12022 0xfe, 0x94, 0x00, 0xfe,
12023 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02,
12024 0xe6, 0x2c, 0xfe, 0x4e,
12025 0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69,
12026 0x03, 0x07, 0x7a, 0xfe,
12027 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
12028 0x07, 0x1b, 0xfe, 0x5a,
12029 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d,
12030 0x24, 0x2c, 0xdc, 0x07,
12031 0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d,
12032 0x9f, 0xad, 0x03, 0x14,
12033 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
12034 0x03, 0x25, 0xfe, 0xca,
12035 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a,
12036 0x00, 0x00,
1da177e4
LT
12037};
12038
27c868c2
MW
12039static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
12040static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
1da177e4
LT
12041
12042/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
12043static unsigned char _adv_asc38C0800_buf[] = {
12044 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
12045 0x01, 0x00, 0x48, 0xe4,
12046 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff,
12047 0x1c, 0x0f, 0x00, 0xf6,
12048 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6,
12049 0x09, 0xe7, 0x55, 0xf0,
12050 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
12051 0x18, 0xf4, 0x08, 0x00,
12052 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6,
12053 0x86, 0xf0, 0xb1, 0xf0,
12054 0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c,
12055 0x3c, 0x00, 0xbb, 0x00,
12056 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
12057 0xba, 0x13, 0x18, 0x40,
12058 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01,
12059 0x6e, 0x01, 0x74, 0x01,
12060 0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00,
12061 0xc0, 0x00, 0x01, 0x01,
12062 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
12063 0x08, 0x12, 0x02, 0x4a,
12064 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4,
12065 0x5d, 0xf0, 0x02, 0xfa,
12066 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01,
12067 0x68, 0x01, 0x6a, 0x01,
12068 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
12069 0x06, 0x13, 0x4c, 0x1c,
12070 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00,
12071 0x0f, 0x00, 0x47, 0x00,
12072 0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c,
12073 0x4e, 0x1c, 0x10, 0x44,
12074 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
12075 0x05, 0x00, 0x34, 0x00,
12076 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b,
12077 0x42, 0x0c, 0x12, 0x0f,
12078 0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48,
12079 0x00, 0x4e, 0x42, 0x54,
12080 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
12081 0x59, 0xf0, 0xb8, 0xf0,
12082 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00,
12083 0x19, 0x00, 0x33, 0x00,
12084 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00,
12085 0xe7, 0x00, 0xe2, 0x03,
12086 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
12087 0x12, 0x13, 0x24, 0x14,
12088 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c,
12089 0x36, 0x1c, 0x08, 0x44,
12090 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54,
12091 0x3a, 0x55, 0x83, 0x55,
12092 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
12093 0x0c, 0xf0, 0x04, 0xf8,
12094 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00,
12095 0xa8, 0x00, 0xaa, 0x00,
12096 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01,
12097 0xc4, 0x01, 0xc6, 0x01,
12098 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
12099 0x68, 0x08, 0x69, 0x08,
12100 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10,
12101 0xed, 0x10, 0xf1, 0x10,
12102 0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13,
12103 0x1e, 0x13, 0x46, 0x14,
12104 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
12105 0xca, 0x18, 0xe6, 0x19,
12106 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c,
12107 0xf0, 0x2b, 0x02, 0xfe,
12108 0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6,
12109 0xfe, 0x84, 0x01, 0xff,
12110 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
12111 0x00, 0xfe, 0x57, 0x24,
12112 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09,
12113 0x00, 0x00, 0xff, 0x08,
12114 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
12115 0xff, 0xff, 0xff, 0x11,
12116 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
12117 0xfe, 0x04, 0xf7, 0xd6,
12118 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99,
12119 0x0a, 0x42, 0x2c, 0xfe,
12120 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0,
12121 0xfe, 0xf4, 0x01, 0xfe,
12122 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
12123 0x02, 0xfe, 0xc8, 0x0d,
12124 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
12125 0x1c, 0x03, 0xfe, 0xa6,
12126 0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48,
12127 0xf0, 0xfe, 0x8a, 0x02,
12128 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
12129 0xfe, 0x46, 0xf0, 0xfe,
12130 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
12131 0x48, 0x02, 0xfe, 0x44,
12132 0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a,
12133 0xaa, 0x18, 0x06, 0x14,
12134 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
12135 0x1e, 0x1c, 0xfe, 0xe9,
12136 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce,
12137 0x09, 0x70, 0x01, 0xa8,
12138 0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70,
12139 0x01, 0x87, 0xfe, 0xbd,
12140 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
12141 0x58, 0x1c, 0x18, 0x06,
12142 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23,
12143 0xfe, 0x98, 0x02, 0xfe,
12144 0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2,
12145 0x01, 0xfe, 0x48, 0x10,
12146 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
12147 0x69, 0x10, 0x18, 0x06,
12148 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05,
12149 0xf6, 0xce, 0x01, 0xfe,
12150 0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe,
12151 0x82, 0x16, 0x02, 0x2b,
12152 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
12153 0xfe, 0x41, 0x58, 0x09,
12154 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe,
12155 0x82, 0x16, 0x02, 0x2b,
12156 0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43,
12157 0xfe, 0x77, 0x57, 0xfe,
12158 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
12159 0xfe, 0x40, 0x1c, 0x1c,
12160 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48,
12161 0x03, 0xfe, 0x11, 0xf0,
12162 0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10,
12163 0xfe, 0x11, 0x00, 0x02,
12164 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
12165 0x21, 0x22, 0xa3, 0xb7,
12166 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16,
12167 0x12, 0xd1, 0x1c, 0xd9,
12168 0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12,
12169 0xfe, 0xe4, 0x00, 0x27,
12170 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
12171 0x06, 0xf0, 0xfe, 0xc8,
12172 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03,
12173 0x70, 0x28, 0x17, 0xfe,
12174 0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8,
12175 0xf9, 0x2c, 0x99, 0x19,
12176 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
12177 0x74, 0x01, 0xaf, 0x8c,
12178 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e,
12179 0x8d, 0x51, 0x64, 0x79,
12180 0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b,
12181 0xfe, 0x6a, 0x02, 0x02,
12182 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
12183 0xfe, 0x3c, 0x04, 0x3b,
12184 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02,
12185 0x00, 0x10, 0x01, 0x0b,
12186 0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde,
12187 0xfe, 0x4c, 0x44, 0xfe,
12188 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
12189 0xda, 0x4f, 0x79, 0x2a,
12190 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b,
12191 0xfe, 0x2a, 0x13, 0x32,
12192 0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c,
12193 0x54, 0x6b, 0xda, 0xfe,
12194 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
12195 0x08, 0x13, 0x32, 0x07,
12196 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d,
12197 0x08, 0x05, 0x06, 0x4d,
12198 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24,
12199 0x2d, 0x12, 0xfe, 0xe6,
12200 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
12201 0x02, 0x2b, 0xfe, 0x42,
12202 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
12203 0xfe, 0x87, 0x80, 0xfe,
12204 0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80,
12205 0x07, 0x19, 0xfe, 0x7c,
12206 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
12207 0x17, 0xfe, 0x90, 0x05,
12208 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe,
12209 0xa0, 0x00, 0x28, 0xfe,
12210 0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c,
12211 0x34, 0xfe, 0x89, 0x48,
12212 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
12213 0x12, 0xfe, 0xe3, 0x00,
12214 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
12215 0x70, 0x05, 0x88, 0x25,
12216 0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe,
12217 0x09, 0x48, 0xff, 0x02,
12218 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
12219 0x08, 0x53, 0x05, 0xcb,
12220 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08,
12221 0x05, 0x1b, 0xfe, 0x22,
12222 0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe,
12223 0x0d, 0x00, 0x01, 0x36,
12224 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
12225 0x03, 0x5c, 0x28, 0xfe,
12226 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53,
12227 0x05, 0x1f, 0xfe, 0x02,
12228 0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5,
12229 0x01, 0x4b, 0x12, 0xfe,
12230 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
12231 0x12, 0x03, 0x45, 0x28,
12232 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe,
12233 0x43, 0x48, 0xc4, 0xcc,
12234 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4,
12235 0x6e, 0x41, 0x01, 0xb2,
12236 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
12237 0xfe, 0xcc, 0x15, 0x1d,
12238 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03,
12239 0x45, 0xc1, 0x0c, 0x45,
12240 0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe,
12241 0xe2, 0x00, 0x27, 0xdb,
12242 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
12243 0xfe, 0x06, 0xf0, 0xfe,
12244 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12,
12245 0x16, 0x19, 0x01, 0x0b,
12246 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
12247 0xfe, 0x99, 0xa4, 0x01,
12248 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
12249 0x12, 0x08, 0x05, 0x1a,
12250 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
12251 0x0b, 0x16, 0x00, 0x01,
12252 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02,
12253 0xe2, 0x6c, 0x58, 0xbe,
12254 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
12255 0xfe, 0x09, 0x6f, 0xba,
12256 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27,
12257 0xfe, 0x54, 0x07, 0x1c,
12258 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c,
12259 0x07, 0x02, 0x24, 0x01,
12260 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
12261 0x2c, 0x90, 0xfe, 0xae,
12262 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a,
12263 0x37, 0x22, 0x20, 0x07,
12264 0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a,
12265 0xfe, 0x06, 0x10, 0xfe,
12266 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
12267 0x37, 0x01, 0xb3, 0xb8,
12268 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a,
12269 0x50, 0xfe, 0x44, 0x51,
12270 0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e,
12271 0x14, 0x5f, 0xfe, 0x0c,
12272 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
12273 0x14, 0x3e, 0xfe, 0x4a,
12274 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
12275 0x90, 0x0c, 0x60, 0x14,
12276 0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62,
12277 0xfe, 0x44, 0x90, 0xfe,
12278 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
12279 0x0c, 0x5e, 0x14, 0x5f,
12280 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e,
12281 0x14, 0x3c, 0x21, 0x0c,
12282 0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11,
12283 0x27, 0xdd, 0xfe, 0x9e,
12284 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
12285 0x9a, 0x08, 0xc6, 0xfe,
12286 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08,
12287 0x95, 0x86, 0x02, 0x24,
12288 0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05,
12289 0x06, 0xfe, 0x10, 0x12,
12290 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
12291 0x1c, 0x02, 0xfe, 0x18,
12292 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe,
12293 0x2c, 0x1c, 0xfe, 0xaa,
12294 0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe,
12295 0xde, 0x09, 0xfe, 0xb7,
12296 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
12297 0xfe, 0xf1, 0x18, 0xfe,
12298 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe,
12299 0x14, 0x59, 0xfe, 0x95,
12300 0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0,
12301 0xfe, 0xf0, 0x08, 0xb5,
12302 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
12303 0x0b, 0xb6, 0xfe, 0xbf,
12304 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c,
12305 0x12, 0xc2, 0xfe, 0xd2,
12306 0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e,
12307 0x06, 0x17, 0x85, 0xc5,
12308 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
12309 0x9d, 0x01, 0x36, 0x10,
12310 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe,
12311 0x98, 0x80, 0xfe, 0x19,
12312 0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18,
12313 0xfe, 0x44, 0x54, 0xbe,
12314 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
12315 0x02, 0x4a, 0x08, 0x05,
12316 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e,
12317 0x9c, 0x3c, 0xfe, 0x6c,
12318 0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f,
12319 0x3b, 0x40, 0x03, 0x49,
12320 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
12321 0x8f, 0xfe, 0xe3, 0x54,
12322 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe,
12323 0xda, 0x09, 0xfe, 0x8b,
12324 0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa,
12325 0x0a, 0x3a, 0x49, 0x3b,
12326 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
12327 0xad, 0xfe, 0x01, 0x59,
12328 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a,
12329 0x49, 0x8f, 0xfe, 0xe3,
12330 0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02,
12331 0x4a, 0x3a, 0x49, 0x3b,
12332 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
12333 0x02, 0x4a, 0x08, 0x05,
12334 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62,
12335 0xb7, 0xfe, 0x03, 0xa1,
12336 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
12337 0xfe, 0x86, 0x91, 0x6a,
12338 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
12339 0x61, 0x0c, 0x7f, 0x14,
12340 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62,
12341 0x9b, 0x2e, 0x9c, 0x3c,
12342 0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05,
12343 0xfa, 0x3c, 0x01, 0xef,
12344 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
12345 0xe4, 0x08, 0x05, 0x1f,
12346 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37,
12347 0x03, 0x5e, 0x29, 0x5f,
12348 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe,
12349 0xf4, 0x09, 0x08, 0x05,
12350 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
12351 0x81, 0x50, 0xfe, 0x10,
12352 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe,
12353 0x08, 0x09, 0x12, 0xa6,
12354 0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe,
12355 0x08, 0x09, 0xfe, 0x0c,
12356 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
12357 0x08, 0x05, 0x0a, 0xfe,
12358 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1,
12359 0xf0, 0xe2, 0x15, 0x7e,
12360 0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19,
12361 0x57, 0x3d, 0xfe, 0xed,
12362 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
12363 0x00, 0xff, 0x35, 0xfe,
12364 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18,
12365 0x1e, 0x19, 0x8a, 0x03,
12366 0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65,
12367 0xfe, 0xd1, 0xf0, 0xfe,
12368 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
12369 0x10, 0xfe, 0xce, 0xf0,
12370 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b,
12371 0x10, 0xfe, 0x22, 0x00,
12372 0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00,
12373 0x02, 0x65, 0xfe, 0xd0,
12374 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
12375 0x0b, 0x10, 0x58, 0xfe,
12376 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe,
12377 0x12, 0x00, 0x2c, 0x0f,
12378 0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14,
12379 0x0c, 0xbc, 0x17, 0x34,
12380 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
12381 0x0c, 0x1c, 0x34, 0x94,
12382 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01,
12383 0x4b, 0xfe, 0xdb, 0x10,
12384 0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe,
12385 0x89, 0xf0, 0x24, 0x33,
12386 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
12387 0x33, 0x31, 0xdf, 0xbc,
12388 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49,
12389 0x17, 0xfe, 0x2c, 0x0d,
12390 0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54,
12391 0x12, 0x55, 0xfe, 0x28,
12392 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
12393 0x44, 0xfe, 0x28, 0x00,
12394 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26,
12395 0x0f, 0x64, 0x12, 0x2f,
12396 0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44,
12397 0x0a, 0xfe, 0xb4, 0x10,
12398 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
12399 0xfe, 0x34, 0x46, 0xac,
12400 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a,
12401 0x37, 0x01, 0xf5, 0x01,
12402 0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02,
12403 0xfe, 0x2e, 0x03, 0x08,
12404 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
12405 0x1a, 0xfe, 0x58, 0x12,
12406 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
12407 0xfe, 0x50, 0x0d, 0xfe,
12408 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37,
12409 0xfe, 0xa9, 0x10, 0x10,
12410 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
12411 0xfe, 0x13, 0x00, 0xfe,
12412 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe,
12413 0x24, 0x00, 0x8c, 0xb5,
12414 0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a,
12415 0xfe, 0x9d, 0x41, 0xfe,
12416 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
12417 0xb4, 0x15, 0xfe, 0x31,
12418 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06,
12419 0xec, 0xd0, 0xfc, 0x44,
12420 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47,
12421 0x4b, 0x91, 0xfe, 0x75,
12422 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
12423 0x0e, 0xfe, 0x44, 0x48,
12424 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41,
12425 0xfe, 0x41, 0x58, 0x09,
12426 0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe,
12427 0x2e, 0x03, 0x09, 0x5d,
12428 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
12429 0xce, 0x47, 0xfe, 0xad,
12430 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13,
12431 0x59, 0x13, 0x9f, 0x13,
12432 0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe,
12433 0xe0, 0x0e, 0x0f, 0x06,
12434 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
12435 0x3a, 0x01, 0x56, 0xfe,
12436 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec,
12437 0x20, 0x4f, 0xfe, 0x05,
12438 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe,
12439 0x48, 0xf4, 0x0d, 0xfe,
12440 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
12441 0x15, 0x1a, 0x39, 0xa0,
12442 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff,
12443 0x0c, 0xfe, 0x60, 0x01,
12444 0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25,
12445 0x06, 0x13, 0x2f, 0x12,
12446 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
12447 0x22, 0x9f, 0xb7, 0x13,
12448 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39,
12449 0xa0, 0xb4, 0xfe, 0xd9,
12450 0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04,
12451 0xc3, 0xfe, 0x03, 0xdc,
12452 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
12453 0xfe, 0x00, 0xcc, 0x04,
12454 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13,
12455 0xfe, 0x1c, 0x80, 0x07,
12456 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae,
12457 0xfe, 0x0c, 0x90, 0xfe,
12458 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
12459 0x0a, 0xfe, 0x3c, 0x50,
12460 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4,
12461 0x16, 0x08, 0x05, 0x1b,
12462 0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58,
12463 0xfe, 0x2c, 0x13, 0x01,
12464 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
12465 0x0c, 0xfe, 0x64, 0x01,
12466 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03,
12467 0x80, 0x8d, 0xfe, 0x01,
12468 0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64,
12469 0x22, 0x20, 0xfb, 0x79,
12470 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
12471 0x03, 0xfe, 0xae, 0x00,
12472
12473 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe,
12474 0xb2, 0x00, 0xfe, 0x09,
12475 0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c,
12476 0x45, 0x0f, 0x46, 0x52,
12477 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
12478 0x0f, 0x44, 0x11, 0x0f,
12479 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4,
12480 0x25, 0x11, 0x13, 0x20,
12481 0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14,
12482 0x56, 0xfe, 0xd6, 0xf0,
12483 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
12484 0x18, 0x1c, 0x04, 0x42,
12485 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe,
12486 0xf5, 0x13, 0x04, 0x01,
12487 0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
12488 0x13, 0x32, 0x07, 0x2f,
12489 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
12490 0x41, 0x48, 0xfe, 0x45,
12491 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78,
12492 0x07, 0x11, 0xac, 0x09,
12493 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07,
12494 0x82, 0x4e, 0xfe, 0x14,
12495 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
12496 0xfe, 0x01, 0xec, 0xa2,
12497 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79,
12498 0x2a, 0x01, 0xe3, 0xfe,
12499 0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a,
12500 0xfe, 0x48, 0x12, 0x07,
12501 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
12502 0xfe, 0x32, 0x12, 0x07,
12503 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07,
12504 0x1f, 0xfe, 0x12, 0x12,
12505 0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b,
12506 0x94, 0x4b, 0x04, 0x2d,
12507 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
12508 0x32, 0x07, 0xa6, 0xfe,
12509 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05,
12510 0x5a, 0xfe, 0x72, 0x12,
12511 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62,
12512 0xfe, 0x26, 0x13, 0x03,
12513 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
12514 0x0c, 0x7f, 0x0c, 0x80,
12515 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c,
12516 0x3c, 0xfe, 0x04, 0x55,
12517 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe,
12518 0x91, 0x10, 0x03, 0x3f,
12519 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
12520 0x88, 0x9b, 0x2e, 0x9c,
12521 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
12522 0x56, 0x0c, 0x5e, 0x14,
12523 0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40,
12524 0x03, 0x60, 0x29, 0x61,
12525 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
12526 0x50, 0xfe, 0xc6, 0x50,
12527 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d,
12528 0x29, 0x3e, 0xfe, 0x40,
12529 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72,
12530 0x2d, 0x01, 0x0b, 0x1d,
12531 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
12532 0x72, 0x01, 0xaf, 0x1e,
12533 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe,
12534 0x0a, 0x55, 0x35, 0xfe,
12535 0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51,
12536 0x02, 0x72, 0xfe, 0x19,
12537 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
12538 0x1d, 0xe8, 0x33, 0x31,
12539 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01,
12540 0x0b, 0x1c, 0x34, 0x1d,
12541 0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8,
12542 0x33, 0x31, 0xfe, 0xe8,
12543 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
12544 0x05, 0x1f, 0x35, 0xa9,
12545 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda,
12546 0x14, 0x01, 0xaf, 0x8c,
12547 0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a,
12548 0x03, 0x45, 0x28, 0x35,
12549 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
12550 0x03, 0x5c, 0xc1, 0x0c,
12551 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02,
12552 0x89, 0x01, 0x0b, 0x1c,
12553 0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1,
12554 0xfe, 0x42, 0x58, 0xf1,
12555 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
12556 0xf4, 0x06, 0xea, 0x32,
12557 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d,
12558 0x01, 0x0b, 0x26, 0x89,
12559 0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13,
12560 0x26, 0xfe, 0xd4, 0x13,
12561 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
12562 0x13, 0x1c, 0xfe, 0xd0,
12563 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10,
12564 0x0f, 0x71, 0xff, 0x02,
12565 0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe,
12566 0x00, 0x5c, 0x04, 0x0f,
12567 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
12568 0xfe, 0x00, 0x5c, 0x04,
12569 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff,
12570 0x02, 0x00, 0x57, 0x52,
12571 0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01,
12572 0x87, 0x04, 0xfe, 0x03,
12573 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
12574 0xfe, 0x00, 0x7d, 0xfe,
12575 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e,
12576 0x14, 0x5f, 0x57, 0x3f,
12577 0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83,
12578 0x5a, 0x8d, 0x04, 0x01,
12579 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
12580 0xfe, 0x96, 0x15, 0x33,
12581 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8,
12582 0x0a, 0xfe, 0xc1, 0x59,
12583 0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13,
12584 0x21, 0x69, 0x1a, 0xee,
12585 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
12586 0x30, 0xfe, 0x78, 0x10,
12587 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae,
12588 0x98, 0xfe, 0x30, 0x00,
12589 0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed,
12590 0x98, 0xfe, 0x64, 0x00,
12591 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
12592 0x10, 0x69, 0x06, 0xfe,
12593 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00,
12594 0x18, 0x59, 0x0f, 0x06,
12595 0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe,
12596 0x43, 0xf4, 0x9f, 0xfe,
12597 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
12598 0x9e, 0xfe, 0xf3, 0x10,
12599 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00,
12600 0x17, 0xfe, 0x4d, 0xe4,
12601 0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00,
12602 0x17, 0xfe, 0x4d, 0xe4,
12603 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
12604 0xf4, 0x00, 0xe9, 0x91,
12605 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a,
12606 0x04, 0x16, 0x06, 0x01,
12607 0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01,
12608 0x0b, 0x26, 0xf3, 0x76,
12609 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
12610 0x16, 0x19, 0x01, 0x0b,
12611 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01,
12612 0x0b, 0x26, 0xb1, 0x76,
12613 0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06,
12614 0xfe, 0x48, 0x13, 0xb8,
12615 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
12616 0xec, 0xfe, 0x27, 0x01,
12617 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32,
12618 0x07, 0xfe, 0xe3, 0x00,
12619 0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b,
12620 0x22, 0xd4, 0x07, 0x06,
12621 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
12622 0x07, 0x11, 0xae, 0x09,
12623 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01,
12624 0x0e, 0x8e, 0xfe, 0x80,
12625 0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04,
12626 0x09, 0x48, 0x01, 0x0e,
12627 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
12628 0x80, 0xfe, 0x80, 0x4c,
12629 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c,
12630 0x09, 0x5d, 0x01, 0x87,
12631 0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe,
12632 0x19, 0xde, 0xfe, 0x24,
12633 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
12634 0x17, 0xad, 0x9a, 0x1b,
12635 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde,
12636 0x16, 0xfe, 0xda, 0x10,
12637 0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe,
12638 0x18, 0x58, 0x03, 0xfe,
12639 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
12640 0xf4, 0x06, 0xfe, 0x3c,
12641 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f,
12642 0x97, 0xfe, 0x38, 0x17,
12643 0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c,
12644 0x10, 0x18, 0x11, 0x75,
12645 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
12646 0x2e, 0x97, 0xfe, 0x5a,
12647 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19,
12648 0xfe, 0x98, 0xe7, 0x00,
12649 0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75,
12650 0xfe, 0x30, 0xbc, 0xfe,
12651 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
12652 0xcb, 0x97, 0xfe, 0x92,
12653 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe,
12654 0x42, 0x10, 0xfe, 0x02,
12655 0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe,
12656 0x03, 0xa1, 0xfe, 0x1d,
12657 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
12658 0x9a, 0x5b, 0x41, 0xfe,
12659 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7,
12660 0x11, 0x12, 0xfe, 0xdd,
12661 0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8,
12662 0x17, 0x15, 0x06, 0x39,
12663 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
12664 0xfe, 0x7e, 0x18, 0x1e,
12665 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef,
12666 0x12, 0xfe, 0xe1, 0x10,
12667 0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42,
12668 0x13, 0x42, 0x92, 0x09,
12669 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
12670 0xf0, 0xfe, 0x00, 0xcc,
12671 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01,
12672 0x0e, 0xfe, 0x80, 0x4c,
12673 0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe,
12674 0x24, 0x12, 0xfe, 0x14,
12675 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
12676 0xe7, 0x0a, 0x10, 0xfe,
12677 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92,
12678 0x08, 0x54, 0x1b, 0x37,
12679 0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba,
12680 0x90, 0x3a, 0xce, 0x3b,
12681 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
12682 0x13, 0xa3, 0x04, 0x09,
12683 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49,
12684 0x44, 0x17, 0xfe, 0xe8,
12685 0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09,
12686 0x5d, 0x01, 0xa8, 0x09,
12687 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
12688 0x1c, 0x19, 0x03, 0xfe,
12689 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9,
12690 0x6b, 0xfe, 0x2e, 0x19,
12691 0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4,
12692 0xfe, 0x0b, 0x00, 0x6b,
12693 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
12694 0x08, 0x10, 0x03, 0xfe,
12695 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff,
12696 0x04, 0x68, 0x54, 0xe7,
12697 0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe,
12698 0x1a, 0xf4, 0xfe, 0x00,
12699 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
12700 0x04, 0x07, 0x7e, 0xfe,
12701 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
12702 0x07, 0x1a, 0xfe, 0x5a,
12703 0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66,
12704 0x25, 0x6d, 0xe5, 0x07,
12705 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
12706 0xa9, 0xb8, 0x04, 0x15,
12707 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe,
12708 0x40, 0x5c, 0x04, 0x1c,
12709 0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b,
12710 0xf7, 0xfe, 0x82, 0xf0,
12711 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
1da177e4
LT
12712};
12713
27c868c2
MW
12714static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
12715static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
1da177e4
LT
12716
12717/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
12718static unsigned char _adv_asc38C1600_buf[] = {
12719 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
12720 0x18, 0xe4, 0x01, 0x00,
12721 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00,
12722 0x07, 0x17, 0xc0, 0x5f,
12723 0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7,
12724 0x85, 0xf0, 0x86, 0xf0,
12725 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
12726 0x98, 0x57, 0x01, 0xe6,
12727 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d,
12728 0x38, 0x54, 0x32, 0xf0,
12729 0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4,
12730 0x00, 0xe6, 0xb1, 0xf0,
12731 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
12732 0x06, 0x13, 0x0c, 0x1c,
12733 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12,
12734 0xb9, 0x54, 0x00, 0x80,
12735 0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56,
12736 0x03, 0xe6, 0x01, 0xea,
12737 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
12738 0x04, 0x13, 0xbb, 0x55,
12739 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00,
12740 0xbb, 0x00, 0xc0, 0x00,
12741 0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12,
12742 0x4c, 0x1c, 0x4e, 0x1c,
12743 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
12744 0x24, 0x01, 0x3c, 0x01,
12745 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01,
12746 0x78, 0x01, 0x7c, 0x01,
12747 0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c,
12748 0x6e, 0x1e, 0x02, 0x48,
12749 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
12750 0x03, 0xfc, 0x06, 0x00,
12751 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a,
12752 0x30, 0x1c, 0x38, 0x1c,
12753 0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea,
12754 0x5d, 0xf0, 0xa7, 0xf0,
12755 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
12756 0x33, 0x00, 0x34, 0x00,
12757 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01,
12758 0x79, 0x01, 0x3c, 0x09,
12759 0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13,
12760 0x40, 0x16, 0x50, 0x16,
12761 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
12762 0x05, 0xf0, 0x09, 0xf0,
12763 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00,
12764 0x9c, 0x00, 0xa4, 0x00,
12765 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08,
12766 0xe9, 0x09, 0x5c, 0x0c,
12767 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
12768 0x42, 0x1d, 0x08, 0x44,
12769 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54,
12770 0x83, 0x55, 0x83, 0x59,
12771 0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0,
12772 0x4b, 0xf4, 0x04, 0xf8,
12773 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
12774 0xa8, 0x00, 0xaa, 0x00,
12775 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01,
12776 0x7a, 0x01, 0x82, 0x01,
12777 0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07,
12778 0x68, 0x08, 0x10, 0x0d,
12779 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
12780 0xf3, 0x10, 0x06, 0x12,
12781 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c,
12782 0xf0, 0x35, 0x05, 0xfe,
12783 0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8,
12784 0xfe, 0x88, 0x01, 0xff,
12785 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
12786 0x00, 0xfe, 0x57, 0x24,
12787 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09,
12788 0x00, 0x00, 0xff, 0x08,
12789 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
12790 0xff, 0xff, 0xff, 0x13,
12791 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
12792 0xfe, 0x04, 0xf7, 0xe8,
12793 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d,
12794 0x0d, 0x51, 0x37, 0xfe,
12795 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0,
12796 0xfe, 0xf8, 0x01, 0xfe,
12797 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
12798 0x05, 0xfe, 0x08, 0x0f,
12799 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe,
12800 0x28, 0x1c, 0x03, 0xfe,
12801 0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe,
12802 0x48, 0xf0, 0xfe, 0x90,
12803 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
12804 0x02, 0xfe, 0x46, 0xf0,
12805 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0,
12806 0xfe, 0x4e, 0x02, 0xfe,
12807 0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c,
12808 0x0d, 0xa2, 0x1c, 0x07,
12809 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
12810 0x1c, 0xf5, 0xfe, 0x1e,
12811 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc,
12812 0xde, 0x0a, 0x81, 0x01,
12813 0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a,
12814 0x81, 0x01, 0x5c, 0xfe,
12815 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
12816 0xfe, 0x58, 0x1c, 0x1c,
12817 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02,
12818 0x2b, 0xfe, 0x9e, 0x02,
12819 0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30,
12820 0x00, 0x47, 0xb8, 0x01,
12821 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
12822 0x1a, 0x31, 0xfe, 0x69,
12823 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe,
12824 0x1e, 0x1e, 0x20, 0x2c,
12825 0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a,
12826 0x44, 0x15, 0x56, 0x51,
12827 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
12828 0x01, 0x18, 0x09, 0x00,
12829 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01,
12830 0x18, 0xfe, 0xc8, 0x54,
12831 0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60,
12832 0xfe, 0x02, 0xe8, 0x30,
12833 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
12834 0xfe, 0xe4, 0x01, 0xfe,
12835 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe,
12836 0x26, 0xf0, 0xfe, 0x66,
12837 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe,
12838 0xef, 0x10, 0xfe, 0x9f,
12839 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
12840 0x70, 0x37, 0xfe, 0x48,
12841 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26,
12842 0x21, 0xb9, 0xc7, 0x20,
12843 0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15,
12844 0xe1, 0x2a, 0xeb, 0xfe,
12845 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
12846 0x15, 0xfe, 0xe4, 0x00,
12847 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41,
12848 0xfe, 0x06, 0xf0, 0xfe,
12849 0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29,
12850 0x03, 0x81, 0x1e, 0x1b,
12851 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
12852 0xea, 0xfe, 0x46, 0x1c,
12853 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
12854 0xfe, 0x48, 0x1c, 0x75,
12855 0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a,
12856 0xe1, 0x01, 0x18, 0x77,
12857 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
12858 0x8f, 0xfe, 0x70, 0x02,
12859 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04,
12860 0x16, 0xfe, 0x4a, 0x04,
12861 0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff,
12862 0x02, 0x00, 0x10, 0x01,
12863 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
12864 0xee, 0xfe, 0x4c, 0x44,
12865 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54,
12866 0x7b, 0xec, 0x60, 0x8d,
12867 0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01,
12868 0x0c, 0x06, 0x28, 0xfe,
12869 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
12870 0x13, 0x34, 0xfe, 0x4c,
12871 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54,
12872 0x13, 0x01, 0x0c, 0x06,
12873 0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06,
12874 0x28, 0xf9, 0x1f, 0x7f,
12875 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
12876 0xfe, 0xa4, 0x0e, 0x05,
12877 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe,
12878 0x9c, 0x93, 0x3a, 0x0b,
12879 0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b,
12880 0x7d, 0x1d, 0xfe, 0x46,
12881 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
12882 0xfe, 0x87, 0x83, 0xfe,
12883 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98,
12884 0x13, 0x0f, 0xfe, 0x20,
12885 0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84,
12886 0x12, 0x01, 0x38, 0x06,
12887 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
12888 0x05, 0xd0, 0x54, 0x01,
12889 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe,
12890 0x50, 0x12, 0x5e, 0xff,
12891 0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02,
12892 0x00, 0x10, 0x2f, 0xfe,
12893 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
12894 0x38, 0xfe, 0x4a, 0xf0,
12895 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe,
12896 0x21, 0x00, 0xf1, 0x2e,
12897 0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00,
12898 0x10, 0x2f, 0xfe, 0xd0,
12899 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
12900 0x1c, 0x00, 0x4d, 0x01,
12901 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06,
12902 0x28, 0xfe, 0x24, 0x12,
12903 0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe,
12904 0x0d, 0x00, 0x01, 0x42,
12905 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
12906 0x03, 0xb6, 0x1e, 0xfe,
12907 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17,
12908 0xfe, 0x72, 0x06, 0x0a,
12909 0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56,
12910 0x19, 0x16, 0xfe, 0x68,
12911 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
12912 0x03, 0x9a, 0x1e, 0xfe,
12913 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12,
12914 0x48, 0xfe, 0x92, 0x06,
12915 0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13,
12916 0x58, 0xff, 0x02, 0x00,
12917 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
12918 0xfe, 0xea, 0x06, 0x01,
12919 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16,
12920 0xfe, 0xe0, 0x06, 0x15,
12921 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07,
12922 0x01, 0x84, 0xfe, 0xae,
12923 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
12924 0x1e, 0xfe, 0x1a, 0x12,
12925 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
12926 0x43, 0x48, 0x62, 0x80,
12927 0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24,
12928 0x36, 0xfe, 0x02, 0xf6,
12929 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
12930 0xd0, 0x0d, 0x17, 0xfe,
12931 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20,
12932 0x9e, 0x15, 0x82, 0x01,
12933 0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58,
12934 0x57, 0x10, 0xe6, 0x05,
12935 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
12936 0xfe, 0x9c, 0x32, 0x5f,
12937 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c,
12938 0xfe, 0x0a, 0xf0, 0xfe,
12939 0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08,
12940 0xaf, 0xa0, 0x05, 0x29,
12941 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
12942 0x00, 0x01, 0x08, 0x14,
12943 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08,
12944 0x14, 0x00, 0x05, 0xfe,
12945 0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06,
12946 0x12, 0xfe, 0x30, 0x13,
12947 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
12948 0x01, 0x08, 0x14, 0x00,
12949 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a,
12950 0x78, 0x4f, 0x0f, 0xfe,
12951 0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d,
12952 0x28, 0x48, 0xfe, 0x6c,
12953 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
12954 0x12, 0x53, 0x63, 0x4e,
12955 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe,
12956 0x6c, 0x08, 0xaf, 0xa0,
12957 0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24,
12958 0x05, 0xed, 0xfe, 0x9c,
12959 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
12960 0x1e, 0xfe, 0x99, 0x58,
12961 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a,
12962 0x22, 0x6b, 0x01, 0x0c,
12963 0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e,
12964 0x1e, 0x47, 0x2c, 0x7a,
12965 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
12966 0x01, 0x0c, 0x61, 0x65,
12967 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a,
12968 0x16, 0xfe, 0x08, 0x50,
12969 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10,
12970 0x01, 0xfe, 0xce, 0x1e,
12971 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
12972 0x01, 0xfe, 0xfe, 0x1e,
12973 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a,
12974 0x10, 0x01, 0x0c, 0x06,
12975 0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e,
12976 0x10, 0x6a, 0x22, 0x6b,
12977 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
12978 0xfe, 0x9f, 0x83, 0x33,
12979 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93,
12980 0x3a, 0x0b, 0xfe, 0xc6,
12981 0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d,
12982 0x01, 0xfe, 0xce, 0x1e,
12983 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
12984 0x04, 0xfe, 0xc0, 0x93,
12985 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e,
12986 0x10, 0x4b, 0x22, 0x4c,
12987 0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe,
12988 0x4e, 0x11, 0x2f, 0xfe,
12989 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
12990 0x3c, 0x37, 0x88, 0xf5,
12991 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a,
12992 0xd3, 0xfe, 0x42, 0x0a,
12993 0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0,
12994 0x05, 0x29, 0x01, 0x41,
12995 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
12996 0xfe, 0x14, 0x12, 0x01,
12997 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe,
12998 0x2e, 0x1c, 0x05, 0xfe,
12999 0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41,
13000 0xfe, 0x2c, 0x1c, 0xfe,
13001 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
13002 0x92, 0x10, 0xc4, 0xf6,
13003 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe,
13004 0xe7, 0x10, 0xfe, 0x2b,
13005 0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12,
13006 0xac, 0xfe, 0xd2, 0xf0,
13007 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
13008 0x1b, 0xbf, 0xd4, 0x5b,
13009 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75,
13010 0x5e, 0x32, 0x1f, 0x7f,
13011 0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98,
13012 0x05, 0x70, 0xfe, 0x74,
13013 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
13014 0x0f, 0x4d, 0x01, 0xfe,
13015 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06,
13016 0x0d, 0x2b, 0xfe, 0xe2,
13017 0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24,
13018 0xfe, 0x88, 0x13, 0x21,
13019 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
13020 0x83, 0x83, 0xfe, 0xc9,
13021 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04,
13022 0x91, 0x04, 0xfe, 0x84,
13023 0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93,
13024 0xfe, 0xcb, 0x57, 0x0b,
13025 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
13026 0x6a, 0x3b, 0x6b, 0x10,
13027 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30,
13028 0x20, 0x6e, 0xdb, 0x64,
13029 0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55,
13030 0xfe, 0x04, 0xfa, 0x64,
13031 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
13032 0x10, 0x98, 0x91, 0x6c,
13033 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91,
13034 0x4b, 0x7e, 0x4c, 0x01,
13035 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10,
13036 0x58, 0xfe, 0x91, 0x58,
13037 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
13038 0x1b, 0x40, 0x01, 0x0c,
13039 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f,
13040 0xfe, 0x10, 0x90, 0x04,
13041 0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93,
13042 0x79, 0x0b, 0x0e, 0xfe,
13043 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
13044 0x01, 0x0c, 0x06, 0x0d,
13045 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe,
13046 0x0c, 0x58, 0xfe, 0x8d,
13047 0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99,
13048 0x83, 0x33, 0x0b, 0x0e,
13049 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
13050 0x19, 0xfe, 0x19, 0x41,
13051 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42,
13052 0x19, 0xfe, 0x44, 0x00,
13053 0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda,
13054 0x4c, 0xfe, 0x0c, 0x51,
13055 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
13056 0x76, 0x10, 0xac, 0xfe,
13057 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03,
13058 0xe3, 0x23, 0x07, 0xfe,
13059 0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe,
13060 0xcc, 0x0c, 0x1f, 0x92,
13061 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
13062 0x0c, 0xfe, 0x3e, 0x10,
13063 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70,
13064 0xfe, 0xcb, 0xf0, 0xfe,
13065 0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe,
13066 0xf4, 0x0c, 0x19, 0x94,
13067 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
13068 0xfe, 0xcc, 0xf0, 0xef,
13069 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe,
13070 0x4e, 0x11, 0x2f, 0xfe,
13071 0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b,
13072 0x3c, 0x37, 0x88, 0xf5,
13073 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
13074 0x2f, 0xfe, 0x3e, 0x0d,
13075 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f,
13076 0xd2, 0x9f, 0xd3, 0x9f,
13077 0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4,
13078 0xc5, 0x75, 0xd7, 0x99,
13079 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
13080 0x9c, 0x2f, 0xfe, 0x8c,
13081 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe,
13082 0x42, 0x00, 0x05, 0x70,
13083 0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06,
13084 0x0d, 0xfe, 0x44, 0x13,
13085 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
13086 0xfe, 0xda, 0x0e, 0x0a,
13087 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa,
13088 0x10, 0x01, 0xfe, 0xf4,
13089 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40,
13090 0x15, 0x56, 0x01, 0x85,
13091 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
13092 0xcc, 0x10, 0x01, 0xa7,
13093 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04,
13094 0xfe, 0x99, 0x83, 0xfe,
13095 0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe,
13096 0x43, 0x00, 0xfe, 0xa2,
13097 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
13098 0x00, 0x1d, 0x40, 0x15,
13099 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05,
13100 0xfe, 0x3a, 0x03, 0x01,
13101 0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01,
13102 0x76, 0x06, 0x12, 0xfe,
13103 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
13104 0xfe, 0x9d, 0xf0, 0xfe,
13105 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01,
13106 0x0c, 0x61, 0x12, 0x44,
13107 0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f,
13108 0xfe, 0x2e, 0x10, 0x19,
13109 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
13110 0xfe, 0x41, 0x00, 0xa2,
13111 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b,
13112 0xea, 0x4f, 0xfe, 0x04,
13113 0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05,
13114 0x35, 0xfe, 0x12, 0x1c,
13115 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
13116 0xfe, 0xd4, 0x11, 0x05,
13117 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe,
13118 0xce, 0x45, 0x31, 0x51,
13119 0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03,
13120 0x67, 0xfe, 0x98, 0x56,
13121 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
13122 0x0c, 0x06, 0x28, 0xfe,
13123 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba,
13124 0xfe, 0xfa, 0x14, 0xfe,
13125 0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67,
13126 0xfe, 0xe0, 0x14, 0xfe,
13127 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
13128 0xfe, 0xad, 0x13, 0x05,
13129 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20,
13130 0xe7, 0xfe, 0x08, 0x1c,
13131 0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe,
13132 0x48, 0x55, 0xa5, 0x3b,
13133 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
13134 0xf0, 0x1a, 0x03, 0xfe,
13135 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02,
13136 0xec, 0xe7, 0x53, 0x00,
13137 0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
13138 0x01, 0xfe, 0x62, 0x1b,
13139 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
13140 0xea, 0xe7, 0x53, 0x92,
13141 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03,
13142 0xfe, 0x38, 0x01, 0x23,
13143 0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62,
13144 0x01, 0x01, 0xfe, 0x1e,
13145 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
13146 0x26, 0x02, 0x21, 0x96,
13147 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5,
13148 0xc3, 0xfe, 0xe1, 0x10,
13149 0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf,
13150 0xfe, 0x03, 0xdc, 0xfe,
13151 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
13152 0x00, 0xcc, 0x02, 0xfe,
13153 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13,
13154 0x0f, 0xfe, 0x1c, 0x80,
13155 0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13,
13156 0x0f, 0xfe, 0x1e, 0x80,
13157 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
13158 0x1d, 0x80, 0x04, 0xfe,
13159 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee,
13160 0x1e, 0xac, 0xfe, 0x14,
13161 0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e,
13162 0x1f, 0xfe, 0x30, 0xf4,
13163 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
13164 0x56, 0xfb, 0x01, 0xfe,
13165 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01,
13166 0xfe, 0x00, 0x1d, 0x15,
13167 0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe,
13168 0x22, 0x1b, 0xfe, 0x1e,
13169 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
13170 0x96, 0x90, 0x04, 0xfe,
13171 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66,
13172 0x01, 0x01, 0x0c, 0x06,
13173 0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b,
13174 0x0e, 0x77, 0xfe, 0x01,
13175 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
13176 0x21, 0x2c, 0xfe, 0x00,
13177 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe,
13178 0x06, 0x58, 0x03, 0xfe,
13179 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58,
13180 0x03, 0xfe, 0xb2, 0x00,
13181 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
13182 0x66, 0x10, 0x55, 0x10,
13183 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91,
13184 0x54, 0x2b, 0xfe, 0x88,
13185 0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe,
13186 0x91, 0x54, 0x2b, 0xfe,
13187 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
13188 0x00, 0x40, 0x8d, 0x2c,
13189 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe,
13190 0x12, 0x1c, 0x75, 0xfe,
13191 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c,
13192 0x14, 0xfe, 0x0e, 0x47,
13193 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
13194 0xa7, 0x90, 0x34, 0x60,
13195 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80,
13196 0x09, 0x56, 0xfe, 0x34,
13197 0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48,
13198 0xfe, 0x45, 0x48, 0x01,
13199 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
13200 0x09, 0x1a, 0xa5, 0x0a,
13201 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4,
13202 0xfe, 0x14, 0x56, 0xfe,
13203 0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01,
13204 0xec, 0xb8, 0xfe, 0x9e,
13205 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
13206 0xf4, 0xfe, 0xdd, 0x10,
13207 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48,
13208 0x12, 0x09, 0x0d, 0xfe,
13209 0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4,
13210 0x13, 0x09, 0xfe, 0x23,
13211 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
13212 0x24, 0xfe, 0x12, 0x12,
13213 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08,
13214 0xae, 0x41, 0x02, 0x32,
13215 0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05,
13216 0x35, 0x32, 0x01, 0x43,
13217 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
13218 0x13, 0x01, 0x0c, 0x06,
13219 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe,
13220 0xe5, 0x55, 0xb0, 0xfe,
13221 0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e,
13222 0xfe, 0xb6, 0x0e, 0x10,
13223 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
13224 0x88, 0x20, 0x6e, 0x01,
13225 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5,
13226 0x55, 0xfe, 0x04, 0xfa,
13227 0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d,
13228 0xfe, 0x40, 0x56, 0xfe,
13229 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
13230 0x44, 0x55, 0xfe, 0xe5,
13231 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10,
13232 0x68, 0x22, 0x69, 0x01,
13233 0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b,
13234 0x6b, 0xfe, 0x2c, 0x50,
13235 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
13236 0x50, 0x03, 0x68, 0x3b,
13237 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe,
13238 0x40, 0x50, 0xfe, 0xc2,
13239 0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08,
13240 0x16, 0x3d, 0x27, 0x25,
13241 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
13242 0xa6, 0x23, 0x3f, 0x1b,
13243 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c,
13244 0xfe, 0x0a, 0x55, 0x31,
13245 0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e,
13246 0x51, 0x05, 0x72, 0x01,
13247 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
13248 0x2a, 0x3c, 0x16, 0xc0,
13249 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b,
13250 0xfe, 0x66, 0x15, 0x05,
13251 0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d,
13252 0x2b, 0x3d, 0x01, 0x08,
13253 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
13254 0xb6, 0x1e, 0x83, 0x01,
13255 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46,
13256 0x07, 0x90, 0x3f, 0x01,
13257 0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13,
13258 0x01, 0x43, 0x09, 0x82,
13259 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
13260 0x05, 0x72, 0xfe, 0xc0,
13261 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e,
13262 0x32, 0x01, 0x08, 0x17,
13263 0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16,
13264 0x3d, 0x27, 0x25, 0xbd,
13265 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
13266 0xe8, 0x14, 0x01, 0xa6,
13267 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe,
13268 0x0e, 0x12, 0x01, 0x43,
13269 0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32,
13270 0x01, 0x08, 0x17, 0x73,
13271 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
13272 0x27, 0x25, 0xbd, 0x09,
13273 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe,
13274 0xb6, 0x14, 0x86, 0xa8,
13275 0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09,
13276 0x82, 0x4e, 0x05, 0x72,
13277 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
13278 0xfe, 0xc0, 0x19, 0x05,
13279 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f,
13280 0xcc, 0x01, 0x08, 0x26,
13281 0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe,
13282 0xcc, 0x15, 0x5e, 0x32,
13283 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
13284 0xad, 0x23, 0xfe, 0xff,
13285 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02,
13286 0x00, 0x57, 0x52, 0xad,
13287 0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff,
13288 0x02, 0x00, 0x57, 0x52,
13289 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
13290 0x02, 0x13, 0x58, 0xff,
13291 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01,
13292 0x5c, 0x0a, 0x55, 0x01,
13293 0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a,
13294 0xff, 0x03, 0x00, 0x54,
13295 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
13296 0x7c, 0x3a, 0x0b, 0x0e,
13297 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19,
13298 0xfe, 0x1a, 0xf7, 0x00,
13299 0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c,
13300 0xda, 0x6d, 0x02, 0xfe,
13301 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
13302 0x02, 0x01, 0xc6, 0xfe,
13303 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27,
13304 0x25, 0xbe, 0x01, 0x08,
13305 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59,
13306 0x03, 0x9a, 0x1e, 0xfe,
13307 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
13308 0x48, 0xfe, 0x08, 0x17,
13309 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26,
13310 0x17, 0x4d, 0x13, 0x07,
13311 0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1,
13312 0xff, 0x02, 0x83, 0x55,
13313 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
13314 0x17, 0x1c, 0x63, 0x13,
13315 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64,
13316 0x00, 0xb0, 0xfe, 0x80,
13317 0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10,
13318 0x53, 0x07, 0xfe, 0x60,
13319 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
13320 0x00, 0x1c, 0x95, 0x13,
13321 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3,
13322 0xfe, 0x43, 0xf4, 0x96,
13323 0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43,
13324 0xf4, 0x94, 0xf6, 0x8b,
13325 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
13326 0xda, 0x17, 0x62, 0x49,
13327 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80,
13328 0x71, 0x50, 0x26, 0xfe,
13329 0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3,
13330 0x58, 0x02, 0x50, 0x13,
13331 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
13332 0x25, 0xbe, 0xfe, 0x03,
13333 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9,
13334 0x0a, 0x01, 0x08, 0x16,
13335 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01,
13336 0x01, 0x08, 0x16, 0xa9,
13337 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
13338 0x08, 0x16, 0xa9, 0x27,
13339 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83,
13340 0x01, 0x38, 0x06, 0x24,
13341 0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1,
13342 0x78, 0x03, 0x9a, 0x1e,
13343 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
13344 0xfe, 0x40, 0x5a, 0x23,
13345 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c,
13346 0x80, 0x48, 0xfe, 0xaa,
13347 0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01,
13348 0xfe, 0xac, 0x1d, 0xfe,
13349 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
13350 0x43, 0x48, 0x2d, 0x93,
13351 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4,
13352 0x36, 0xfe, 0x34, 0xf4,
13353 0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe,
13354 0x28, 0x10, 0xfe, 0xc0,
13355 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
13356 0x18, 0x45, 0xfe, 0x1c,
13357 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c,
13358 0x19, 0xfe, 0x04, 0xf4,
13359 0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d,
13360 0x21, 0xfe, 0x7f, 0x01,
13361 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
13362 0x7e, 0x01, 0xfe, 0xc8,
13363 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa,
13364 0x21, 0xfe, 0x81, 0x01,
13365 0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50,
13366 0x13, 0x0d, 0x02, 0x14,
13367 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
13368 0xfe, 0x82, 0x19, 0x14,
13369 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01,
13370 0x08, 0x02, 0x14, 0x07,
13371 0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07,
13372 0x01, 0x08, 0x17, 0xc1,
13373 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
13374 0x08, 0x02, 0x50, 0x02,
13375 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74,
13376 0x14, 0x12, 0x01, 0x08,
13377 0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01,
13378 0x08, 0x17, 0x74, 0xfe,
13379 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
13380 0x74, 0x5f, 0xcc, 0x01,
13381 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4,
13382 0xfe, 0x49, 0xf4, 0x00,
13383 0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff,
13384 0x02, 0x00, 0x10, 0x2f,
13385 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
13386 0x16, 0xfe, 0x64, 0x1a,
13387 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c,
13388 0x61, 0x07, 0x44, 0x02,
13389 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12,
13390 0x13, 0x0a, 0x9d, 0x01,
13391 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
13392 0xfe, 0x80, 0xe7, 0x1a,
13393 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02,
13394 0x0a, 0x5a, 0x01, 0x18,
13395 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe,
13396 0x7e, 0x1e, 0xfe, 0x80,
13397 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
13398 0xfe, 0x80, 0x4c, 0x0a,
13399 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf,
13400 0xfe, 0x19, 0xde, 0xfe,
13401 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe,
13402 0x2a, 0x1c, 0xfa, 0xb3,
13403 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
13404 0xf4, 0x1a, 0xfe, 0xfa,
13405 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24,
13406 0xfe, 0x18, 0x58, 0x03,
13407 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f,
13408 0xfe, 0x30, 0xf4, 0x07,
13409 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
13410 0xf7, 0x24, 0xb1, 0xfe,
13411 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b,
13412 0xfe, 0xba, 0x10, 0x1c,
13413 0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
13414 0x1d, 0xf7, 0x54, 0xb1,
13415 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
13416 0xaf, 0x19, 0xfe, 0x98,
13417 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c,
13418 0x1a, 0x87, 0x8b, 0x0f,
13419 0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58,
13420 0xfe, 0x32, 0x90, 0x04,
13421 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
13422 0x7c, 0x12, 0xfe, 0x0f,
13423 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14,
13424 0x31, 0x02, 0xc9, 0x2b,
13425 0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe,
13426 0x6a, 0xfe, 0x19, 0xfe,
13427 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
13428 0x1b, 0xfe, 0x36, 0x14,
13429 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19,
13430 0xfe, 0x80, 0xe7, 0x1a,
13431 0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a,
13432 0x30, 0xfe, 0x12, 0x45,
13433 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
13434 0x39, 0xf0, 0x75, 0x26,
13435 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03,
13436 0xe3, 0x23, 0x07, 0xfe,
13437 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09,
13438 0x56, 0xfe, 0x3c, 0x13,
13439 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
13440 0x01, 0x18, 0xcb, 0xfe,
13441 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16,
13442 0xfe, 0x00, 0xcc, 0xcb,
13443 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18,
13444 0xfe, 0x80, 0x4c, 0x01,
13445 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
13446 0x12, 0xfe, 0x14, 0x56,
13447 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7,
13448 0x0d, 0x19, 0xfe, 0x15,
13449 0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06,
13450 0x83, 0xfe, 0x18, 0x80,
13451 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
13452 0x90, 0xfe, 0xba, 0x90,
13453 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02,
13454 0x21, 0xb9, 0x88, 0x20,
13455 0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01,
13456 0x18, 0xfe, 0x49, 0x44,
13457 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
13458 0x1a, 0xa4, 0x0a, 0x67,
13459 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4,
13460 0x1d, 0x7b, 0xfe, 0x52,
13461 0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe,
13462 0x4e, 0xe4, 0xdd, 0x7b,
13463 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
13464 0xfe, 0x4e, 0xe4, 0xfe,
13465 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24,
13466 0xfe, 0x08, 0x10, 0x03,
13467 0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04,
13468 0x68, 0x54, 0xfe, 0xf1,
13469 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
13470 0xfe, 0x1a, 0xf4, 0xfe,
13471 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02,
13472 0x09, 0x92, 0xfe, 0x5a,
13473 0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe,
13474 0x5a, 0xf0, 0xfe, 0xc8,
13475 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
13476 0x1a, 0x10, 0x09, 0x0d,
13477 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02,
13478 0x1f, 0x93, 0x01, 0x42,
13479 0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e,
13480 0xfe, 0x14, 0xf0, 0x08,
13481 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
13482 0xfe, 0x82, 0xf0, 0xfe,
13483 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e,
13484 0x02, 0x0f, 0xfe, 0x18,
13485 0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02,
13486 0x80, 0x04, 0xfe, 0x82,
13487 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
13488 0x83, 0x33, 0x0b, 0x0e,
13489 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e,
13490 0x02, 0x0f, 0xfe, 0x04,
13491 0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80,
13492 0x80, 0x04, 0xfe, 0x80,
13493 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
13494 0xfe, 0x99, 0x83, 0xfe,
13495 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86,
13496 0x83, 0xfe, 0xce, 0x47,
13497 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a,
13498 0x0b, 0x0e, 0x02, 0x0f,
13499 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13500 0xfe, 0x08, 0x90, 0x04,
13501 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04,
13502 0xfe, 0x8a, 0x93, 0x79,
13503 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a,
13504 0x0b, 0x0e, 0x02, 0x0f,
13505 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13506 0xfe, 0x3c, 0x90, 0x04,
13507 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80,
13508 0x04, 0xfe, 0x83, 0x83,
13509 0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
1da177e4
LT
13510};
13511
27c868c2
MW
13512static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
13513static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
1da177e4
LT
13514
13515/* a_init.c */
13516/*
13517 * EEPROM Configuration.
13518 *
13519 * All drivers should use this structure to set the default EEPROM
13520 * configuration. The BIOS now uses this structure when it is built.
13521 * Additional structure information can be found in a_condor.h where
13522 * the structure is defined.
13523 *
13524 * The *_Field_IsChar structs are needed to correct for endianness.
13525 * These values are read from the board 16 bits at a time directly
13526 * into the structs. Because some fields are char, the values will be
13527 * in the wrong order. The *_Field_IsChar tells when to flip the
13528 * bytes. Data read and written to PCI memory is automatically swapped
13529 * on big-endian platforms so char fields read as words are actually being
13530 * unswapped on big-endian platforms.
13531 */
78e77d8b 13532static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
27c868c2
MW
13533 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
13534 0x0000, /* cfg_msw */
13535 0xFFFF, /* disc_enable */
13536 0xFFFF, /* wdtr_able */
13537 0xFFFF, /* sdtr_able */
13538 0xFFFF, /* start_motor */
13539 0xFFFF, /* tagqng_able */
13540 0xFFFF, /* bios_scan */
13541 0, /* scam_tolerant */
13542 7, /* adapter_scsi_id */
13543 0, /* bios_boot_delay */
13544 3, /* scsi_reset_delay */
13545 0, /* bios_id_lun */
13546 0, /* termination */
13547 0, /* reserved1 */
13548 0xFFE7, /* bios_ctrl */
13549 0xFFFF, /* ultra_able */
13550 0, /* reserved2 */
13551 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
13552 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13553 0, /* dvc_cntl */
13554 0, /* bug_fix */
13555 0, /* serial_number_word1 */
13556 0, /* serial_number_word2 */
13557 0, /* serial_number_word3 */
13558 0, /* check_sum */
13559 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13560 , /* oem_name[16] */
13561 0, /* dvc_err_code */
13562 0, /* adv_err_code */
13563 0, /* adv_err_addr */
13564 0, /* saved_dvc_err_code */
13565 0, /* saved_adv_err_code */
13566 0, /* saved_adv_err_addr */
13567 0 /* num_of_err */
1da177e4
LT
13568};
13569
78e77d8b 13570static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
27c868c2
MW
13571 0, /* cfg_lsw */
13572 0, /* cfg_msw */
13573 0, /* -disc_enable */
13574 0, /* wdtr_able */
13575 0, /* sdtr_able */
13576 0, /* start_motor */
13577 0, /* tagqng_able */
13578 0, /* bios_scan */
13579 0, /* scam_tolerant */
13580 1, /* adapter_scsi_id */
13581 1, /* bios_boot_delay */
13582 1, /* scsi_reset_delay */
13583 1, /* bios_id_lun */
13584 1, /* termination */
13585 1, /* reserved1 */
13586 0, /* bios_ctrl */
13587 0, /* ultra_able */
13588 0, /* reserved2 */
13589 1, /* max_host_qng */
13590 1, /* max_dvc_qng */
13591 0, /* dvc_cntl */
13592 0, /* bug_fix */
13593 0, /* serial_number_word1 */
13594 0, /* serial_number_word2 */
13595 0, /* serial_number_word3 */
13596 0, /* check_sum */
13597 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13598 , /* oem_name[16] */
13599 0, /* dvc_err_code */
13600 0, /* adv_err_code */
13601 0, /* adv_err_addr */
13602 0, /* saved_dvc_err_code */
13603 0, /* saved_adv_err_code */
13604 0, /* saved_adv_err_addr */
13605 0 /* num_of_err */
1da177e4
LT
13606};
13607
78e77d8b 13608static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
27c868c2
MW
13609 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13610 0x0000, /* 01 cfg_msw */
13611 0xFFFF, /* 02 disc_enable */
13612 0xFFFF, /* 03 wdtr_able */
13613 0x4444, /* 04 sdtr_speed1 */
13614 0xFFFF, /* 05 start_motor */
13615 0xFFFF, /* 06 tagqng_able */
13616 0xFFFF, /* 07 bios_scan */
13617 0, /* 08 scam_tolerant */
13618 7, /* 09 adapter_scsi_id */
13619 0, /* bios_boot_delay */
13620 3, /* 10 scsi_reset_delay */
13621 0, /* bios_id_lun */
13622 0, /* 11 termination_se */
13623 0, /* termination_lvd */
13624 0xFFE7, /* 12 bios_ctrl */
13625 0x4444, /* 13 sdtr_speed2 */
13626 0x4444, /* 14 sdtr_speed3 */
13627 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
13628 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13629 0, /* 16 dvc_cntl */
13630 0x4444, /* 17 sdtr_speed4 */
13631 0, /* 18 serial_number_word1 */
13632 0, /* 19 serial_number_word2 */
13633 0, /* 20 serial_number_word3 */
13634 0, /* 21 check_sum */
13635 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13636 , /* 22-29 oem_name[16] */
13637 0, /* 30 dvc_err_code */
13638 0, /* 31 adv_err_code */
13639 0, /* 32 adv_err_addr */
13640 0, /* 33 saved_dvc_err_code */
13641 0, /* 34 saved_adv_err_code */
13642 0, /* 35 saved_adv_err_addr */
13643 0, /* 36 reserved */
13644 0, /* 37 reserved */
13645 0, /* 38 reserved */
13646 0, /* 39 reserved */
13647 0, /* 40 reserved */
13648 0, /* 41 reserved */
13649 0, /* 42 reserved */
13650 0, /* 43 reserved */
13651 0, /* 44 reserved */
13652 0, /* 45 reserved */
13653 0, /* 46 reserved */
13654 0, /* 47 reserved */
13655 0, /* 48 reserved */
13656 0, /* 49 reserved */
13657 0, /* 50 reserved */
13658 0, /* 51 reserved */
13659 0, /* 52 reserved */
13660 0, /* 53 reserved */
13661 0, /* 54 reserved */
13662 0, /* 55 reserved */
13663 0, /* 56 cisptr_lsw */
13664 0, /* 57 cisprt_msw */
13665 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
13666 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
13667 0, /* 60 reserved */
13668 0, /* 61 reserved */
13669 0, /* 62 reserved */
13670 0 /* 63 reserved */
1da177e4
LT
13671};
13672
78e77d8b 13673static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
27c868c2
MW
13674 0, /* 00 cfg_lsw */
13675 0, /* 01 cfg_msw */
13676 0, /* 02 disc_enable */
13677 0, /* 03 wdtr_able */
13678 0, /* 04 sdtr_speed1 */
13679 0, /* 05 start_motor */
13680 0, /* 06 tagqng_able */
13681 0, /* 07 bios_scan */
13682 0, /* 08 scam_tolerant */
13683 1, /* 09 adapter_scsi_id */
13684 1, /* bios_boot_delay */
13685 1, /* 10 scsi_reset_delay */
13686 1, /* bios_id_lun */
13687 1, /* 11 termination_se */
13688 1, /* termination_lvd */
13689 0, /* 12 bios_ctrl */
13690 0, /* 13 sdtr_speed2 */
13691 0, /* 14 sdtr_speed3 */
13692 1, /* 15 max_host_qng */
13693 1, /* max_dvc_qng */
13694 0, /* 16 dvc_cntl */
13695 0, /* 17 sdtr_speed4 */
13696 0, /* 18 serial_number_word1 */
13697 0, /* 19 serial_number_word2 */
13698 0, /* 20 serial_number_word3 */
13699 0, /* 21 check_sum */
13700 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13701 , /* 22-29 oem_name[16] */
13702 0, /* 30 dvc_err_code */
13703 0, /* 31 adv_err_code */
13704 0, /* 32 adv_err_addr */
13705 0, /* 33 saved_dvc_err_code */
13706 0, /* 34 saved_adv_err_code */
13707 0, /* 35 saved_adv_err_addr */
13708 0, /* 36 reserved */
13709 0, /* 37 reserved */
13710 0, /* 38 reserved */
13711 0, /* 39 reserved */
13712 0, /* 40 reserved */
13713 0, /* 41 reserved */
13714 0, /* 42 reserved */
13715 0, /* 43 reserved */
13716 0, /* 44 reserved */
13717 0, /* 45 reserved */
13718 0, /* 46 reserved */
13719 0, /* 47 reserved */
13720 0, /* 48 reserved */
13721 0, /* 49 reserved */
13722 0, /* 50 reserved */
13723 0, /* 51 reserved */
13724 0, /* 52 reserved */
13725 0, /* 53 reserved */
13726 0, /* 54 reserved */
13727 0, /* 55 reserved */
13728 0, /* 56 cisptr_lsw */
13729 0, /* 57 cisprt_msw */
13730 0, /* 58 subsysvid */
13731 0, /* 59 subsysid */
13732 0, /* 60 reserved */
13733 0, /* 61 reserved */
13734 0, /* 62 reserved */
13735 0 /* 63 reserved */
1da177e4
LT
13736};
13737
78e77d8b 13738static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
27c868c2
MW
13739 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13740 0x0000, /* 01 cfg_msw */
13741 0xFFFF, /* 02 disc_enable */
13742 0xFFFF, /* 03 wdtr_able */
13743 0x5555, /* 04 sdtr_speed1 */
13744 0xFFFF, /* 05 start_motor */
13745 0xFFFF, /* 06 tagqng_able */
13746 0xFFFF, /* 07 bios_scan */
13747 0, /* 08 scam_tolerant */
13748 7, /* 09 adapter_scsi_id */
13749 0, /* bios_boot_delay */
13750 3, /* 10 scsi_reset_delay */
13751 0, /* bios_id_lun */
13752 0, /* 11 termination_se */
13753 0, /* termination_lvd */
13754 0xFFE7, /* 12 bios_ctrl */
13755 0x5555, /* 13 sdtr_speed2 */
13756 0x5555, /* 14 sdtr_speed3 */
13757 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
13758 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13759 0, /* 16 dvc_cntl */
13760 0x5555, /* 17 sdtr_speed4 */
13761 0, /* 18 serial_number_word1 */
13762 0, /* 19 serial_number_word2 */
13763 0, /* 20 serial_number_word3 */
13764 0, /* 21 check_sum */
13765 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13766 , /* 22-29 oem_name[16] */
13767 0, /* 30 dvc_err_code */
13768 0, /* 31 adv_err_code */
13769 0, /* 32 adv_err_addr */
13770 0, /* 33 saved_dvc_err_code */
13771 0, /* 34 saved_adv_err_code */
13772 0, /* 35 saved_adv_err_addr */
13773 0, /* 36 reserved */
13774 0, /* 37 reserved */
13775 0, /* 38 reserved */
13776 0, /* 39 reserved */
13777 0, /* 40 reserved */
13778 0, /* 41 reserved */
13779 0, /* 42 reserved */
13780 0, /* 43 reserved */
13781 0, /* 44 reserved */
13782 0, /* 45 reserved */
13783 0, /* 46 reserved */
13784 0, /* 47 reserved */
13785 0, /* 48 reserved */
13786 0, /* 49 reserved */
13787 0, /* 50 reserved */
13788 0, /* 51 reserved */
13789 0, /* 52 reserved */
13790 0, /* 53 reserved */
13791 0, /* 54 reserved */
13792 0, /* 55 reserved */
13793 0, /* 56 cisptr_lsw */
13794 0, /* 57 cisprt_msw */
13795 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
13796 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
13797 0, /* 60 reserved */
13798 0, /* 61 reserved */
13799 0, /* 62 reserved */
13800 0 /* 63 reserved */
1da177e4
LT
13801};
13802
78e77d8b 13803static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
27c868c2
MW
13804 0, /* 00 cfg_lsw */
13805 0, /* 01 cfg_msw */
13806 0, /* 02 disc_enable */
13807 0, /* 03 wdtr_able */
13808 0, /* 04 sdtr_speed1 */
13809 0, /* 05 start_motor */
13810 0, /* 06 tagqng_able */
13811 0, /* 07 bios_scan */
13812 0, /* 08 scam_tolerant */
13813 1, /* 09 adapter_scsi_id */
13814 1, /* bios_boot_delay */
13815 1, /* 10 scsi_reset_delay */
13816 1, /* bios_id_lun */
13817 1, /* 11 termination_se */
13818 1, /* termination_lvd */
13819 0, /* 12 bios_ctrl */
13820 0, /* 13 sdtr_speed2 */
13821 0, /* 14 sdtr_speed3 */
13822 1, /* 15 max_host_qng */
13823 1, /* max_dvc_qng */
13824 0, /* 16 dvc_cntl */
13825 0, /* 17 sdtr_speed4 */
13826 0, /* 18 serial_number_word1 */
13827 0, /* 19 serial_number_word2 */
13828 0, /* 20 serial_number_word3 */
13829 0, /* 21 check_sum */
13830 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13831 , /* 22-29 oem_name[16] */
13832 0, /* 30 dvc_err_code */
13833 0, /* 31 adv_err_code */
13834 0, /* 32 adv_err_addr */
13835 0, /* 33 saved_dvc_err_code */
13836 0, /* 34 saved_adv_err_code */
13837 0, /* 35 saved_adv_err_addr */
13838 0, /* 36 reserved */
13839 0, /* 37 reserved */
13840 0, /* 38 reserved */
13841 0, /* 39 reserved */
13842 0, /* 40 reserved */
13843 0, /* 41 reserved */
13844 0, /* 42 reserved */
13845 0, /* 43 reserved */
13846 0, /* 44 reserved */
13847 0, /* 45 reserved */
13848 0, /* 46 reserved */
13849 0, /* 47 reserved */
13850 0, /* 48 reserved */
13851 0, /* 49 reserved */
13852 0, /* 50 reserved */
13853 0, /* 51 reserved */
13854 0, /* 52 reserved */
13855 0, /* 53 reserved */
13856 0, /* 54 reserved */
13857 0, /* 55 reserved */
13858 0, /* 56 cisptr_lsw */
13859 0, /* 57 cisprt_msw */
13860 0, /* 58 subsysvid */
13861 0, /* 59 subsysid */
13862 0, /* 60 reserved */
13863 0, /* 61 reserved */
13864 0, /* 62 reserved */
13865 0 /* 63 reserved */
1da177e4
LT
13866};
13867
13868/*
13869 * Initialize the ADV_DVC_VAR structure.
13870 *
13871 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13872 *
13873 * For a non-fatal error return a warning code. If there are no warnings
13874 * then 0 is returned.
13875 */
78e77d8b 13876static int __devinit AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
1da177e4 13877{
27c868c2
MW
13878 ushort warn_code;
13879 AdvPortAddr iop_base;
13880 uchar pci_cmd_reg;
13881 int status;
13882
13883 warn_code = 0;
13884 asc_dvc->err_code = 0;
13885 iop_base = asc_dvc->iop_base;
13886
13887 /*
13888 * PCI Command Register
13889 *
13890 * Note: AscPCICmdRegBits_BusMastering definition (0x0007) includes
13891 * I/O Space Control, Memory Space Control and Bus Master Control bits.
13892 */
13893
13894 if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
13895 AscPCIConfigCommandRegister))
13896 & AscPCICmdRegBits_BusMastering)
13897 != AscPCICmdRegBits_BusMastering) {
13898 pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
13899
13900 DvcAdvWritePCIConfigByte(asc_dvc,
13901 AscPCIConfigCommandRegister,
13902 pci_cmd_reg);
13903
13904 if (((DvcAdvReadPCIConfigByte
13905 (asc_dvc, AscPCIConfigCommandRegister))
13906 & AscPCICmdRegBits_BusMastering)
13907 != AscPCICmdRegBits_BusMastering) {
13908 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
13909 }
13910 }
1da177e4 13911
27c868c2
MW
13912 /*
13913 * PCI Latency Timer
13914 *
13915 * If the "latency timer" register is 0x20 or above, then we don't need
13916 * to change it. Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
13917 * comes up less than 0x20).
13918 */
13919 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
13920 DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer,
13921 0x20);
13922 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) <
13923 0x20) {
13924 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
13925 }
13926 }
1da177e4 13927
27c868c2
MW
13928 /*
13929 * Save the state of the PCI Configuration Command Register
13930 * "Parity Error Response Control" Bit. If the bit is clear (0),
13931 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
13932 * DMA parity errors.
13933 */
13934 asc_dvc->cfg->control_flag = 0;
13935 if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
13936 & AscPCICmdRegBits_ParErrRespCtrl)) == 0) {
13937 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
13938 }
1da177e4 13939
27c868c2
MW
13940 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
13941 ADV_LIB_VERSION_MINOR;
13942 asc_dvc->cfg->chip_version =
13943 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
13944
13945 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
13946 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
13947 (ushort)ADV_CHIP_ID_BYTE);
13948
13949 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
13950 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
13951 (ushort)ADV_CHIP_ID_WORD);
13952
13953 /*
13954 * Reset the chip to start and allow register writes.
13955 */
13956 if (AdvFindSignature(iop_base) == 0) {
13957 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
13958 return ADV_ERROR;
13959 } else {
13960 /*
13961 * The caller must set 'chip_type' to a valid setting.
13962 */
13963 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
13964 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
13965 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
13966 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
13967 return ADV_ERROR;
13968 }
1da177e4 13969
27c868c2
MW
13970 /*
13971 * Reset Chip.
13972 */
13973 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13974 ADV_CTRL_REG_CMD_RESET);
13975 DvcSleepMilliSecond(100);
13976 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13977 ADV_CTRL_REG_CMD_WR_IO_REG);
13978
13979 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13980 if ((status =
13981 AdvInitFrom38C1600EEP(asc_dvc)) == ADV_ERROR) {
13982 return ADV_ERROR;
13983 }
13984 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13985 if ((status =
13986 AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR) {
13987 return ADV_ERROR;
13988 }
13989 } else {
13990 if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR) {
13991 return ADV_ERROR;
13992 }
13993 }
13994 warn_code |= status;
13995 }
1da177e4 13996
27c868c2 13997 return warn_code;
1da177e4
LT
13998}
13999
14000/*
14001 * Initialize the ASC-3550.
14002 *
14003 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14004 *
14005 * For a non-fatal error return a warning code. If there are no warnings
14006 * then 0 is returned.
14007 *
14008 * Needed after initialization for error recovery.
14009 */
27c868c2 14010static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
1da177e4 14011{
27c868c2
MW
14012 AdvPortAddr iop_base;
14013 ushort warn_code;
14014 ADV_DCNT sum;
14015 int begin_addr;
14016 int end_addr;
14017 ushort code_sum;
14018 int word;
14019 int j;
14020 int adv_asc3550_expanded_size;
14021 ADV_CARR_T *carrp;
14022 ADV_DCNT contig_len;
14023 ADV_SDCNT buf_size;
14024 ADV_PADDR carr_paddr;
14025 int i;
14026 ushort scsi_cfg1;
14027 uchar tid;
14028 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
14029 ushort wdtr_able = 0, sdtr_able, tagqng_able;
14030 uchar max_cmd[ADV_MAX_TID + 1];
14031
14032 /* If there is already an error, don't continue. */
14033 if (asc_dvc->err_code != 0) {
14034 return ADV_ERROR;
14035 }
1da177e4 14036
27c868c2
MW
14037 /*
14038 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
14039 */
14040 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
14041 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14042 return ADV_ERROR;
14043 }
1da177e4 14044
27c868c2
MW
14045 warn_code = 0;
14046 iop_base = asc_dvc->iop_base;
14047
14048 /*
14049 * Save the RISC memory BIOS region before writing the microcode.
14050 * The BIOS may already be loaded and using its RISC LRAM region
14051 * so its region must be saved and restored.
14052 *
14053 * Note: This code makes the assumption, which is currently true,
14054 * that a chip reset does not clear RISC LRAM.
14055 */
14056 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14057 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14058 bios_mem[i]);
14059 }
1da177e4 14060
27c868c2
MW
14061 /*
14062 * Save current per TID negotiated values.
14063 */
14064 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
14065 ushort bios_version, major, minor;
14066
14067 bios_version =
14068 bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
14069 major = (bios_version >> 12) & 0xF;
14070 minor = (bios_version >> 8) & 0xF;
14071 if (major < 3 || (major == 3 && minor == 1)) {
14072 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
14073 AdvReadWordLram(iop_base, 0x120, wdtr_able);
14074 } else {
14075 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14076 }
14077 }
14078 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14079 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14080 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14081 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14082 max_cmd[tid]);
14083 }
1da177e4 14084
27c868c2
MW
14085 /*
14086 * Load the Microcode
14087 *
14088 * Write the microcode image to RISC memory starting at address 0.
14089 */
14090 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14091 /* Assume the following compressed format of the microcode buffer:
14092 *
14093 * 254 word (508 byte) table indexed by byte code followed
14094 * by the following byte codes:
14095 *
14096 * 1-Byte Code:
14097 * 00: Emit word 0 in table.
14098 * 01: Emit word 1 in table.
14099 * .
14100 * FD: Emit word 253 in table.
14101 *
14102 * Multi-Byte Code:
14103 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14104 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14105 */
14106 word = 0;
14107 for (i = 253 * 2; i < _adv_asc3550_size; i++) {
14108 if (_adv_asc3550_buf[i] == 0xff) {
14109 for (j = 0; j < _adv_asc3550_buf[i + 1]; j++) {
14110 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14111 _adv_asc3550_buf
14112 [i +
14113 3] << 8) |
14114 _adv_asc3550_buf
14115 [i + 2]));
14116 word++;
14117 }
14118 i += 3;
14119 } else if (_adv_asc3550_buf[i] == 0xfe) {
14120 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14121 _adv_asc3550_buf[i +
14122 2]
14123 << 8) |
14124 _adv_asc3550_buf[i +
14125 1]));
14126 i += 2;
14127 word++;
14128 } else {
14129 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14130 _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) | _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
14131 word++;
14132 }
14133 }
1da177e4 14134
27c868c2
MW
14135 /*
14136 * Set 'word' for later use to clear the rest of memory and save
14137 * the expanded mcode size.
14138 */
14139 word *= 2;
14140 adv_asc3550_expanded_size = word;
14141
14142 /*
14143 * Clear the rest of ASC-3550 Internal RAM (8KB).
14144 */
14145 for (; word < ADV_3550_MEMSIZE; word += 2) {
14146 AdvWriteWordAutoIncLram(iop_base, 0);
14147 }
1da177e4 14148
27c868c2
MW
14149 /*
14150 * Verify the microcode checksum.
14151 */
14152 sum = 0;
14153 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
1da177e4 14154
27c868c2
MW
14155 for (word = 0; word < adv_asc3550_expanded_size; word += 2) {
14156 sum += AdvReadWordAutoIncLram(iop_base);
14157 }
1da177e4 14158
27c868c2
MW
14159 if (sum != _adv_asc3550_chksum) {
14160 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14161 return ADV_ERROR;
14162 }
1da177e4 14163
27c868c2
MW
14164 /*
14165 * Restore the RISC memory BIOS region.
14166 */
14167 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14168 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14169 bios_mem[i]);
14170 }
1da177e4 14171
27c868c2
MW
14172 /*
14173 * Calculate and write the microcode code checksum to the microcode
14174 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14175 */
14176 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14177 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14178 code_sum = 0;
14179 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14180 for (word = begin_addr; word < end_addr; word += 2) {
14181 code_sum += AdvReadWordAutoIncLram(iop_base);
14182 }
14183 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14184
14185 /*
14186 * Read and save microcode version and date.
14187 */
14188 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
14189 asc_dvc->cfg->mcode_date);
14190 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
14191 asc_dvc->cfg->mcode_version);
14192
14193 /*
14194 * Set the chip type to indicate the ASC3550.
14195 */
14196 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
14197
14198 /*
14199 * If the PCI Configuration Command Register "Parity Error Response
14200 * Control" Bit was clear (0), then set the microcode variable
14201 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14202 * to ignore DMA parity errors.
14203 */
14204 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
14205 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14206 word |= CONTROL_FLAG_IGNORE_PERR;
14207 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14208 }
1da177e4 14209
27c868c2
MW
14210 /*
14211 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
14212 * threshold of 128 bytes. This register is only accessible to the host.
14213 */
14214 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14215 START_CTL_EMFU | READ_CMD_MRM);
14216
14217 /*
14218 * Microcode operating variables for WDTR, SDTR, and command tag
14219 * queuing will be set in AdvInquiryHandling() based on what a
14220 * device reports it is capable of in Inquiry byte 7.
14221 *
14222 * If SCSI Bus Resets have been disabled, then directly set
14223 * SDTR and WDTR from the EEPROM configuration. This will allow
14224 * the BIOS and warm boot to work without a SCSI bus hang on
14225 * the Inquiry caused by host and target mismatched DTR values.
14226 * Without the SCSI Bus Reset, before an Inquiry a device can't
14227 * be assumed to be in Asynchronous, Narrow mode.
14228 */
14229 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
14230 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
14231 asc_dvc->wdtr_able);
14232 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
14233 asc_dvc->sdtr_able);
14234 }
1da177e4 14235
27c868c2
MW
14236 /*
14237 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
14238 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
14239 * bitmask. These values determine the maximum SDTR speed negotiated
14240 * with a device.
14241 *
14242 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14243 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14244 * without determining here whether the device supports SDTR.
14245 *
14246 * 4-bit speed SDTR speed name
14247 * =========== ===============
14248 * 0000b (0x0) SDTR disabled
14249 * 0001b (0x1) 5 Mhz
14250 * 0010b (0x2) 10 Mhz
14251 * 0011b (0x3) 20 Mhz (Ultra)
14252 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
14253 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
14254 * 0110b (0x6) Undefined
14255 * .
14256 * 1111b (0xF) Undefined
14257 */
14258 word = 0;
14259 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14260 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
14261 /* Set Ultra speed for TID 'tid'. */
14262 word |= (0x3 << (4 * (tid % 4)));
14263 } else {
14264 /* Set Fast speed for TID 'tid'. */
14265 word |= (0x2 << (4 * (tid % 4)));
14266 }
14267 if (tid == 3) { /* Check if done with sdtr_speed1. */
14268 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
14269 word = 0;
14270 } else if (tid == 7) { /* Check if done with sdtr_speed2. */
14271 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
14272 word = 0;
14273 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
14274 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
14275 word = 0;
14276 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
14277 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
14278 /* End of loop. */
14279 }
14280 }
1da177e4 14281
27c868c2
MW
14282 /*
14283 * Set microcode operating variable for the disconnect per TID bitmask.
14284 */
14285 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
14286 asc_dvc->cfg->disc_enable);
14287
14288 /*
14289 * Set SCSI_CFG0 Microcode Default Value.
14290 *
14291 * The microcode will set the SCSI_CFG0 register using this value
14292 * after it is started below.
14293 */
14294 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14295 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14296 asc_dvc->chip_scsi_id);
14297
14298 /*
14299 * Determine SCSI_CFG1 Microcode Default Value.
14300 *
14301 * The microcode will set the SCSI_CFG1 register using this value
14302 * after it is started below.
14303 */
14304
14305 /* Read current SCSI_CFG1 Register value. */
14306 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14307
14308 /*
14309 * If all three connectors are in use, return an error.
14310 */
14311 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
14312 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
14313 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
14314 return ADV_ERROR;
14315 }
1da177e4 14316
27c868c2
MW
14317 /*
14318 * If the internal narrow cable is reversed all of the SCSI_CTRL
14319 * register signals will be set. Check for and return an error if
14320 * this condition is found.
14321 */
14322 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
14323 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14324 return ADV_ERROR;
14325 }
1da177e4 14326
27c868c2
MW
14327 /*
14328 * If this is a differential board and a single-ended device
14329 * is attached to one of the connectors, return an error.
14330 */
14331 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
14332 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
14333 return ADV_ERROR;
14334 }
1da177e4 14335
27c868c2
MW
14336 /*
14337 * If automatic termination control is enabled, then set the
14338 * termination value based on a table listed in a_condor.h.
14339 *
14340 * If manual termination was specified with an EEPROM setting
14341 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
14342 * is ready to be 'ored' into SCSI_CFG1.
14343 */
14344 if (asc_dvc->cfg->termination == 0) {
14345 /*
14346 * The software always controls termination by setting TERM_CTL_SEL.
14347 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
14348 */
14349 asc_dvc->cfg->termination |= TERM_CTL_SEL;
14350
14351 switch (scsi_cfg1 & CABLE_DETECT) {
14352 /* TERM_CTL_H: on, TERM_CTL_L: on */
14353 case 0x3:
14354 case 0x7:
14355 case 0xB:
14356 case 0xD:
14357 case 0xE:
14358 case 0xF:
14359 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
14360 break;
14361
14362 /* TERM_CTL_H: on, TERM_CTL_L: off */
14363 case 0x1:
14364 case 0x5:
14365 case 0x9:
14366 case 0xA:
14367 case 0xC:
14368 asc_dvc->cfg->termination |= TERM_CTL_H;
14369 break;
14370
14371 /* TERM_CTL_H: off, TERM_CTL_L: off */
14372 case 0x2:
14373 case 0x6:
14374 break;
14375 }
14376 }
1da177e4 14377
27c868c2
MW
14378 /*
14379 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
14380 */
14381 scsi_cfg1 &= ~TERM_CTL;
14382
14383 /*
14384 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
14385 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
14386 * referenced, because the hardware internally inverts
14387 * the Termination High and Low bits if TERM_POL is set.
14388 */
14389 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
14390
14391 /*
14392 * Set SCSI_CFG1 Microcode Default Value
14393 *
14394 * Set filter value and possibly modified termination control
14395 * bits in the Microcode SCSI_CFG1 Register Value.
14396 *
14397 * The microcode will set the SCSI_CFG1 register using this value
14398 * after it is started below.
14399 */
14400 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
14401 FLTR_DISABLE | scsi_cfg1);
14402
14403 /*
14404 * Set MEM_CFG Microcode Default Value
14405 *
14406 * The microcode will set the MEM_CFG register using this value
14407 * after it is started below.
14408 *
14409 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
14410 * are defined.
14411 *
14412 * ASC-3550 has 8KB internal memory.
14413 */
14414 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
14415 BIOS_EN | RAM_SZ_8KB);
14416
14417 /*
14418 * Set SEL_MASK Microcode Default Value
14419 *
14420 * The microcode will set the SEL_MASK register using this value
14421 * after it is started below.
14422 */
14423 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
14424 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
14425
14426 /*
14427 * Build carrier freelist.
14428 *
14429 * Driver must have already allocated memory and set 'carrier_buf'.
14430 */
14431 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
14432
14433 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
14434 asc_dvc->carr_freelist = NULL;
14435 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
14436 buf_size = ADV_CARRIER_BUFSIZE;
14437 } else {
14438 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
14439 }
1da177e4 14440
27c868c2
MW
14441 do {
14442 /*
14443 * Get physical address of the carrier 'carrp'.
14444 */
14445 contig_len = sizeof(ADV_CARR_T);
14446 carr_paddr =
14447 cpu_to_le32(DvcGetPhyAddr
14448 (asc_dvc, NULL, (uchar *)carrp,
14449 (ADV_SDCNT *)&contig_len,
14450 ADV_IS_CARRIER_FLAG));
1da177e4 14451
27c868c2 14452 buf_size -= sizeof(ADV_CARR_T);
1da177e4 14453
27c868c2
MW
14454 /*
14455 * If the current carrier is not physically contiguous, then
14456 * maybe there was a page crossing. Try the next carrier aligned
14457 * start address.
14458 */
14459 if (contig_len < sizeof(ADV_CARR_T)) {
14460 carrp++;
14461 continue;
14462 }
14463
14464 carrp->carr_pa = carr_paddr;
14465 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
1da177e4 14466
27c868c2
MW
14467 /*
14468 * Insert the carrier at the beginning of the freelist.
14469 */
14470 carrp->next_vpa =
14471 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
14472 asc_dvc->carr_freelist = carrp;
1da177e4 14473
27c868c2
MW
14474 carrp++;
14475 }
14476 while (buf_size > 0);
1da177e4 14477
27c868c2
MW
14478 /*
14479 * Set-up the Host->RISC Initiator Command Queue (ICQ).
14480 */
1da177e4 14481
27c868c2
MW
14482 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
14483 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14484 return ADV_ERROR;
14485 }
14486 asc_dvc->carr_freelist = (ADV_CARR_T *)
14487 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
14488
14489 /*
14490 * The first command issued will be placed in the stopper carrier.
14491 */
14492 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14493
14494 /*
14495 * Set RISC ICQ physical address start value.
14496 */
14497 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
14498
14499 /*
14500 * Set-up the RISC->Host Initiator Response Queue (IRQ).
14501 */
14502 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
14503 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14504 return ADV_ERROR;
14505 }
14506 asc_dvc->carr_freelist = (ADV_CARR_T *)
14507 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
14508
14509 /*
14510 * The first command completed by the RISC will be placed in
14511 * the stopper.
14512 *
14513 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
14514 * completed the RISC will set the ASC_RQ_STOPPER bit.
14515 */
14516 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14517
14518 /*
14519 * Set RISC IRQ physical address start value.
14520 */
14521 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
14522 asc_dvc->carr_pending_cnt = 0;
14523
14524 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
14525 (ADV_INTR_ENABLE_HOST_INTR |
14526 ADV_INTR_ENABLE_GLOBAL_INTR));
14527
14528 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
14529 AdvWriteWordRegister(iop_base, IOPW_PC, word);
14530
14531 /* finally, finally, gentlemen, start your engine */
14532 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
14533
14534 /*
14535 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
14536 * Resets should be performed. The RISC has to be running
14537 * to issue a SCSI Bus Reset.
14538 */
14539 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
14540 /*
14541 * If the BIOS Signature is present in memory, restore the
14542 * BIOS Handshake Configuration Table and do not perform
14543 * a SCSI Bus Reset.
14544 */
14545 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
14546 0x55AA) {
14547 /*
14548 * Restore per TID negotiated values.
14549 */
14550 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14551 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14552 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
14553 tagqng_able);
14554 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14555 AdvWriteByteLram(iop_base,
14556 ASC_MC_NUMBER_OF_MAX_CMD + tid,
14557 max_cmd[tid]);
14558 }
14559 } else {
14560 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
14561 warn_code = ASC_WARN_BUSRESET_ERROR;
14562 }
14563 }
14564 }
1da177e4 14565
27c868c2
MW
14566 return warn_code;
14567}
1da177e4 14568
27c868c2
MW
14569/*
14570 * Initialize the ASC-38C0800.
14571 *
14572 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14573 *
14574 * For a non-fatal error return a warning code. If there are no warnings
14575 * then 0 is returned.
14576 *
14577 * Needed after initialization for error recovery.
14578 */
14579static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
14580{
14581 AdvPortAddr iop_base;
14582 ushort warn_code;
14583 ADV_DCNT sum;
14584 int begin_addr;
14585 int end_addr;
14586 ushort code_sum;
14587 int word;
14588 int j;
14589 int adv_asc38C0800_expanded_size;
14590 ADV_CARR_T *carrp;
14591 ADV_DCNT contig_len;
14592 ADV_SDCNT buf_size;
14593 ADV_PADDR carr_paddr;
14594 int i;
14595 ushort scsi_cfg1;
14596 uchar byte;
14597 uchar tid;
14598 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
14599 ushort wdtr_able, sdtr_able, tagqng_able;
14600 uchar max_cmd[ADV_MAX_TID + 1];
14601
14602 /* If there is already an error, don't continue. */
14603 if (asc_dvc->err_code != 0) {
14604 return ADV_ERROR;
14605 }
1da177e4 14606
27c868c2
MW
14607 /*
14608 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
14609 */
14610 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
14611 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
14612 return ADV_ERROR;
14613 }
1da177e4 14614
27c868c2
MW
14615 warn_code = 0;
14616 iop_base = asc_dvc->iop_base;
14617
14618 /*
14619 * Save the RISC memory BIOS region before writing the microcode.
14620 * The BIOS may already be loaded and using its RISC LRAM region
14621 * so its region must be saved and restored.
14622 *
14623 * Note: This code makes the assumption, which is currently true,
14624 * that a chip reset does not clear RISC LRAM.
14625 */
14626 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14627 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14628 bios_mem[i]);
14629 }
1da177e4 14630
27c868c2
MW
14631 /*
14632 * Save current per TID negotiated values.
14633 */
14634 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14635 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14636 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14637 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14638 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14639 max_cmd[tid]);
14640 }
1da177e4 14641
27c868c2
MW
14642 /*
14643 * RAM BIST (RAM Built-In Self Test)
14644 *
14645 * Address : I/O base + offset 0x38h register (byte).
14646 * Function: Bit 7-6(RW) : RAM mode
14647 * Normal Mode : 0x00
14648 * Pre-test Mode : 0x40
14649 * RAM Test Mode : 0x80
14650 * Bit 5 : unused
14651 * Bit 4(RO) : Done bit
14652 * Bit 3-0(RO) : Status
14653 * Host Error : 0x08
14654 * Int_RAM Error : 0x04
14655 * RISC Error : 0x02
14656 * SCSI Error : 0x01
14657 * No Error : 0x00
14658 *
14659 * Note: RAM BIST code should be put right here, before loading the
14660 * microcode and after saving the RISC memory BIOS region.
14661 */
14662
14663 /*
14664 * LRAM Pre-test
14665 *
14666 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
14667 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
14668 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
14669 * to NORMAL_MODE, return an error too.
14670 */
14671 for (i = 0; i < 2; i++) {
14672 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
14673 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14674 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14675 if ((byte & RAM_TEST_DONE) == 0
14676 || (byte & 0x0F) != PRE_TEST_VALUE) {
14677 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14678 return ADV_ERROR;
14679 }
14680
14681 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14682 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14683 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
14684 != NORMAL_VALUE) {
14685 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14686 return ADV_ERROR;
14687 }
14688 }
1da177e4 14689
27c868c2
MW
14690 /*
14691 * LRAM Test - It takes about 1.5 ms to run through the test.
14692 *
14693 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
14694 * If Done bit not set or Status not 0, save register byte, set the
14695 * err_code, and return an error.
14696 */
14697 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
14698 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
14699
14700 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14701 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
14702 /* Get here if Done bit not set or Status not 0. */
14703 asc_dvc->bist_err_code = byte; /* for BIOS display message */
14704 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
14705 return ADV_ERROR;
14706 }
1da177e4 14707
27c868c2
MW
14708 /* We need to reset back to normal mode after LRAM test passes. */
14709 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14710
14711 /*
14712 * Load the Microcode
14713 *
14714 * Write the microcode image to RISC memory starting at address 0.
14715 *
14716 */
14717 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14718
14719 /* Assume the following compressed format of the microcode buffer:
14720 *
14721 * 254 word (508 byte) table indexed by byte code followed
14722 * by the following byte codes:
14723 *
14724 * 1-Byte Code:
14725 * 00: Emit word 0 in table.
14726 * 01: Emit word 1 in table.
14727 * .
14728 * FD: Emit word 253 in table.
14729 *
14730 * Multi-Byte Code:
14731 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14732 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14733 */
14734 word = 0;
14735 for (i = 253 * 2; i < _adv_asc38C0800_size; i++) {
14736 if (_adv_asc38C0800_buf[i] == 0xff) {
14737 for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++) {
14738 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14739 _adv_asc38C0800_buf
14740 [i +
14741 3] << 8) |
14742 _adv_asc38C0800_buf
14743 [i + 2]));
14744 word++;
14745 }
14746 i += 3;
14747 } else if (_adv_asc38C0800_buf[i] == 0xfe) {
14748 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14749 _adv_asc38C0800_buf
14750 [i +
14751 2] << 8) |
14752 _adv_asc38C0800_buf[i
14753 +
14754 1]));
14755 i += 2;
14756 word++;
14757 } else {
14758 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14759 _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) | _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
14760 word++;
14761 }
14762 }
1da177e4 14763
27c868c2
MW
14764 /*
14765 * Set 'word' for later use to clear the rest of memory and save
14766 * the expanded mcode size.
14767 */
14768 word *= 2;
14769 adv_asc38C0800_expanded_size = word;
14770
14771 /*
14772 * Clear the rest of ASC-38C0800 Internal RAM (16KB).
14773 */
14774 for (; word < ADV_38C0800_MEMSIZE; word += 2) {
14775 AdvWriteWordAutoIncLram(iop_base, 0);
14776 }
1da177e4 14777
27c868c2
MW
14778 /*
14779 * Verify the microcode checksum.
14780 */
14781 sum = 0;
14782 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
1da177e4 14783
27c868c2
MW
14784 for (word = 0; word < adv_asc38C0800_expanded_size; word += 2) {
14785 sum += AdvReadWordAutoIncLram(iop_base);
14786 }
14787 ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
1da177e4 14788
27c868c2
MW
14789 ASC_DBG2(1,
14790 "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
14791 (ulong)sum, (ulong)_adv_asc38C0800_chksum);
1da177e4 14792
27c868c2
MW
14793 if (sum != _adv_asc38C0800_chksum) {
14794 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14795 return ADV_ERROR;
14796 }
1da177e4 14797
27c868c2
MW
14798 /*
14799 * Restore the RISC memory BIOS region.
14800 */
14801 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14802 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14803 bios_mem[i]);
14804 }
1da177e4 14805
27c868c2
MW
14806 /*
14807 * Calculate and write the microcode code checksum to the microcode
14808 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14809 */
14810 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14811 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14812 code_sum = 0;
14813 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14814 for (word = begin_addr; word < end_addr; word += 2) {
14815 code_sum += AdvReadWordAutoIncLram(iop_base);
14816 }
14817 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14818
14819 /*
14820 * Read microcode version and date.
14821 */
14822 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
14823 asc_dvc->cfg->mcode_date);
14824 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
14825 asc_dvc->cfg->mcode_version);
14826
14827 /*
14828 * Set the chip type to indicate the ASC38C0800.
14829 */
14830 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
14831
14832 /*
14833 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
14834 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
14835 * cable detection and then we are able to read C_DET[3:0].
14836 *
14837 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
14838 * Microcode Default Value' section below.
14839 */
14840 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14841 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
14842 scsi_cfg1 | DIS_TERM_DRV);
14843
14844 /*
14845 * If the PCI Configuration Command Register "Parity Error Response
14846 * Control" Bit was clear (0), then set the microcode variable
14847 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14848 * to ignore DMA parity errors.
14849 */
14850 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
14851 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14852 word |= CONTROL_FLAG_IGNORE_PERR;
14853 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14854 }
1da177e4 14855
27c868c2
MW
14856 /*
14857 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
14858 * bits for the default FIFO threshold.
14859 *
14860 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
14861 *
14862 * For DMA Errata #4 set the BC_THRESH_ENB bit.
14863 */
14864 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14865 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
14866 READ_CMD_MRM);
14867
14868 /*
14869 * Microcode operating variables for WDTR, SDTR, and command tag
14870 * queuing will be set in AdvInquiryHandling() based on what a
14871 * device reports it is capable of in Inquiry byte 7.
14872 *
14873 * If SCSI Bus Resets have been disabled, then directly set
14874 * SDTR and WDTR from the EEPROM configuration. This will allow
14875 * the BIOS and warm boot to work without a SCSI bus hang on
14876 * the Inquiry caused by host and target mismatched DTR values.
14877 * Without the SCSI Bus Reset, before an Inquiry a device can't
14878 * be assumed to be in Asynchronous, Narrow mode.
14879 */
14880 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
14881 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
14882 asc_dvc->wdtr_able);
14883 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
14884 asc_dvc->sdtr_able);
14885 }
1da177e4 14886
27c868c2
MW
14887 /*
14888 * Set microcode operating variables for DISC and SDTR_SPEED1,
14889 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
14890 * configuration values.
14891 *
14892 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14893 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14894 * without determining here whether the device supports SDTR.
14895 */
14896 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
14897 asc_dvc->cfg->disc_enable);
14898 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
14899 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
14900 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
14901 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
14902
14903 /*
14904 * Set SCSI_CFG0 Microcode Default Value.
14905 *
14906 * The microcode will set the SCSI_CFG0 register using this value
14907 * after it is started below.
14908 */
14909 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14910 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14911 asc_dvc->chip_scsi_id);
14912
14913 /*
14914 * Determine SCSI_CFG1 Microcode Default Value.
14915 *
14916 * The microcode will set the SCSI_CFG1 register using this value
14917 * after it is started below.
14918 */
14919
14920 /* Read current SCSI_CFG1 Register value. */
14921 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14922
14923 /*
14924 * If the internal narrow cable is reversed all of the SCSI_CTRL
14925 * register signals will be set. Check for and return an error if
14926 * this condition is found.
14927 */
14928 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
14929 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14930 return ADV_ERROR;
14931 }
1da177e4 14932
27c868c2
MW
14933 /*
14934 * All kind of combinations of devices attached to one of four connectors
14935 * are acceptable except HVD device attached. For example, LVD device can
14936 * be attached to SE connector while SE device attached to LVD connector.
14937 * If LVD device attached to SE connector, it only runs up to Ultra speed.
14938 *
14939 * If an HVD device is attached to one of LVD connectors, return an error.
14940 * However, there is no way to detect HVD device attached to SE connectors.
14941 */
14942 if (scsi_cfg1 & HVD) {
14943 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
14944 return ADV_ERROR;
14945 }
1da177e4 14946
27c868c2
MW
14947 /*
14948 * If either SE or LVD automatic termination control is enabled, then
14949 * set the termination value based on a table listed in a_condor.h.
14950 *
14951 * If manual termination was specified with an EEPROM setting then
14952 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
14953 * be 'ored' into SCSI_CFG1.
14954 */
14955 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
14956 /* SE automatic termination control is enabled. */
14957 switch (scsi_cfg1 & C_DET_SE) {
14958 /* TERM_SE_HI: on, TERM_SE_LO: on */
14959 case 0x1:
14960 case 0x2:
14961 case 0x3:
14962 asc_dvc->cfg->termination |= TERM_SE;
14963 break;
14964
14965 /* TERM_SE_HI: on, TERM_SE_LO: off */
14966 case 0x0:
14967 asc_dvc->cfg->termination |= TERM_SE_HI;
14968 break;
14969 }
14970 }
14971
14972 if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
14973 /* LVD automatic termination control is enabled. */
14974 switch (scsi_cfg1 & C_DET_LVD) {
14975 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
14976 case 0x4:
14977 case 0x8:
14978 case 0xC:
14979 asc_dvc->cfg->termination |= TERM_LVD;
14980 break;
14981
14982 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
14983 case 0x0:
14984 break;
14985 }
14986 }
14987
14988 /*
14989 * Clear any set TERM_SE and TERM_LVD bits.
14990 */
14991 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
14992
14993 /*
14994 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
14995 */
14996 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
14997
14998 /*
14999 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
15000 * and set possibly modified termination control bits in the Microcode
15001 * SCSI_CFG1 Register Value.
15002 */
15003 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
15004
15005 /*
15006 * Set SCSI_CFG1 Microcode Default Value
15007 *
15008 * Set possibly modified termination control and reset DIS_TERM_DRV
15009 * bits in the Microcode SCSI_CFG1 Register Value.
15010 *
15011 * The microcode will set the SCSI_CFG1 register using this value
15012 * after it is started below.
15013 */
15014 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15015
15016 /*
15017 * Set MEM_CFG Microcode Default Value
15018 *
15019 * The microcode will set the MEM_CFG register using this value
15020 * after it is started below.
15021 *
15022 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15023 * are defined.
15024 *
15025 * ASC-38C0800 has 16KB internal memory.
15026 */
15027 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15028 BIOS_EN | RAM_SZ_16KB);
15029
15030 /*
15031 * Set SEL_MASK Microcode Default Value
15032 *
15033 * The microcode will set the SEL_MASK register using this value
15034 * after it is started below.
15035 */
15036 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15037 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15038
15039 /*
15040 * Build the carrier freelist.
15041 *
15042 * Driver must have already allocated memory and set 'carrier_buf'.
15043 */
15044 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15045
15046 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15047 asc_dvc->carr_freelist = NULL;
15048 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
15049 buf_size = ADV_CARRIER_BUFSIZE;
15050 } else {
15051 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15052 }
15053
15054 do {
15055 /*
15056 * Get physical address for the carrier 'carrp'.
15057 */
15058 contig_len = sizeof(ADV_CARR_T);
15059 carr_paddr =
15060 cpu_to_le32(DvcGetPhyAddr
15061 (asc_dvc, NULL, (uchar *)carrp,
15062 (ADV_SDCNT *)&contig_len,
15063 ADV_IS_CARRIER_FLAG));
1da177e4 15064
27c868c2
MW
15065 buf_size -= sizeof(ADV_CARR_T);
15066
15067 /*
15068 * If the current carrier is not physically contiguous, then
15069 * maybe there was a page crossing. Try the next carrier aligned
15070 * start address.
15071 */
15072 if (contig_len < sizeof(ADV_CARR_T)) {
15073 carrp++;
15074 continue;
15075 }
15076
15077 carrp->carr_pa = carr_paddr;
15078 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15079
15080 /*
15081 * Insert the carrier at the beginning of the freelist.
15082 */
15083 carrp->next_vpa =
15084 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15085 asc_dvc->carr_freelist = carrp;
15086
15087 carrp++;
15088 }
15089 while (buf_size > 0);
15090
15091 /*
15092 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15093 */
15094
15095 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
15096 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15097 return ADV_ERROR;
15098 }
15099 asc_dvc->carr_freelist = (ADV_CARR_T *)
15100 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15101
15102 /*
15103 * The first command issued will be placed in the stopper carrier.
15104 */
15105 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15106
15107 /*
15108 * Set RISC ICQ physical address start value.
15109 * carr_pa is LE, must be native before write
15110 */
15111 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15112
15113 /*
15114 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15115 */
15116 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
15117 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15118 return ADV_ERROR;
15119 }
15120 asc_dvc->carr_freelist = (ADV_CARR_T *)
15121 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15122
15123 /*
15124 * The first command completed by the RISC will be placed in
15125 * the stopper.
15126 *
15127 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15128 * completed the RISC will set the ASC_RQ_STOPPER bit.
15129 */
15130 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15131
15132 /*
15133 * Set RISC IRQ physical address start value.
15134 *
15135 * carr_pa is LE, must be native before write *
15136 */
15137 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15138 asc_dvc->carr_pending_cnt = 0;
15139
15140 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15141 (ADV_INTR_ENABLE_HOST_INTR |
15142 ADV_INTR_ENABLE_GLOBAL_INTR));
15143
15144 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15145 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15146
15147 /* finally, finally, gentlemen, start your engine */
15148 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15149
15150 /*
15151 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15152 * Resets should be performed. The RISC has to be running
15153 * to issue a SCSI Bus Reset.
15154 */
15155 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
15156 /*
15157 * If the BIOS Signature is present in memory, restore the
15158 * BIOS Handshake Configuration Table and do not perform
15159 * a SCSI Bus Reset.
15160 */
15161 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
15162 0x55AA) {
15163 /*
15164 * Restore per TID negotiated values.
15165 */
15166 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15167 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15168 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
15169 tagqng_able);
15170 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
15171 AdvWriteByteLram(iop_base,
15172 ASC_MC_NUMBER_OF_MAX_CMD + tid,
15173 max_cmd[tid]);
15174 }
15175 } else {
15176 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
15177 warn_code = ASC_WARN_BUSRESET_ERROR;
15178 }
15179 }
15180 }
15181
15182 return warn_code;
1da177e4
LT
15183}
15184
15185/*
27c868c2 15186 * Initialize the ASC-38C1600.
1da177e4 15187 *
27c868c2 15188 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
1da177e4
LT
15189 *
15190 * For a non-fatal error return a warning code. If there are no warnings
15191 * then 0 is returned.
15192 *
15193 * Needed after initialization for error recovery.
15194 */
27c868c2 15195static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
1da177e4 15196{
27c868c2
MW
15197 AdvPortAddr iop_base;
15198 ushort warn_code;
15199 ADV_DCNT sum;
15200 int begin_addr;
15201 int end_addr;
15202 ushort code_sum;
15203 long word;
15204 int j;
15205 int adv_asc38C1600_expanded_size;
15206 ADV_CARR_T *carrp;
15207 ADV_DCNT contig_len;
15208 ADV_SDCNT buf_size;
15209 ADV_PADDR carr_paddr;
15210 int i;
15211 ushort scsi_cfg1;
15212 uchar byte;
15213 uchar tid;
15214 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
15215 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
15216 uchar max_cmd[ASC_MAX_TID + 1];
15217
15218 /* If there is already an error, don't continue. */
15219 if (asc_dvc->err_code != 0) {
15220 return ADV_ERROR;
15221 }
1da177e4 15222
27c868c2
MW
15223 /*
15224 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
15225 */
15226 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
15227 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
15228 return ADV_ERROR;
15229 }
1da177e4 15230
27c868c2
MW
15231 warn_code = 0;
15232 iop_base = asc_dvc->iop_base;
15233
15234 /*
15235 * Save the RISC memory BIOS region before writing the microcode.
15236 * The BIOS may already be loaded and using its RISC LRAM region
15237 * so its region must be saved and restored.
15238 *
15239 * Note: This code makes the assumption, which is currently true,
15240 * that a chip reset does not clear RISC LRAM.
15241 */
15242 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15243 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15244 bios_mem[i]);
15245 }
1da177e4 15246
27c868c2
MW
15247 /*
15248 * Save current per TID negotiated values.
15249 */
15250 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15251 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15252 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15253 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15254 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15255 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15256 max_cmd[tid]);
15257 }
1da177e4 15258
27c868c2
MW
15259 /*
15260 * RAM BIST (Built-In Self Test)
15261 *
15262 * Address : I/O base + offset 0x38h register (byte).
15263 * Function: Bit 7-6(RW) : RAM mode
15264 * Normal Mode : 0x00
15265 * Pre-test Mode : 0x40
15266 * RAM Test Mode : 0x80
15267 * Bit 5 : unused
15268 * Bit 4(RO) : Done bit
15269 * Bit 3-0(RO) : Status
15270 * Host Error : 0x08
15271 * Int_RAM Error : 0x04
15272 * RISC Error : 0x02
15273 * SCSI Error : 0x01
15274 * No Error : 0x00
15275 *
15276 * Note: RAM BIST code should be put right here, before loading the
15277 * microcode and after saving the RISC memory BIOS region.
15278 */
15279
15280 /*
15281 * LRAM Pre-test
15282 *
15283 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15284 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15285 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15286 * to NORMAL_MODE, return an error too.
15287 */
15288 for (i = 0; i < 2; i++) {
15289 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15290 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15291 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15292 if ((byte & RAM_TEST_DONE) == 0
15293 || (byte & 0x0F) != PRE_TEST_VALUE) {
15294 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15295 return ADV_ERROR;
15296 }
15297
15298 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15299 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15300 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15301 != NORMAL_VALUE) {
15302 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15303 return ADV_ERROR;
15304 }
15305 }
1da177e4 15306
27c868c2
MW
15307 /*
15308 * LRAM Test - It takes about 1.5 ms to run through the test.
15309 *
15310 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15311 * If Done bit not set or Status not 0, save register byte, set the
15312 * err_code, and return an error.
15313 */
15314 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15315 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
15316
15317 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15318 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
15319 /* Get here if Done bit not set or Status not 0. */
15320 asc_dvc->bist_err_code = byte; /* for BIOS display message */
15321 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15322 return ADV_ERROR;
15323 }
1da177e4 15324
27c868c2
MW
15325 /* We need to reset back to normal mode after LRAM test passes. */
15326 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15327
15328 /*
15329 * Load the Microcode
15330 *
15331 * Write the microcode image to RISC memory starting at address 0.
15332 *
15333 */
15334 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15335
15336 /*
15337 * Assume the following compressed format of the microcode buffer:
15338 *
15339 * 254 word (508 byte) table indexed by byte code followed
15340 * by the following byte codes:
15341 *
15342 * 1-Byte Code:
15343 * 00: Emit word 0 in table.
15344 * 01: Emit word 1 in table.
15345 * .
15346 * FD: Emit word 253 in table.
15347 *
15348 * Multi-Byte Code:
15349 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15350 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15351 */
15352 word = 0;
15353 for (i = 253 * 2; i < _adv_asc38C1600_size; i++) {
15354 if (_adv_asc38C1600_buf[i] == 0xff) {
15355 for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++) {
15356 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15357 _adv_asc38C1600_buf
15358 [i +
15359 3] << 8) |
15360 _adv_asc38C1600_buf
15361 [i + 2]));
15362 word++;
15363 }
15364 i += 3;
15365 } else if (_adv_asc38C1600_buf[i] == 0xfe) {
15366 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15367 _adv_asc38C1600_buf
15368 [i +
15369 2] << 8) |
15370 _adv_asc38C1600_buf[i
15371 +
15372 1]));
15373 i += 2;
15374 word++;
15375 } else {
15376 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15377 _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) | _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
15378 word++;
15379 }
15380 }
1da177e4 15381
27c868c2
MW
15382 /*
15383 * Set 'word' for later use to clear the rest of memory and save
15384 * the expanded mcode size.
15385 */
15386 word *= 2;
15387 adv_asc38C1600_expanded_size = word;
15388
15389 /*
15390 * Clear the rest of ASC-38C1600 Internal RAM (32KB).
15391 */
15392 for (; word < ADV_38C1600_MEMSIZE; word += 2) {
15393 AdvWriteWordAutoIncLram(iop_base, 0);
15394 }
1da177e4 15395
27c868c2
MW
15396 /*
15397 * Verify the microcode checksum.
15398 */
15399 sum = 0;
15400 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
1da177e4 15401
27c868c2
MW
15402 for (word = 0; word < adv_asc38C1600_expanded_size; word += 2) {
15403 sum += AdvReadWordAutoIncLram(iop_base);
15404 }
1da177e4 15405
27c868c2
MW
15406 if (sum != _adv_asc38C1600_chksum) {
15407 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15408 return ADV_ERROR;
15409 }
1da177e4 15410
27c868c2
MW
15411 /*
15412 * Restore the RISC memory BIOS region.
15413 */
15414 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15415 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15416 bios_mem[i]);
15417 }
1da177e4 15418
27c868c2
MW
15419 /*
15420 * Calculate and write the microcode code checksum to the microcode
15421 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15422 */
15423 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15424 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15425 code_sum = 0;
15426 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15427 for (word = begin_addr; word < end_addr; word += 2) {
15428 code_sum += AdvReadWordAutoIncLram(iop_base);
15429 }
15430 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15431
15432 /*
15433 * Read microcode version and date.
15434 */
15435 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
15436 asc_dvc->cfg->mcode_date);
15437 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
15438 asc_dvc->cfg->mcode_version);
15439
15440 /*
15441 * Set the chip type to indicate the ASC38C1600.
15442 */
15443 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
15444
15445 /*
15446 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15447 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15448 * cable detection and then we are able to read C_DET[3:0].
15449 *
15450 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15451 * Microcode Default Value' section below.
15452 */
15453 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15454 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
15455 scsi_cfg1 | DIS_TERM_DRV);
15456
15457 /*
15458 * If the PCI Configuration Command Register "Parity Error Response
15459 * Control" Bit was clear (0), then set the microcode variable
15460 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15461 * to ignore DMA parity errors.
15462 */
15463 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
15464 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15465 word |= CONTROL_FLAG_IGNORE_PERR;
15466 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15467 }
1da177e4 15468
27c868c2
MW
15469 /*
15470 * If the BIOS control flag AIPP (Asynchronous Information
15471 * Phase Protection) disable bit is not set, then set the firmware
15472 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
15473 * AIPP checking and encoding.
15474 */
15475 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
15476 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15477 word |= CONTROL_FLAG_ENABLE_AIPP;
15478 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15479 }
1da177e4 15480
27c868c2
MW
15481 /*
15482 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
15483 * and START_CTL_TH [3:2].
15484 */
15485 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15486 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
15487
15488 /*
15489 * Microcode operating variables for WDTR, SDTR, and command tag
15490 * queuing will be set in AdvInquiryHandling() based on what a
15491 * device reports it is capable of in Inquiry byte 7.
15492 *
15493 * If SCSI Bus Resets have been disabled, then directly set
15494 * SDTR and WDTR from the EEPROM configuration. This will allow
15495 * the BIOS and warm boot to work without a SCSI bus hang on
15496 * the Inquiry caused by host and target mismatched DTR values.
15497 * Without the SCSI Bus Reset, before an Inquiry a device can't
15498 * be assumed to be in Asynchronous, Narrow mode.
15499 */
15500 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
15501 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
15502 asc_dvc->wdtr_able);
15503 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
15504 asc_dvc->sdtr_able);
15505 }
1da177e4 15506
27c868c2
MW
15507 /*
15508 * Set microcode operating variables for DISC and SDTR_SPEED1,
15509 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15510 * configuration values.
15511 *
15512 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15513 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15514 * without determining here whether the device supports SDTR.
15515 */
15516 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
15517 asc_dvc->cfg->disc_enable);
15518 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15519 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15520 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15521 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15522
15523 /*
15524 * Set SCSI_CFG0 Microcode Default Value.
15525 *
15526 * The microcode will set the SCSI_CFG0 register using this value
15527 * after it is started below.
15528 */
15529 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15530 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15531 asc_dvc->chip_scsi_id);
15532
15533 /*
15534 * Calculate SCSI_CFG1 Microcode Default Value.
15535 *
15536 * The microcode will set the SCSI_CFG1 register using this value
15537 * after it is started below.
15538 *
15539 * Each ASC-38C1600 function has only two cable detect bits.
15540 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
15541 */
15542 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15543
15544 /*
15545 * If the cable is reversed all of the SCSI_CTRL register signals
15546 * will be set. Check for and return an error if this condition is
15547 * found.
15548 */
15549 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
15550 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15551 return ADV_ERROR;
15552 }
1da177e4 15553
27c868c2
MW
15554 /*
15555 * Each ASC-38C1600 function has two connectors. Only an HVD device
15556 * can not be connected to either connector. An LVD device or SE device
15557 * may be connected to either connecor. If an SE device is connected,
15558 * then at most Ultra speed (20 Mhz) can be used on both connectors.
15559 *
15560 * If an HVD device is attached, return an error.
15561 */
15562 if (scsi_cfg1 & HVD) {
15563 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15564 return ADV_ERROR;
15565 }
1da177e4 15566
27c868c2
MW
15567 /*
15568 * Each function in the ASC-38C1600 uses only the SE cable detect and
15569 * termination because there are two connectors for each function. Each
15570 * function may use either LVD or SE mode. Corresponding the SE automatic
15571 * termination control EEPROM bits are used for each function. Each
15572 * function has its own EEPROM. If SE automatic control is enabled for
15573 * the function, then set the termination value based on a table listed
15574 * in a_condor.h.
15575 *
15576 * If manual termination is specified in the EEPROM for the function,
15577 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
15578 * ready to be 'ored' into SCSI_CFG1.
15579 */
15580 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
15581 /* SE automatic termination control is enabled. */
15582 switch (scsi_cfg1 & C_DET_SE) {
15583 /* TERM_SE_HI: on, TERM_SE_LO: on */
15584 case 0x1:
15585 case 0x2:
15586 case 0x3:
15587 asc_dvc->cfg->termination |= TERM_SE;
15588 break;
15589
15590 case 0x0:
15591 if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0) {
15592 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
15593 } else {
15594 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
15595 asc_dvc->cfg->termination |= TERM_SE_HI;
15596 }
15597 break;
15598 }
15599 }
1da177e4 15600
27c868c2
MW
15601 /*
15602 * Clear any set TERM_SE bits.
15603 */
15604 scsi_cfg1 &= ~TERM_SE;
15605
15606 /*
15607 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
15608 */
15609 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
15610
15611 /*
15612 * Clear Big Endian and Terminator Polarity bits and set possibly
15613 * modified termination control bits in the Microcode SCSI_CFG1
15614 * Register Value.
15615 *
15616 * Big Endian bit is not used even on big endian machines.
15617 */
15618 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
15619
15620 /*
15621 * Set SCSI_CFG1 Microcode Default Value
15622 *
15623 * Set possibly modified termination control bits in the Microcode
15624 * SCSI_CFG1 Register Value.
15625 *
15626 * The microcode will set the SCSI_CFG1 register using this value
15627 * after it is started below.
15628 */
15629 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15630
15631 /*
15632 * Set MEM_CFG Microcode Default Value
15633 *
15634 * The microcode will set the MEM_CFG register using this value
15635 * after it is started below.
15636 *
15637 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15638 * are defined.
15639 *
15640 * ASC-38C1600 has 32KB internal memory.
15641 *
15642 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
15643 * out a special 16K Adv Library and Microcode version. After the issue
15644 * resolved, we should turn back to the 32K support. Both a_condor.h and
15645 * mcode.sas files also need to be updated.
15646 *
15647 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15648 * BIOS_EN | RAM_SZ_32KB);
15649 */
15650 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15651 BIOS_EN | RAM_SZ_16KB);
15652
15653 /*
15654 * Set SEL_MASK Microcode Default Value
15655 *
15656 * The microcode will set the SEL_MASK register using this value
15657 * after it is started below.
15658 */
15659 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15660 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15661
15662 /*
15663 * Build the carrier freelist.
15664 *
15665 * Driver must have already allocated memory and set 'carrier_buf'.
15666 */
15667
15668 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15669
15670 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15671 asc_dvc->carr_freelist = NULL;
15672 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
15673 buf_size = ADV_CARRIER_BUFSIZE;
15674 } else {
15675 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15676 }
1da177e4 15677
27c868c2
MW
15678 do {
15679 /*
15680 * Get physical address for the carrier 'carrp'.
15681 */
15682 contig_len = sizeof(ADV_CARR_T);
15683 carr_paddr =
15684 cpu_to_le32(DvcGetPhyAddr
15685 (asc_dvc, NULL, (uchar *)carrp,
15686 (ADV_SDCNT *)&contig_len,
15687 ADV_IS_CARRIER_FLAG));
1da177e4 15688
27c868c2 15689 buf_size -= sizeof(ADV_CARR_T);
1da177e4 15690
27c868c2
MW
15691 /*
15692 * If the current carrier is not physically contiguous, then
15693 * maybe there was a page crossing. Try the next carrier aligned
15694 * start address.
15695 */
15696 if (contig_len < sizeof(ADV_CARR_T)) {
15697 carrp++;
15698 continue;
15699 }
15700
15701 carrp->carr_pa = carr_paddr;
15702 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
1da177e4 15703
27c868c2
MW
15704 /*
15705 * Insert the carrier at the beginning of the freelist.
15706 */
15707 carrp->next_vpa =
15708 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15709 asc_dvc->carr_freelist = carrp;
1da177e4 15710
27c868c2
MW
15711 carrp++;
15712 }
15713 while (buf_size > 0);
15714
15715 /*
15716 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15717 */
15718 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
15719 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15720 return ADV_ERROR;
15721 }
15722 asc_dvc->carr_freelist = (ADV_CARR_T *)
15723 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15724
15725 /*
15726 * The first command issued will be placed in the stopper carrier.
15727 */
15728 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15729
15730 /*
15731 * Set RISC ICQ physical address start value. Initialize the
15732 * COMMA register to the same value otherwise the RISC will
15733 * prematurely detect a command is available.
15734 */
15735 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15736 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
15737 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
15738
15739 /*
15740 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15741 */
15742 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
15743 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15744 return ADV_ERROR;
15745 }
15746 asc_dvc->carr_freelist = (ADV_CARR_T *)
15747 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15748
15749 /*
15750 * The first command completed by the RISC will be placed in
15751 * the stopper.
15752 *
15753 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15754 * completed the RISC will set the ASC_RQ_STOPPER bit.
15755 */
15756 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15757
15758 /*
15759 * Set RISC IRQ physical address start value.
15760 */
15761 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15762 asc_dvc->carr_pending_cnt = 0;
15763
15764 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15765 (ADV_INTR_ENABLE_HOST_INTR |
15766 ADV_INTR_ENABLE_GLOBAL_INTR));
15767 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15768 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15769
15770 /* finally, finally, gentlemen, start your engine */
15771 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15772
15773 /*
15774 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15775 * Resets should be performed. The RISC has to be running
15776 * to issue a SCSI Bus Reset.
15777 */
15778 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
15779 /*
15780 * If the BIOS Signature is present in memory, restore the
15781 * per TID microcode operating variables.
15782 */
15783 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
15784 0x55AA) {
15785 /*
15786 * Restore per TID negotiated values.
15787 */
15788 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15789 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15790 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15791 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
15792 tagqng_able);
15793 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15794 AdvWriteByteLram(iop_base,
15795 ASC_MC_NUMBER_OF_MAX_CMD + tid,
15796 max_cmd[tid]);
15797 }
15798 } else {
15799 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
15800 warn_code = ASC_WARN_BUSRESET_ERROR;
15801 }
15802 }
15803 }
1da177e4 15804
27c868c2
MW
15805 return warn_code;
15806}
1da177e4 15807
27c868c2
MW
15808/*
15809 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
15810 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
15811 * all of this is done.
15812 *
15813 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15814 *
15815 * For a non-fatal error return a warning code. If there are no warnings
15816 * then 0 is returned.
15817 *
15818 * Note: Chip is stopped on entry.
15819 */
78e77d8b 15820static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
27c868c2
MW
15821{
15822 AdvPortAddr iop_base;
15823 ushort warn_code;
15824 ADVEEP_3550_CONFIG eep_config;
15825 int i;
1da177e4 15826
27c868c2 15827 iop_base = asc_dvc->iop_base;
1da177e4 15828
27c868c2 15829 warn_code = 0;
1da177e4 15830
27c868c2
MW
15831 /*
15832 * Read the board's EEPROM configuration.
15833 *
15834 * Set default values if a bad checksum is found.
15835 */
15836 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
15837 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 15838
27c868c2
MW
15839 /*
15840 * Set EEPROM default values.
15841 */
15842 for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++) {
15843 *((uchar *)&eep_config + i) =
15844 *((uchar *)&Default_3550_EEPROM_Config + i);
15845 }
1da177e4 15846
27c868c2
MW
15847 /*
15848 * Assume the 6 byte board serial number that was read
15849 * from EEPROM is correct even if the EEPROM checksum
15850 * failed.
15851 */
15852 eep_config.serial_number_word3 =
15853 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 15854
27c868c2
MW
15855 eep_config.serial_number_word2 =
15856 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
1da177e4 15857
27c868c2
MW
15858 eep_config.serial_number_word1 =
15859 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 15860
27c868c2
MW
15861 AdvSet3550EEPConfig(iop_base, &eep_config);
15862 }
15863 /*
15864 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
15865 * EEPROM configuration that was read.
15866 *
15867 * This is the mapping of EEPROM fields to Adv Library fields.
15868 */
15869 asc_dvc->wdtr_able = eep_config.wdtr_able;
15870 asc_dvc->sdtr_able = eep_config.sdtr_able;
15871 asc_dvc->ultra_able = eep_config.ultra_able;
15872 asc_dvc->tagqng_able = eep_config.tagqng_able;
15873 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
15874 asc_dvc->max_host_qng = eep_config.max_host_qng;
15875 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15876 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
15877 asc_dvc->start_motor = eep_config.start_motor;
15878 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
15879 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
15880 asc_dvc->no_scam = eep_config.scam_tolerant;
15881 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
15882 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
15883 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
15884
15885 /*
15886 * Set the host maximum queuing (max. 253, min. 16) and the per device
15887 * maximum queuing (max. 63, min. 4).
15888 */
15889 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
15890 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15891 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
15892 /* If the value is zero, assume it is uninitialized. */
15893 if (eep_config.max_host_qng == 0) {
15894 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15895 } else {
15896 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
15897 }
15898 }
1da177e4 15899
27c868c2
MW
15900 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
15901 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15902 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
15903 /* If the value is zero, assume it is uninitialized. */
15904 if (eep_config.max_dvc_qng == 0) {
15905 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15906 } else {
15907 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
15908 }
15909 }
1da177e4 15910
27c868c2
MW
15911 /*
15912 * If 'max_dvc_qng' is greater than 'max_host_qng', then
15913 * set 'max_dvc_qng' to 'max_host_qng'.
15914 */
15915 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
15916 eep_config.max_dvc_qng = eep_config.max_host_qng;
15917 }
1da177e4 15918
27c868c2
MW
15919 /*
15920 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
15921 * values based on possibly adjusted EEPROM values.
15922 */
15923 asc_dvc->max_host_qng = eep_config.max_host_qng;
15924 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15925
15926 /*
15927 * If the EEPROM 'termination' field is set to automatic (0), then set
15928 * the ADV_DVC_CFG 'termination' field to automatic also.
15929 *
15930 * If the termination is specified with a non-zero 'termination'
15931 * value check that a legal value is set and set the ADV_DVC_CFG
15932 * 'termination' field appropriately.
15933 */
15934 if (eep_config.termination == 0) {
15935 asc_dvc->cfg->termination = 0; /* auto termination */
15936 } else {
15937 /* Enable manual control with low off / high off. */
15938 if (eep_config.termination == 1) {
15939 asc_dvc->cfg->termination = TERM_CTL_SEL;
15940
15941 /* Enable manual control with low off / high on. */
15942 } else if (eep_config.termination == 2) {
15943 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
15944
15945 /* Enable manual control with low on / high on. */
15946 } else if (eep_config.termination == 3) {
15947 asc_dvc->cfg->termination =
15948 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
15949 } else {
15950 /*
15951 * The EEPROM 'termination' field contains a bad value. Use
15952 * automatic termination instead.
15953 */
15954 asc_dvc->cfg->termination = 0;
15955 warn_code |= ASC_WARN_EEPROM_TERMINATION;
15956 }
15957 }
1da177e4 15958
27c868c2
MW
15959 return warn_code;
15960}
1da177e4 15961
27c868c2
MW
15962/*
15963 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
15964 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
15965 * all of this is done.
15966 *
15967 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15968 *
15969 * For a non-fatal error return a warning code. If there are no warnings
15970 * then 0 is returned.
15971 *
15972 * Note: Chip is stopped on entry.
15973 */
78e77d8b 15974static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
27c868c2
MW
15975{
15976 AdvPortAddr iop_base;
15977 ushort warn_code;
15978 ADVEEP_38C0800_CONFIG eep_config;
15979 int i;
15980 uchar tid, termination;
15981 ushort sdtr_speed = 0;
15982
15983 iop_base = asc_dvc->iop_base;
15984
15985 warn_code = 0;
15986
15987 /*
15988 * Read the board's EEPROM configuration.
15989 *
15990 * Set default values if a bad checksum is found.
15991 */
15992 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
15993 eep_config.check_sum) {
15994 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 15995
27c868c2
MW
15996 /*
15997 * Set EEPROM default values.
15998 */
15999 for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++) {
16000 *((uchar *)&eep_config + i) =
16001 *((uchar *)&Default_38C0800_EEPROM_Config + i);
16002 }
1da177e4 16003
27c868c2
MW
16004 /*
16005 * Assume the 6 byte board serial number that was read
16006 * from EEPROM is correct even if the EEPROM checksum
16007 * failed.
16008 */
16009 eep_config.serial_number_word3 =
16010 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 16011
27c868c2
MW
16012 eep_config.serial_number_word2 =
16013 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
1da177e4 16014
27c868c2
MW
16015 eep_config.serial_number_word1 =
16016 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 16017
27c868c2
MW
16018 AdvSet38C0800EEPConfig(iop_base, &eep_config);
16019 }
16020 /*
16021 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
16022 * EEPROM configuration that was read.
16023 *
16024 * This is the mapping of EEPROM fields to Adv Library fields.
16025 */
16026 asc_dvc->wdtr_able = eep_config.wdtr_able;
16027 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16028 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16029 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16030 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16031 asc_dvc->tagqng_able = eep_config.tagqng_able;
16032 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16033 asc_dvc->max_host_qng = eep_config.max_host_qng;
16034 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16035 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16036 asc_dvc->start_motor = eep_config.start_motor;
16037 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16038 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16039 asc_dvc->no_scam = eep_config.scam_tolerant;
16040 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16041 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16042 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16043
16044 /*
16045 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16046 * are set, then set an 'sdtr_able' bit for it.
16047 */
16048 asc_dvc->sdtr_able = 0;
16049 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
16050 if (tid == 0) {
16051 sdtr_speed = asc_dvc->sdtr_speed1;
16052 } else if (tid == 4) {
16053 sdtr_speed = asc_dvc->sdtr_speed2;
16054 } else if (tid == 8) {
16055 sdtr_speed = asc_dvc->sdtr_speed3;
16056 } else if (tid == 12) {
16057 sdtr_speed = asc_dvc->sdtr_speed4;
16058 }
16059 if (sdtr_speed & ADV_MAX_TID) {
16060 asc_dvc->sdtr_able |= (1 << tid);
16061 }
16062 sdtr_speed >>= 4;
16063 }
1da177e4 16064
27c868c2
MW
16065 /*
16066 * Set the host maximum queuing (max. 253, min. 16) and the per device
16067 * maximum queuing (max. 63, min. 4).
16068 */
16069 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
16070 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16071 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
16072 /* If the value is zero, assume it is uninitialized. */
16073 if (eep_config.max_host_qng == 0) {
16074 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16075 } else {
16076 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16077 }
16078 }
1da177e4 16079
27c868c2
MW
16080 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
16081 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16082 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
16083 /* If the value is zero, assume it is uninitialized. */
16084 if (eep_config.max_dvc_qng == 0) {
16085 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16086 } else {
16087 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16088 }
16089 }
1da177e4 16090
27c868c2
MW
16091 /*
16092 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16093 * set 'max_dvc_qng' to 'max_host_qng'.
16094 */
16095 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
16096 eep_config.max_dvc_qng = eep_config.max_host_qng;
16097 }
1da177e4 16098
27c868c2
MW
16099 /*
16100 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16101 * values based on possibly adjusted EEPROM values.
16102 */
16103 asc_dvc->max_host_qng = eep_config.max_host_qng;
16104 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16105
16106 /*
16107 * If the EEPROM 'termination' field is set to automatic (0), then set
16108 * the ADV_DVC_CFG 'termination' field to automatic also.
16109 *
16110 * If the termination is specified with a non-zero 'termination'
16111 * value check that a legal value is set and set the ADV_DVC_CFG
16112 * 'termination' field appropriately.
16113 */
16114 if (eep_config.termination_se == 0) {
16115 termination = 0; /* auto termination for SE */
16116 } else {
16117 /* Enable manual control with low off / high off. */
16118 if (eep_config.termination_se == 1) {
16119 termination = 0;
16120
16121 /* Enable manual control with low off / high on. */
16122 } else if (eep_config.termination_se == 2) {
16123 termination = TERM_SE_HI;
16124
16125 /* Enable manual control with low on / high on. */
16126 } else if (eep_config.termination_se == 3) {
16127 termination = TERM_SE;
16128 } else {
16129 /*
16130 * The EEPROM 'termination_se' field contains a bad value.
16131 * Use automatic termination instead.
16132 */
16133 termination = 0;
16134 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16135 }
16136 }
1da177e4 16137
27c868c2
MW
16138 if (eep_config.termination_lvd == 0) {
16139 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
16140 } else {
16141 /* Enable manual control with low off / high off. */
16142 if (eep_config.termination_lvd == 1) {
16143 asc_dvc->cfg->termination = termination;
16144
16145 /* Enable manual control with low off / high on. */
16146 } else if (eep_config.termination_lvd == 2) {
16147 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16148
16149 /* Enable manual control with low on / high on. */
16150 } else if (eep_config.termination_lvd == 3) {
16151 asc_dvc->cfg->termination = termination | TERM_LVD;
16152 } else {
16153 /*
16154 * The EEPROM 'termination_lvd' field contains a bad value.
16155 * Use automatic termination instead.
16156 */
16157 asc_dvc->cfg->termination = termination;
16158 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16159 }
16160 }
1da177e4 16161
27c868c2 16162 return warn_code;
1da177e4
LT
16163}
16164
16165/*
27c868c2
MW
16166 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
16167 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
16168 * all of this is done.
1da177e4
LT
16169 *
16170 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
16171 *
16172 * For a non-fatal error return a warning code. If there are no warnings
16173 * then 0 is returned.
16174 *
27c868c2 16175 * Note: Chip is stopped on entry.
1da177e4 16176 */
78e77d8b 16177static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
1da177e4 16178{
27c868c2
MW
16179 AdvPortAddr iop_base;
16180 ushort warn_code;
16181 ADVEEP_38C1600_CONFIG eep_config;
16182 int i;
16183 uchar tid, termination;
16184 ushort sdtr_speed = 0;
16185
16186 iop_base = asc_dvc->iop_base;
16187
16188 warn_code = 0;
16189
16190 /*
16191 * Read the board's EEPROM configuration.
16192 *
16193 * Set default values if a bad checksum is found.
16194 */
16195 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
16196 eep_config.check_sum) {
16197 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 16198
27c868c2
MW
16199 /*
16200 * Set EEPROM default values.
16201 */
16202 for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++) {
16203 if (i == 1
16204 && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) !=
16205 0) {
16206 /*
16207 * Set Function 1 EEPROM Word 0 MSB
16208 *
16209 * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11)
16210 * EEPROM bits.
16211 *
16212 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and
16213 * old Mac system booting problem. The Expansion ROM must
16214 * be disabled in Function 1 for these systems.
16215 *
16216 */
16217 *((uchar *)&eep_config + i) =
16218 ((*
16219 ((uchar *)&Default_38C1600_EEPROM_Config
16220 +
16221 i)) &
16222 (~
16223 (((ADV_EEPROM_BIOS_ENABLE |
16224 ADV_EEPROM_INTAB) >> 8) & 0xFF)));
16225
16226 /*
16227 * Set the INTAB (bit 11) if the GPIO 0 input indicates
16228 * the Function 1 interrupt line is wired to INTA.
16229 *
16230 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
16231 * 1 - Function 1 interrupt line wired to INT A.
16232 * 0 - Function 1 interrupt line wired to INT B.
16233 *
16234 * Note: Adapter boards always have Function 0 wired to INTA.
16235 * Put all 5 GPIO bits in input mode and then read
16236 * their input values.
16237 */
16238 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL,
16239 0);
16240 if (AdvReadByteRegister
16241 (iop_base, IOPB_GPIO_DATA) & 0x01) {
16242 /* Function 1 interrupt wired to INTA; Set EEPROM bit. */
16243 *((uchar *)&eep_config + i) |=
16244 ((ADV_EEPROM_INTAB >> 8) & 0xFF);
16245 }
16246 } else {
16247 *((uchar *)&eep_config + i) =
16248 *((uchar *)&Default_38C1600_EEPROM_Config
16249 + i);
16250 }
16251 }
1da177e4 16252
27c868c2
MW
16253 /*
16254 * Assume the 6 byte board serial number that was read
16255 * from EEPROM is correct even if the EEPROM checksum
16256 * failed.
16257 */
16258 eep_config.serial_number_word3 =
16259 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 16260
27c868c2
MW
16261 eep_config.serial_number_word2 =
16262 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
1da177e4 16263
27c868c2
MW
16264 eep_config.serial_number_word1 =
16265 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 16266
27c868c2
MW
16267 AdvSet38C1600EEPConfig(iop_base, &eep_config);
16268 }
1da177e4 16269
27c868c2
MW
16270 /*
16271 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16272 * EEPROM configuration that was read.
16273 *
16274 * This is the mapping of EEPROM fields to Adv Library fields.
16275 */
16276 asc_dvc->wdtr_able = eep_config.wdtr_able;
16277 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16278 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16279 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16280 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16281 asc_dvc->ppr_able = 0;
16282 asc_dvc->tagqng_able = eep_config.tagqng_able;
16283 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16284 asc_dvc->max_host_qng = eep_config.max_host_qng;
16285 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16286 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
16287 asc_dvc->start_motor = eep_config.start_motor;
16288 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16289 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16290 asc_dvc->no_scam = eep_config.scam_tolerant;
16291
16292 /*
16293 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16294 * are set, then set an 'sdtr_able' bit for it.
16295 */
16296 asc_dvc->sdtr_able = 0;
16297 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
16298 if (tid == 0) {
16299 sdtr_speed = asc_dvc->sdtr_speed1;
16300 } else if (tid == 4) {
16301 sdtr_speed = asc_dvc->sdtr_speed2;
16302 } else if (tid == 8) {
16303 sdtr_speed = asc_dvc->sdtr_speed3;
16304 } else if (tid == 12) {
16305 sdtr_speed = asc_dvc->sdtr_speed4;
16306 }
16307 if (sdtr_speed & ASC_MAX_TID) {
16308 asc_dvc->sdtr_able |= (1 << tid);
16309 }
16310 sdtr_speed >>= 4;
16311 }
1da177e4 16312
27c868c2
MW
16313 /*
16314 * Set the host maximum queuing (max. 253, min. 16) and the per device
16315 * maximum queuing (max. 63, min. 4).
16316 */
16317 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
16318 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16319 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
16320 /* If the value is zero, assume it is uninitialized. */
16321 if (eep_config.max_host_qng == 0) {
16322 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16323 } else {
16324 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16325 }
16326 }
1da177e4 16327
27c868c2
MW
16328 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
16329 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16330 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
16331 /* If the value is zero, assume it is uninitialized. */
16332 if (eep_config.max_dvc_qng == 0) {
16333 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16334 } else {
16335 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16336 }
16337 }
1da177e4 16338
27c868c2
MW
16339 /*
16340 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16341 * set 'max_dvc_qng' to 'max_host_qng'.
16342 */
16343 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
16344 eep_config.max_dvc_qng = eep_config.max_host_qng;
16345 }
1da177e4 16346
27c868c2
MW
16347 /*
16348 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
16349 * values based on possibly adjusted EEPROM values.
16350 */
16351 asc_dvc->max_host_qng = eep_config.max_host_qng;
16352 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16353
16354 /*
16355 * If the EEPROM 'termination' field is set to automatic (0), then set
16356 * the ASC_DVC_CFG 'termination' field to automatic also.
16357 *
16358 * If the termination is specified with a non-zero 'termination'
16359 * value check that a legal value is set and set the ASC_DVC_CFG
16360 * 'termination' field appropriately.
16361 */
16362 if (eep_config.termination_se == 0) {
16363 termination = 0; /* auto termination for SE */
16364 } else {
16365 /* Enable manual control with low off / high off. */
16366 if (eep_config.termination_se == 1) {
16367 termination = 0;
16368
16369 /* Enable manual control with low off / high on. */
16370 } else if (eep_config.termination_se == 2) {
16371 termination = TERM_SE_HI;
16372
16373 /* Enable manual control with low on / high on. */
16374 } else if (eep_config.termination_se == 3) {
16375 termination = TERM_SE;
16376 } else {
16377 /*
16378 * The EEPROM 'termination_se' field contains a bad value.
16379 * Use automatic termination instead.
16380 */
16381 termination = 0;
16382 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16383 }
16384 }
1da177e4 16385
27c868c2
MW
16386 if (eep_config.termination_lvd == 0) {
16387 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
16388 } else {
16389 /* Enable manual control with low off / high off. */
16390 if (eep_config.termination_lvd == 1) {
16391 asc_dvc->cfg->termination = termination;
16392
16393 /* Enable manual control with low off / high on. */
16394 } else if (eep_config.termination_lvd == 2) {
16395 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16396
16397 /* Enable manual control with low on / high on. */
16398 } else if (eep_config.termination_lvd == 3) {
16399 asc_dvc->cfg->termination = termination | TERM_LVD;
16400 } else {
16401 /*
16402 * The EEPROM 'termination_lvd' field contains a bad value.
16403 * Use automatic termination instead.
16404 */
16405 asc_dvc->cfg->termination = termination;
16406 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16407 }
16408 }
1da177e4 16409
27c868c2 16410 return warn_code;
1da177e4
LT
16411}
16412
16413/*
16414 * Read EEPROM configuration into the specified buffer.
16415 *
16416 * Return a checksum based on the EEPROM configuration read.
16417 */
78e77d8b 16418static ushort __devinit
1da177e4
LT
16419AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16420{
27c868c2
MW
16421 ushort wval, chksum;
16422 ushort *wbuf;
16423 int eep_addr;
16424 ushort *charfields;
16425
16426 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16427 wbuf = (ushort *)cfg_buf;
16428 chksum = 0;
16429
16430 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16431 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16432 wval = AdvReadEEPWord(iop_base, eep_addr);
16433 chksum += wval; /* Checksum is calculated from word values. */
16434 if (*charfields++) {
16435 *wbuf = le16_to_cpu(wval);
16436 } else {
16437 *wbuf = wval;
16438 }
16439 }
16440 /* Read checksum word. */
16441 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16442 wbuf++;
16443 charfields++;
16444
16445 /* Read rest of EEPROM not covered by the checksum. */
16446 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16447 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16448 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16449 if (*charfields++) {
16450 *wbuf = le16_to_cpu(*wbuf);
16451 }
16452 }
16453 return chksum;
1da177e4
LT
16454}
16455
16456/*
16457 * Read EEPROM configuration into the specified buffer.
16458 *
16459 * Return a checksum based on the EEPROM configuration read.
16460 */
78e77d8b 16461static ushort __devinit
27c868c2 16462AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
1da177e4 16463{
27c868c2
MW
16464 ushort wval, chksum;
16465 ushort *wbuf;
16466 int eep_addr;
16467 ushort *charfields;
16468
16469 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16470 wbuf = (ushort *)cfg_buf;
16471 chksum = 0;
16472
16473 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16474 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16475 wval = AdvReadEEPWord(iop_base, eep_addr);
16476 chksum += wval; /* Checksum is calculated from word values. */
16477 if (*charfields++) {
16478 *wbuf = le16_to_cpu(wval);
16479 } else {
16480 *wbuf = wval;
16481 }
16482 }
16483 /* Read checksum word. */
16484 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16485 wbuf++;
16486 charfields++;
16487
16488 /* Read rest of EEPROM not covered by the checksum. */
16489 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16490 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16491 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16492 if (*charfields++) {
16493 *wbuf = le16_to_cpu(*wbuf);
16494 }
16495 }
16496 return chksum;
1da177e4
LT
16497}
16498
16499/*
16500 * Read EEPROM configuration into the specified buffer.
16501 *
16502 * Return a checksum based on the EEPROM configuration read.
16503 */
78e77d8b 16504static ushort __devinit
27c868c2 16505AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
1da177e4 16506{
27c868c2
MW
16507 ushort wval, chksum;
16508 ushort *wbuf;
16509 int eep_addr;
16510 ushort *charfields;
16511
16512 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16513 wbuf = (ushort *)cfg_buf;
16514 chksum = 0;
16515
16516 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16517 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16518 wval = AdvReadEEPWord(iop_base, eep_addr);
16519 chksum += wval; /* Checksum is calculated from word values. */
16520 if (*charfields++) {
16521 *wbuf = le16_to_cpu(wval);
16522 } else {
16523 *wbuf = wval;
16524 }
16525 }
16526 /* Read checksum word. */
16527 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16528 wbuf++;
16529 charfields++;
16530
16531 /* Read rest of EEPROM not covered by the checksum. */
16532 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16533 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16534 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16535 if (*charfields++) {
16536 *wbuf = le16_to_cpu(*wbuf);
16537 }
16538 }
16539 return chksum;
1da177e4
LT
16540}
16541
16542/*
16543 * Read the EEPROM from specified location
16544 */
78e77d8b 16545static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
1da177e4 16546{
27c868c2
MW
16547 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16548 ASC_EEP_CMD_READ | eep_word_addr);
16549 AdvWaitEEPCmd(iop_base);
16550 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
1da177e4
LT
16551}
16552
16553/*
16554 * Wait for EEPROM command to complete
16555 */
78e77d8b 16556static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
1da177e4 16557{
27c868c2
MW
16558 int eep_delay_ms;
16559
16560 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
16561 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
16562 ASC_EEP_CMD_DONE) {
16563 break;
16564 }
16565 DvcSleepMilliSecond(1);
16566 }
16567 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
16568 0) {
16569 ASC_ASSERT(0);
16570 }
16571 return;
1da177e4
LT
16572}
16573
16574/*
16575 * Write the EEPROM from 'cfg_buf'.
16576 */
78e77d8b 16577void __devinit
1da177e4
LT
16578AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16579{
27c868c2
MW
16580 ushort *wbuf;
16581 ushort addr, chksum;
16582 ushort *charfields;
16583
16584 wbuf = (ushort *)cfg_buf;
16585 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16586 chksum = 0;
16587
16588 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16589 AdvWaitEEPCmd(iop_base);
16590
16591 /*
16592 * Write EEPROM from word 0 to word 20.
16593 */
16594 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16595 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16596 ushort word;
16597
16598 if (*charfields++) {
16599 word = cpu_to_le16(*wbuf);
16600 } else {
16601 word = *wbuf;
16602 }
16603 chksum += *wbuf; /* Checksum is calculated from word values. */
16604 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16605 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16606 ASC_EEP_CMD_WRITE | addr);
16607 AdvWaitEEPCmd(iop_base);
16608 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16609 }
1da177e4 16610
27c868c2
MW
16611 /*
16612 * Write EEPROM checksum at word 21.
16613 */
16614 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16615 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16616 AdvWaitEEPCmd(iop_base);
16617 wbuf++;
16618 charfields++;
16619
16620 /*
16621 * Write EEPROM OEM name at words 22 to 29.
16622 */
16623 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16624 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16625 ushort word;
16626
16627 if (*charfields++) {
16628 word = cpu_to_le16(*wbuf);
16629 } else {
16630 word = *wbuf;
16631 }
16632 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16633 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16634 ASC_EEP_CMD_WRITE | addr);
16635 AdvWaitEEPCmd(iop_base);
16636 }
16637 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16638 AdvWaitEEPCmd(iop_base);
16639 return;
1da177e4
LT
16640}
16641
16642/*
16643 * Write the EEPROM from 'cfg_buf'.
16644 */
78e77d8b 16645void __devinit
27c868c2 16646AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
1da177e4 16647{
27c868c2
MW
16648 ushort *wbuf;
16649 ushort *charfields;
16650 ushort addr, chksum;
16651
16652 wbuf = (ushort *)cfg_buf;
16653 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16654 chksum = 0;
16655
16656 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16657 AdvWaitEEPCmd(iop_base);
16658
16659 /*
16660 * Write EEPROM from word 0 to word 20.
16661 */
16662 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16663 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16664 ushort word;
16665
16666 if (*charfields++) {
16667 word = cpu_to_le16(*wbuf);
16668 } else {
16669 word = *wbuf;
16670 }
16671 chksum += *wbuf; /* Checksum is calculated from word values. */
16672 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16673 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16674 ASC_EEP_CMD_WRITE | addr);
16675 AdvWaitEEPCmd(iop_base);
16676 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16677 }
1da177e4 16678
27c868c2
MW
16679 /*
16680 * Write EEPROM checksum at word 21.
16681 */
16682 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16683 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16684 AdvWaitEEPCmd(iop_base);
16685 wbuf++;
16686 charfields++;
16687
16688 /*
16689 * Write EEPROM OEM name at words 22 to 29.
16690 */
16691 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16692 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16693 ushort word;
16694
16695 if (*charfields++) {
16696 word = cpu_to_le16(*wbuf);
16697 } else {
16698 word = *wbuf;
16699 }
16700 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16701 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16702 ASC_EEP_CMD_WRITE | addr);
16703 AdvWaitEEPCmd(iop_base);
16704 }
16705 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16706 AdvWaitEEPCmd(iop_base);
16707 return;
1da177e4
LT
16708}
16709
16710/*
16711 * Write the EEPROM from 'cfg_buf'.
16712 */
78e77d8b 16713void __devinit
27c868c2 16714AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
1da177e4 16715{
27c868c2
MW
16716 ushort *wbuf;
16717 ushort *charfields;
16718 ushort addr, chksum;
16719
16720 wbuf = (ushort *)cfg_buf;
16721 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16722 chksum = 0;
16723
16724 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16725 AdvWaitEEPCmd(iop_base);
16726
16727 /*
16728 * Write EEPROM from word 0 to word 20.
16729 */
16730 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16731 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16732 ushort word;
16733
16734 if (*charfields++) {
16735 word = cpu_to_le16(*wbuf);
16736 } else {
16737 word = *wbuf;
16738 }
16739 chksum += *wbuf; /* Checksum is calculated from word values. */
16740 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16741 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16742 ASC_EEP_CMD_WRITE | addr);
16743 AdvWaitEEPCmd(iop_base);
16744 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16745 }
1da177e4 16746
27c868c2
MW
16747 /*
16748 * Write EEPROM checksum at word 21.
16749 */
16750 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16751 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16752 AdvWaitEEPCmd(iop_base);
16753 wbuf++;
16754 charfields++;
16755
16756 /*
16757 * Write EEPROM OEM name at words 22 to 29.
16758 */
16759 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16760 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16761 ushort word;
16762
16763 if (*charfields++) {
16764 word = cpu_to_le16(*wbuf);
16765 } else {
16766 word = *wbuf;
16767 }
16768 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16769 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16770 ASC_EEP_CMD_WRITE | addr);
16771 AdvWaitEEPCmd(iop_base);
16772 }
16773 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16774 AdvWaitEEPCmd(iop_base);
16775 return;
1da177e4
LT
16776}
16777
16778/* a_advlib.c */
16779/*
16780 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
16781 *
16782 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
16783 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
16784 * RISC to notify it a new command is ready to be executed.
16785 *
16786 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
16787 * set to SCSI_MAX_RETRY.
16788 *
16789 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
16790 * for DMA addresses or math operations are byte swapped to little-endian
16791 * order.
16792 *
16793 * Return:
16794 * ADV_SUCCESS(1) - The request was successfully queued.
16795 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
16796 * request completes.
16797 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
16798 * host IC error.
16799 */
27c868c2 16800static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
1da177e4 16801{
27c868c2
MW
16802 ulong last_int_level;
16803 AdvPortAddr iop_base;
16804 ADV_DCNT req_size;
16805 ADV_PADDR req_paddr;
16806 ADV_CARR_T *new_carrp;
16807
16808 ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
16809
16810 /*
16811 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
16812 */
16813 if (scsiq->target_id > ADV_MAX_TID) {
16814 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
16815 scsiq->done_status = QD_WITH_ERROR;
16816 return ADV_ERROR;
16817 }
1da177e4 16818
27c868c2 16819 iop_base = asc_dvc->iop_base;
1da177e4 16820
27c868c2 16821 last_int_level = DvcEnterCritical();
1da177e4 16822
27c868c2
MW
16823 /*
16824 * Allocate a carrier ensuring at least one carrier always
16825 * remains on the freelist and initialize fields.
16826 */
16827 if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
16828 DvcLeaveCritical(last_int_level);
16829 return ADV_BUSY;
16830 }
16831 asc_dvc->carr_freelist = (ADV_CARR_T *)
16832 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
16833 asc_dvc->carr_pending_cnt++;
16834
16835 /*
16836 * Set the carrier to be a stopper by setting 'next_vpa'
16837 * to the stopper value. The current stopper will be changed
16838 * below to point to the new stopper.
16839 */
16840 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16841
16842 /*
16843 * Clear the ADV_SCSI_REQ_Q done flag.
16844 */
16845 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
16846
16847 req_size = sizeof(ADV_SCSI_REQ_Q);
16848 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
16849 (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
16850
16851 ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
16852 ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
16853
16854 /* Wait for assertion before making little-endian */
16855 req_paddr = cpu_to_le32(req_paddr);
16856
16857 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
16858 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
16859 scsiq->scsiq_rptr = req_paddr;
16860
16861 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
16862 /*
16863 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
16864 * order during initialization.
16865 */
16866 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
16867
16868 /*
16869 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
16870 * the microcode. The newly allocated stopper will become the new
16871 * stopper.
16872 */
16873 asc_dvc->icq_sp->areq_vpa = req_paddr;
16874
16875 /*
16876 * Set the 'next_vpa' pointer for the old stopper to be the
16877 * physical address of the new stopper. The RISC can only
16878 * follow physical addresses.
16879 */
16880 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
16881
16882 /*
16883 * Set the host adapter stopper pointer to point to the new carrier.
16884 */
16885 asc_dvc->icq_sp = new_carrp;
16886
16887 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
16888 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
16889 /*
16890 * Tickle the RISC to tell it to read its Command Queue Head pointer.
16891 */
16892 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
16893 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
16894 /*
16895 * Clear the tickle value. In the ASC-3550 the RISC flag
16896 * command 'clr_tickle_a' does not work unless the host
16897 * value is cleared.
16898 */
16899 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
16900 ADV_TICKLE_NOP);
16901 }
16902 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16903 /*
16904 * Notify the RISC a carrier is ready by writing the physical
16905 * address of the new carrier stopper to the COMMA register.
16906 */
16907 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
16908 le32_to_cpu(new_carrp->carr_pa));
16909 }
1da177e4 16910
27c868c2 16911 DvcLeaveCritical(last_int_level);
1da177e4 16912
27c868c2 16913 return ADV_SUCCESS;
1da177e4
LT
16914}
16915
16916/*
16917 * Reset SCSI Bus and purge all outstanding requests.
16918 *
16919 * Return Value:
16920 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
16921 * ADV_FALSE(0) - Microcode command failed.
16922 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
16923 * may be hung which requires driver recovery.
16924 */
27c868c2 16925static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
1da177e4 16926{
27c868c2
MW
16927 int status;
16928
16929 /*
16930 * Send the SCSI Bus Reset idle start idle command which asserts
16931 * the SCSI Bus Reset signal.
16932 */
16933 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
16934 if (status != ADV_TRUE) {
16935 return status;
16936 }
1da177e4 16937
27c868c2
MW
16938 /*
16939 * Delay for the specified SCSI Bus Reset hold time.
16940 *
16941 * The hold time delay is done on the host because the RISC has no
16942 * microsecond accurate timer.
16943 */
16944 DvcDelayMicroSecond(asc_dvc, (ushort)ASC_SCSI_RESET_HOLD_TIME_US);
16945
16946 /*
16947 * Send the SCSI Bus Reset end idle command which de-asserts
16948 * the SCSI Bus Reset signal and purges any pending requests.
16949 */
16950 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
16951 if (status != ADV_TRUE) {
16952 return status;
16953 }
16954
16955 DvcSleepMilliSecond((ADV_DCNT)asc_dvc->scsi_reset_wait * 1000);
1da177e4 16956
27c868c2 16957 return status;
1da177e4
LT
16958}
16959
16960/*
16961 * Reset chip and SCSI Bus.
16962 *
16963 * Return Value:
16964 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
16965 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
16966 */
27c868c2 16967static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
1da177e4 16968{
27c868c2
MW
16969 int status;
16970 ushort wdtr_able, sdtr_able, tagqng_able;
16971 ushort ppr_able = 0;
16972 uchar tid, max_cmd[ADV_MAX_TID + 1];
16973 AdvPortAddr iop_base;
16974 ushort bios_sig;
16975
16976 iop_base = asc_dvc->iop_base;
16977
16978 /*
16979 * Save current per TID negotiated values.
16980 */
16981 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16982 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16983 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16984 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16985 }
16986 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16987 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
16988 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16989 max_cmd[tid]);
16990 }
1da177e4 16991
27c868c2
MW
16992 /*
16993 * Force the AdvInitAsc3550/38C0800Driver() function to
16994 * perform a SCSI Bus Reset by clearing the BIOS signature word.
16995 * The initialization functions assumes a SCSI Bus Reset is not
16996 * needed if the BIOS signature word is present.
16997 */
16998 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
16999 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
17000
17001 /*
17002 * Stop chip and reset it.
17003 */
17004 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
17005 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
17006 DvcSleepMilliSecond(100);
17007 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
17008 ADV_CTRL_REG_CMD_WR_IO_REG);
17009
17010 /*
17011 * Reset Adv Library error code, if any, and try
17012 * re-initializing the chip.
17013 */
17014 asc_dvc->err_code = 0;
17015 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17016 status = AdvInitAsc38C1600Driver(asc_dvc);
17017 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
17018 status = AdvInitAsc38C0800Driver(asc_dvc);
17019 } else {
17020 status = AdvInitAsc3550Driver(asc_dvc);
17021 }
1da177e4 17022
27c868c2
MW
17023 /* Translate initialization return value to status value. */
17024 if (status == 0) {
17025 status = ADV_TRUE;
17026 } else {
17027 status = ADV_FALSE;
17028 }
1da177e4 17029
27c868c2
MW
17030 /*
17031 * Restore the BIOS signature word.
17032 */
17033 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17034
17035 /*
17036 * Restore per TID negotiated values.
17037 */
17038 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17039 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17040 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17041 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17042 }
17043 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17044 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
17045 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17046 max_cmd[tid]);
17047 }
1da177e4 17048
27c868c2 17049 return status;
1da177e4
LT
17050}
17051
17052/*
17053 * Adv Library Interrupt Service Routine
17054 *
17055 * This function is called by a driver's interrupt service routine.
17056 * The function disables and re-enables interrupts.
17057 *
17058 * When a microcode idle command is completed, the ADV_DVC_VAR
17059 * 'idle_cmd_done' field is set to ADV_TRUE.
17060 *
17061 * Note: AdvISR() can be called when interrupts are disabled or even
17062 * when there is no hardware interrupt condition present. It will
17063 * always check for completed idle commands and microcode requests.
17064 * This is an important feature that shouldn't be changed because it
17065 * allows commands to be completed from polling mode loops.
17066 *
17067 * Return:
17068 * ADV_TRUE(1) - interrupt was pending
17069 * ADV_FALSE(0) - no interrupt was pending
17070 */
27c868c2 17071static int AdvISR(ADV_DVC_VAR *asc_dvc)
1da177e4 17072{
27c868c2
MW
17073 AdvPortAddr iop_base;
17074 uchar int_stat;
17075 ushort target_bit;
17076 ADV_CARR_T *free_carrp;
17077 ADV_VADDR irq_next_vpa;
17078 int flags;
17079 ADV_SCSI_REQ_Q *scsiq;
1da177e4 17080
27c868c2 17081 flags = DvcEnterCritical();
1da177e4 17082
27c868c2
MW
17083 iop_base = asc_dvc->iop_base;
17084
17085 /* Reading the register clears the interrupt. */
17086 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
17087
17088 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
17089 ADV_INTR_STATUS_INTRC)) == 0) {
17090 DvcLeaveCritical(flags);
17091 return ADV_FALSE;
17092 }
17093
17094 /*
17095 * Notify the driver of an asynchronous microcode condition by
17096 * calling the ADV_DVC_VAR.async_callback function. The function
17097 * is passed the microcode ASC_MC_INTRB_CODE byte value.
17098 */
17099 if (int_stat & ADV_INTR_STATUS_INTRB) {
17100 uchar intrb_code;
17101
17102 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
17103
17104 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17105 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
17106 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
17107 asc_dvc->carr_pending_cnt != 0) {
17108 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
17109 ADV_TICKLE_A);
17110 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
17111 AdvWriteByteRegister(iop_base,
17112 IOPB_TICKLE,
17113 ADV_TICKLE_NOP);
17114 }
17115 }
17116 }
17117
17118 if (asc_dvc->async_callback != 0) {
17119 (*asc_dvc->async_callback) (asc_dvc, intrb_code);
17120 }
17121 }
17122
17123 /*
17124 * Check if the IRQ stopper carrier contains a completed request.
17125 */
17126 while (((irq_next_vpa =
17127 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
17128 /*
17129 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
17130 * The RISC will have set 'areq_vpa' to a virtual address.
17131 *
17132 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
17133 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
17134 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
17135 * in AdvExeScsiQueue().
17136 */
17137 scsiq = (ADV_SCSI_REQ_Q *)
17138 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
17139
17140 /*
17141 * Request finished with good status and the queue was not
17142 * DMAed to host memory by the firmware. Set all status fields
17143 * to indicate good status.
17144 */
17145 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
17146 scsiq->done_status = QD_NO_ERROR;
17147 scsiq->host_status = scsiq->scsi_status = 0;
17148 scsiq->data_cnt = 0L;
17149 }
17150
17151 /*
17152 * Advance the stopper pointer to the next carrier
17153 * ignoring the lower four bits. Free the previous
17154 * stopper carrier.
17155 */
17156 free_carrp = asc_dvc->irq_sp;
17157 asc_dvc->irq_sp = (ADV_CARR_T *)
17158 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
17159
17160 free_carrp->next_vpa =
17161 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
17162 asc_dvc->carr_freelist = free_carrp;
17163 asc_dvc->carr_pending_cnt--;
17164
17165 ASC_ASSERT(scsiq != NULL);
17166 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
17167
17168 /*
17169 * Clear request microcode control flag.
17170 */
17171 scsiq->cntl = 0;
17172
17173 /*
17174 * If the command that completed was a SCSI INQUIRY and
17175 * LUN 0 was sent the command, then process the INQUIRY
17176 * command information for the device.
17177 *
17178 * Note: If data returned were either VPD or CmdDt data,
17179 * don't process the INQUIRY command information for
17180 * the device, otherwise may erroneously set *_able bits.
17181 */
17182 if (scsiq->done_status == QD_NO_ERROR &&
17183 scsiq->cdb[0] == INQUIRY &&
17184 scsiq->target_lun == 0 &&
17185 (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
17186 == ADV_INQ_RTN_STD_INQUIRY_DATA) {
17187 AdvInquiryHandling(asc_dvc, scsiq);
17188 }
17189
17190 /*
17191 * Notify the driver of the completed request by passing
17192 * the ADV_SCSI_REQ_Q pointer to its callback function.
17193 */
17194 scsiq->a_flag |= ADV_SCSIQ_DONE;
17195 (*asc_dvc->isr_callback) (asc_dvc, scsiq);
17196 /*
17197 * Note: After the driver callback function is called, 'scsiq'
17198 * can no longer be referenced.
17199 *
17200 * Fall through and continue processing other completed
17201 * requests...
17202 */
17203
17204 /*
17205 * Disable interrupts again in case the driver inadvertently
17206 * enabled interrupts in its callback function.
17207 *
17208 * The DvcEnterCritical() return value is ignored, because
17209 * the 'flags' saved when AdvISR() was first entered will be
17210 * used to restore the interrupt flag on exit.
17211 */
17212 (void)DvcEnterCritical();
17213 }
17214 DvcLeaveCritical(flags);
17215 return ADV_TRUE;
1da177e4
LT
17216}
17217
17218/*
17219 * Send an idle command to the chip and wait for completion.
17220 *
17221 * Command completion is polled for once per microsecond.
17222 *
17223 * The function can be called from anywhere including an interrupt handler.
17224 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
17225 * functions to prevent reentrancy.
17226 *
17227 * Return Values:
17228 * ADV_TRUE - command completed successfully
17229 * ADV_FALSE - command failed
17230 * ADV_ERROR - command timed out
17231 */
27c868c2 17232static int
1da177e4 17233AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
27c868c2 17234 ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
1da177e4 17235{
27c868c2
MW
17236 ulong last_int_level;
17237 int result;
17238 ADV_DCNT i, j;
17239 AdvPortAddr iop_base;
17240
17241 last_int_level = DvcEnterCritical();
17242
17243 iop_base = asc_dvc->iop_base;
17244
17245 /*
17246 * Clear the idle command status which is set by the microcode
17247 * to a non-zero value to indicate when the command is completed.
17248 * The non-zero result is one of the IDLE_CMD_STATUS_* values
17249 * defined in a_advlib.h.
17250 */
17251 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
17252
17253 /*
17254 * Write the idle command value after the idle command parameter
17255 * has been written to avoid a race condition. If the order is not
17256 * followed, the microcode may process the idle command before the
17257 * parameters have been written to LRAM.
17258 */
17259 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
17260 cpu_to_le32(idle_cmd_parameter));
17261 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
17262
17263 /*
17264 * Tickle the RISC to tell it to process the idle command.
17265 */
17266 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
17267 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
17268 /*
17269 * Clear the tickle value. In the ASC-3550 the RISC flag
17270 * command 'clr_tickle_b' does not work unless the host
17271 * value is cleared.
17272 */
17273 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17274 }
1da177e4 17275
27c868c2
MW
17276 /* Wait for up to 100 millisecond for the idle command to timeout. */
17277 for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
17278 /* Poll once each microsecond for command completion. */
17279 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
17280 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
17281 result);
17282 if (result != 0) {
17283 DvcLeaveCritical(last_int_level);
17284 return result;
17285 }
17286 DvcDelayMicroSecond(asc_dvc, (ushort)1);
17287 }
17288 }
1da177e4 17289
27c868c2
MW
17290 ASC_ASSERT(0); /* The idle command should never timeout. */
17291 DvcLeaveCritical(last_int_level);
17292 return ADV_ERROR;
1da177e4
LT
17293}
17294
17295/*
17296 * Inquiry Information Byte 7 Handling
17297 *
17298 * Handle SCSI Inquiry Command information for a device by setting
17299 * microcode operating variables that affect WDTR, SDTR, and Tag
17300 * Queuing.
17301 */
27c868c2 17302static void AdvInquiryHandling(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
1da177e4 17303{
27c868c2
MW
17304 AdvPortAddr iop_base;
17305 uchar tid;
17306 ADV_SCSI_INQUIRY *inq;
17307 ushort tidmask;
17308 ushort cfg_word;
17309
17310 /*
17311 * AdvInquiryHandling() requires up to INQUIRY information Byte 7
17312 * to be available.
17313 *
17314 * If less than 8 bytes of INQUIRY information were requested or less
17315 * than 8 bytes were transferred, then return. cdb[4] is the request
17316 * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
17317 * microcode to the transfer residual count.
17318 */
17319
17320 if (scsiq->cdb[4] < 8 ||
17321 (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8) {
17322 return;
17323 }
1da177e4 17324
27c868c2
MW
17325 iop_base = asc_dvc->iop_base;
17326 tid = scsiq->target_id;
17327
17328 inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr;
1da177e4 17329
27c868c2
MW
17330 /*
17331 * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
17332 */
17333 if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2) {
17334 return;
17335 } else {
17336 /*
17337 * INQUIRY Byte 7 Handling
17338 *
17339 * Use a device's INQUIRY byte 7 to determine whether it
17340 * supports WDTR, SDTR, and Tag Queuing. If the feature
17341 * is enabled in the EEPROM and the device supports the
17342 * feature, then enable it in the microcode.
17343 */
1da177e4 17344
27c868c2 17345 tidmask = ADV_TID_TO_TIDMASK(tid);
1da177e4 17346
27c868c2
MW
17347 /*
17348 * Wide Transfers
17349 *
17350 * If the EEPROM enabled WDTR for the device and the device
17351 * supports wide bus (16 bit) transfers, then turn on the
17352 * device's 'wdtr_able' bit and write the new value to the
17353 * microcode.
17354 */
17355 if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq)) {
17356 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
17357 if ((cfg_word & tidmask) == 0) {
17358 cfg_word |= tidmask;
17359 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
17360 cfg_word);
17361
17362 /*
17363 * Clear the microcode "SDTR negotiation" and "WDTR
17364 * negotiation" done indicators for the target to cause
17365 * it to negotiate with the new setting set above.
17366 * WDTR when accepted causes the target to enter
17367 * asynchronous mode, so SDTR must be negotiated.
17368 */
17369 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE,
17370 cfg_word);
17371 cfg_word &= ~tidmask;
17372 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE,
17373 cfg_word);
17374 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE,
17375 cfg_word);
17376 cfg_word &= ~tidmask;
17377 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE,
17378 cfg_word);
17379 }
17380 }
17381
17382 /*
17383 * Synchronous Transfers
17384 *
17385 * If the EEPROM enabled SDTR for the device and the device
17386 * supports synchronous transfers, then turn on the device's
17387 * 'sdtr_able' bit. Write the new value to the microcode.
17388 */
17389 if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq)) {
17390 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
17391 if ((cfg_word & tidmask) == 0) {
17392 cfg_word |= tidmask;
17393 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
17394 cfg_word);
17395
17396 /*
17397 * Clear the microcode "SDTR negotiation" done indicator
17398 * for the target to cause it to negotiate with the new
17399 * setting set above.
17400 */
17401 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE,
17402 cfg_word);
17403 cfg_word &= ~tidmask;
17404 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE,
17405 cfg_word);
17406 }
17407 }
17408 /*
17409 * If the Inquiry data included enough space for the SPI-3
17410 * Clocking field, then check if DT mode is supported.
17411 */
17412 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 &&
17413 (scsiq->cdb[4] >= 57 ||
17414 (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57)) {
17415 /*
17416 * PPR (Parallel Protocol Request) Capable
17417 *
17418 * If the device supports DT mode, then it must be PPR capable.
17419 * The PPR message will be used in place of the SDTR and WDTR
17420 * messages to negotiate synchronous speed and offset, transfer
17421 * width, and protocol options.
17422 */
17423 if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY) {
17424 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE,
17425 asc_dvc->ppr_able);
17426 asc_dvc->ppr_able |= tidmask;
17427 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE,
17428 asc_dvc->ppr_able);
17429 }
17430 }
17431
17432 /*
17433 * If the EEPROM enabled Tag Queuing for the device and the
17434 * device supports Tag Queueing, then turn on the device's
17435 * 'tagqng_enable' bit in the microcode and set the microcode
17436 * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
17437 * value.
17438 *
17439 * Tag Queuing is disabled for the BIOS which runs in polled
17440 * mode and would see no benefit from Tag Queuing. Also by
17441 * disabling Tag Queuing in the BIOS devices with Tag Queuing
17442 * bugs will at least work with the BIOS.
17443 */
17444 if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq)) {
17445 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
17446 cfg_word |= tidmask;
17447 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
17448 cfg_word);
17449
17450 AdvWriteByteLram(iop_base,
17451 ASC_MC_NUMBER_OF_MAX_CMD + tid,
17452 asc_dvc->max_dvc_qng);
17453 }
17454 }
1da177e4 17455}
27c868c2 17456
b2c16f58
MW
17457static int __devinit
17458advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
17459{
17460 int req_cnt = 0;
17461 adv_req_t *reqp = NULL;
17462 int sg_cnt = 0;
17463 adv_sgblk_t *sgp;
17464 int warn_code, err_code;
17465
17466 /*
17467 * Allocate buffer carrier structures. The total size
17468 * is about 4 KB, so allocate all at once.
17469 */
17470 boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
17471 ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp);
17472
17473 if (!boardp->carrp)
17474 goto kmalloc_failed;
17475
17476 /*
17477 * Allocate up to 'max_host_qng' request structures for the Wide
17478 * board. The total size is about 16 KB, so allocate all at once.
17479 * If the allocation fails decrement and try again.
17480 */
17481 for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
17482 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
17483
17484 ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, "
17485 "bytes %lu\n", reqp, req_cnt,
17486 (ulong)sizeof(adv_req_t) * req_cnt);
17487
17488 if (reqp)
17489 break;
17490 }
17491
17492 if (!reqp)
17493 goto kmalloc_failed;
17494
17495 boardp->orig_reqp = reqp;
17496
17497 /*
17498 * Allocate up to ADV_TOT_SG_BLOCK request structures for
17499 * the Wide board. Each structure is about 136 bytes.
17500 */
17501 boardp->adv_sgblkp = NULL;
17502 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
17503 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
17504
17505 if (!sgp)
17506 break;
17507
17508 sgp->next_sgblkp = boardp->adv_sgblkp;
17509 boardp->adv_sgblkp = sgp;
17510
17511 }
17512
17513 ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n",
17514 sg_cnt, sizeof(adv_sgblk_t),
17515 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
17516
17517 if (!boardp->adv_sgblkp)
17518 goto kmalloc_failed;
17519
17520 adv_dvc_varp->carrier_buf = boardp->carrp;
17521
17522 /*
17523 * Point 'adv_reqp' to the request structures and
17524 * link them together.
17525 */
17526 req_cnt--;
17527 reqp[req_cnt].next_reqp = NULL;
17528 for (; req_cnt > 0; req_cnt--) {
17529 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
17530 }
17531 boardp->adv_reqp = &reqp[0];
17532
17533 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17534 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n");
17535 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
17536 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17537 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()"
17538 "\n");
17539 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
17540 } else {
17541 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()"
17542 "\n");
17543 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
17544 }
17545 err_code = adv_dvc_varp->err_code;
17546
17547 if (warn_code || err_code) {
17548 ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
17549 " error 0x%x\n", boardp->id, warn_code, err_code);
17550 }
17551
17552 goto exit;
17553
17554 kmalloc_failed:
17555 ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
17556 "failed\n", boardp->id);
17557 err_code = ADV_ERROR;
17558 exit:
17559 return err_code;
17560}
17561
17562static void advansys_wide_free_mem(asc_board_t *boardp)
17563{
17564 kfree(boardp->carrp);
17565 boardp->carrp = NULL;
17566 kfree(boardp->orig_reqp);
17567 boardp->orig_reqp = boardp->adv_reqp = NULL;
17568 while (boardp->adv_sgblkp) {
17569 adv_sgblk_t *sgp = boardp->adv_sgblkp;
17570 boardp->adv_sgblkp = sgp->next_sgblkp;
17571 kfree(sgp);
17572 }
17573}
17574
27c868c2
MW
17575static struct Scsi_Host *__devinit
17576advansys_board_found(int iop, struct device *dev, int bus_type)
17577{
17578 struct Scsi_Host *shost;
17579 struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL;
17580 asc_board_t *boardp;
17581 ASC_DVC_VAR *asc_dvc_varp = NULL;
17582 ADV_DVC_VAR *adv_dvc_varp = NULL;
074c8fe4 17583 int share_irq;
27c868c2
MW
17584 int iolen = 0;
17585 ADV_PADDR pci_memory_address;
17586 int warn_code, err_code;
17587 int ret;
17588
17589 /*
17590 * Adapter found.
17591 *
17592 * Register the adapter, get its configuration, and
17593 * initialize it.
17594 */
8dfb5379
MW
17595 ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n");
17596 shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t));
27c868c2
MW
17597
17598 if (!shost)
17599 return NULL;
17600
27c868c2
MW
17601 /* Initialize private per board data */
17602 boardp = ASC_BOARDP(shost);
17603 memset(boardp, 0, sizeof(asc_board_t));
78e77d8b 17604 boardp->id = asc_board_count++;
27c868c2
MW
17605
17606 /* Initialize spinlock. */
17607 spin_lock_init(&boardp->lock);
17608
17609 /*
17610 * Handle both narrow and wide boards.
17611 *
17612 * If a Wide board was detected, set the board structure
17613 * wide board flag. Set-up the board structure based on
17614 * the board type.
17615 */
17616#ifdef CONFIG_PCI
17617 if (bus_type == ASC_IS_PCI &&
17618 (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
17619 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
17620 pdev->device == PCI_DEVICE_ID_38C1600_REV1)) {
17621 boardp->flags |= ASC_IS_WIDE_BOARD;
17622 }
17623#endif /* CONFIG_PCI */
17624
17625 if (ASC_NARROW_BOARD(boardp)) {
17626 ASC_DBG(1, "advansys_board_found: narrow board\n");
17627 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
17628 asc_dvc_varp->bus_type = bus_type;
17629 asc_dvc_varp->drv_ptr = boardp;
17630 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
17631 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
17632 asc_dvc_varp->iop_base = iop;
17633 asc_dvc_varp->isr_callback = asc_isr_callback;
17634 } else {
17635 ASC_DBG(1, "advansys_board_found: wide board\n");
17636 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
17637 adv_dvc_varp->drv_ptr = boardp;
17638 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
17639 adv_dvc_varp->isr_callback = adv_isr_callback;
17640 adv_dvc_varp->async_callback = adv_async_callback;
17641#ifdef CONFIG_PCI
17642 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
17643 ASC_DBG(1, "advansys_board_found: ASC-3550\n");
17644 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
17645 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
17646 ASC_DBG(1, "advansys_board_found: ASC-38C0800\n");
17647 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
17648 } else {
17649 ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
17650 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
17651 }
17652#endif /* CONFIG_PCI */
17653
17654 /*
17655 * Map the board's registers into virtual memory for
17656 * PCI slave access. Only memory accesses are used to
17657 * access the board's registers.
17658 *
17659 * Note: The PCI register base address is not always
17660 * page aligned, but the address passed to ioremap()
17661 * must be page aligned. It is guaranteed that the
17662 * PCI register base address will not cross a page
17663 * boundary.
17664 */
17665 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17666 iolen = ADV_3550_IOLEN;
17667 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17668 iolen = ADV_38C0800_IOLEN;
17669 } else {
17670 iolen = ADV_38C1600_IOLEN;
17671 }
17672#ifdef CONFIG_PCI
17673 pci_memory_address = pci_resource_start(pdev, 1);
17674 ASC_DBG1(1,
17675 "advansys_board_found: pci_memory_address: 0x%lx\n",
17676 (ulong)pci_memory_address);
17677 if ((boardp->ioremap_addr =
17678 ioremap(pci_memory_address & PAGE_MASK, PAGE_SIZE)) == 0) {
17679 ASC_PRINT3
17680 ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
17681 boardp->id, pci_memory_address, iolen);
b2c16f58 17682 goto err_shost;
27c868c2 17683 }
71f36115 17684 ASC_DBG1(1, "advansys_board_found: ioremap_addr: 0x%lx\n",
27c868c2
MW
17685 (ulong)boardp->ioremap_addr);
17686 adv_dvc_varp->iop_base = (AdvPortAddr)
17687 (boardp->ioremap_addr +
17688 (pci_memory_address - (pci_memory_address & PAGE_MASK)));
71f36115 17689 ASC_DBG1(1, "advansys_board_found: iop_base: 0x%lx\n",
27c868c2
MW
17690 adv_dvc_varp->iop_base);
17691#endif /* CONFIG_PCI */
17692
17693 /*
17694 * Even though it isn't used to access wide boards, other
17695 * than for the debug line below, save I/O Port address so
17696 * that it can be reported.
17697 */
17698 boardp->ioport = iop;
17699
17700 ASC_DBG2(1,
17701 "advansys_board_found: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
17702 (ushort)inp(iop + 1), (ushort)inpw(iop));
17703 }
17704
17705#ifdef CONFIG_PROC_FS
17706 /*
17707 * Allocate buffer for printing information from
17708 * /proc/scsi/advansys/[0...].
17709 */
b2c16f58
MW
17710 boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
17711 if (!boardp->prtbuf) {
17712 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
17713 "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
17714 goto err_unmap;
27c868c2
MW
17715 }
17716#endif /* CONFIG_PROC_FS */
17717
17718 if (ASC_NARROW_BOARD(boardp)) {
17719 asc_dvc_varp->cfg->dev = dev;
17720 /*
17721 * Set the board bus type and PCI IRQ before
17722 * calling AscInitGetConfig().
17723 */
17724 switch (asc_dvc_varp->bus_type) {
17725#ifdef CONFIG_ISA
17726 case ASC_IS_ISA:
17727 shost->unchecked_isa_dma = TRUE;
074c8fe4 17728 share_irq = 0;
27c868c2
MW
17729 break;
17730 case ASC_IS_VL:
17731 shost->unchecked_isa_dma = FALSE;
074c8fe4 17732 share_irq = 0;
27c868c2
MW
17733 break;
17734 case ASC_IS_EISA:
17735 shost->unchecked_isa_dma = FALSE;
074c8fe4 17736 share_irq = IRQF_SHARED;
27c868c2
MW
17737 break;
17738#endif /* CONFIG_ISA */
17739#ifdef CONFIG_PCI
17740 case ASC_IS_PCI:
17741 shost->irq = asc_dvc_varp->irq_no = pdev->irq;
17742 asc_dvc_varp->cfg->pci_slot_info =
17743 ASC_PCI_MKID(pdev->bus->number,
17744 PCI_SLOT(pdev->devfn),
17745 PCI_FUNC(pdev->devfn));
17746 shost->unchecked_isa_dma = FALSE;
074c8fe4 17747 share_irq = IRQF_SHARED;
27c868c2
MW
17748 break;
17749#endif /* CONFIG_PCI */
17750 default:
17751 ASC_PRINT2
17752 ("advansys_board_found: board %d: unknown adapter type: %d\n",
17753 boardp->id, asc_dvc_varp->bus_type);
17754 shost->unchecked_isa_dma = TRUE;
074c8fe4 17755 share_irq = 0;
27c868c2
MW
17756 break;
17757 }
17758 } else {
17759 adv_dvc_varp->cfg->dev = dev;
17760 /*
17761 * For Wide boards set PCI information before calling
17762 * AdvInitGetConfig().
17763 */
17764#ifdef CONFIG_PCI
17765 shost->irq = adv_dvc_varp->irq_no = pdev->irq;
17766 adv_dvc_varp->cfg->pci_slot_info =
17767 ASC_PCI_MKID(pdev->bus->number,
17768 PCI_SLOT(pdev->devfn),
17769 PCI_FUNC(pdev->devfn));
17770 shost->unchecked_isa_dma = FALSE;
074c8fe4 17771 share_irq = IRQF_SHARED;
27c868c2
MW
17772#endif /* CONFIG_PCI */
17773 }
17774
17775 /*
17776 * Read the board configuration.
17777 */
17778 if (ASC_NARROW_BOARD(boardp)) {
17779 /*
17780 * NOTE: AscInitGetConfig() may change the board's
17781 * bus_type value. The bus_type value should no
17782 * longer be used. If the bus_type field must be
17783 * referenced only use the bit-wise AND operator "&".
17784 */
17785 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
17786 switch (ret = AscInitGetConfig(asc_dvc_varp)) {
17787 case 0: /* No error */
17788 break;
17789 case ASC_WARN_IO_PORT_ROTATE:
17790 ASC_PRINT1
17791 ("AscInitGetConfig: board %d: I/O port address modified\n",
17792 boardp->id);
17793 break;
17794 case ASC_WARN_AUTO_CONFIG:
17795 ASC_PRINT1
17796 ("AscInitGetConfig: board %d: I/O port increment switch enabled\n",
17797 boardp->id);
17798 break;
17799 case ASC_WARN_EEPROM_CHKSUM:
17800 ASC_PRINT1
17801 ("AscInitGetConfig: board %d: EEPROM checksum error\n",
17802 boardp->id);
17803 break;
17804 case ASC_WARN_IRQ_MODIFIED:
17805 ASC_PRINT1
17806 ("AscInitGetConfig: board %d: IRQ modified\n",
17807 boardp->id);
17808 break;
17809 case ASC_WARN_CMD_QNG_CONFLICT:
17810 ASC_PRINT1
17811 ("AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
17812 boardp->id);
17813 break;
17814 default:
17815 ASC_PRINT2
17816 ("AscInitGetConfig: board %d: unknown warning: 0x%x\n",
17817 boardp->id, ret);
17818 break;
17819 }
17820 if ((err_code = asc_dvc_varp->err_code) != 0) {
17821 ASC_PRINT3
17822 ("AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
17823 boardp->id,
17824 asc_dvc_varp->init_state, asc_dvc_varp->err_code);
17825 }
17826 } else {
17827 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
17828 if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
17829 ASC_PRINT2
17830 ("AdvInitGetConfig: board %d: warning: 0x%x\n",
17831 boardp->id, ret);
17832 }
17833 if ((err_code = adv_dvc_varp->err_code) != 0) {
17834 ASC_PRINT2
17835 ("AdvInitGetConfig: board %d error: err_code 0x%x\n",
17836 boardp->id, adv_dvc_varp->err_code);
17837 }
17838 }
17839
b2c16f58
MW
17840 if (err_code != 0)
17841 goto err_free_proc;
27c868c2
MW
17842
17843 /*
17844 * Save the EEPROM configuration so that it can be displayed
17845 * from /proc/scsi/advansys/[0...].
17846 */
17847 if (ASC_NARROW_BOARD(boardp)) {
17848
17849 ASCEEP_CONFIG *ep;
17850
17851 /*
17852 * Set the adapter's target id bit in the 'init_tidmask' field.
17853 */
17854 boardp->init_tidmask |=
17855 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
17856
17857 /*
17858 * Save EEPROM settings for the board.
17859 */
17860 ep = &boardp->eep_config.asc_eep;
17861
17862 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
17863 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
17864 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
17865 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
17866 ep->start_motor = asc_dvc_varp->start_motor;
17867 ep->cntl = asc_dvc_varp->dvc_cntl;
17868 ep->no_scam = asc_dvc_varp->no_scam;
17869 ep->max_total_qng = asc_dvc_varp->max_total_qng;
17870 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
17871 /* 'max_tag_qng' is set to the same value for every device. */
17872 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
17873 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
17874 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
17875 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
17876 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
17877 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
17878 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
17879
17880 /*
17881 * Modify board configuration.
17882 */
17883 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
17884 switch (ret = AscInitSetConfig(asc_dvc_varp)) {
17885 case 0: /* No error. */
17886 break;
17887 case ASC_WARN_IO_PORT_ROTATE:
17888 ASC_PRINT1
17889 ("AscInitSetConfig: board %d: I/O port address modified\n",
17890 boardp->id);
17891 break;
17892 case ASC_WARN_AUTO_CONFIG:
17893 ASC_PRINT1
17894 ("AscInitSetConfig: board %d: I/O port increment switch enabled\n",
17895 boardp->id);
17896 break;
17897 case ASC_WARN_EEPROM_CHKSUM:
17898 ASC_PRINT1
17899 ("AscInitSetConfig: board %d: EEPROM checksum error\n",
17900 boardp->id);
17901 break;
17902 case ASC_WARN_IRQ_MODIFIED:
17903 ASC_PRINT1
17904 ("AscInitSetConfig: board %d: IRQ modified\n",
17905 boardp->id);
17906 break;
17907 case ASC_WARN_CMD_QNG_CONFLICT:
17908 ASC_PRINT1
17909 ("AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
17910 boardp->id);
17911 break;
17912 default:
17913 ASC_PRINT2
17914 ("AscInitSetConfig: board %d: unknown warning: 0x%x\n",
17915 boardp->id, ret);
17916 break;
17917 }
17918 if (asc_dvc_varp->err_code != 0) {
17919 ASC_PRINT3
17920 ("AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
17921 boardp->id,
17922 asc_dvc_varp->init_state, asc_dvc_varp->err_code);
b2c16f58 17923 goto err_free_proc;
27c868c2
MW
17924 }
17925
17926 /*
17927 * Finish initializing the 'Scsi_Host' structure.
17928 */
17929 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
17930 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
17931 shost->irq = asc_dvc_varp->irq_no;
17932 }
17933 } else {
17934 ADVEEP_3550_CONFIG *ep_3550;
17935 ADVEEP_38C0800_CONFIG *ep_38C0800;
17936 ADVEEP_38C1600_CONFIG *ep_38C1600;
17937
17938 /*
17939 * Save Wide EEP Configuration Information.
17940 */
17941 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17942 ep_3550 = &boardp->eep_config.adv_3550_eep;
17943
17944 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
17945 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
17946 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17947 ep_3550->termination = adv_dvc_varp->cfg->termination;
17948 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
17949 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
17950 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
17951 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
17952 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
17953 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
17954 ep_3550->start_motor = adv_dvc_varp->start_motor;
17955 ep_3550->scsi_reset_delay =
17956 adv_dvc_varp->scsi_reset_wait;
17957 ep_3550->serial_number_word1 =
17958 adv_dvc_varp->cfg->serial1;
17959 ep_3550->serial_number_word2 =
17960 adv_dvc_varp->cfg->serial2;
17961 ep_3550->serial_number_word3 =
17962 adv_dvc_varp->cfg->serial3;
17963 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17964 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
17965
17966 ep_38C0800->adapter_scsi_id =
17967 adv_dvc_varp->chip_scsi_id;
17968 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
17969 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17970 ep_38C0800->termination_lvd =
17971 adv_dvc_varp->cfg->termination;
17972 ep_38C0800->disc_enable =
17973 adv_dvc_varp->cfg->disc_enable;
17974 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
17975 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
17976 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
17977 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
17978 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
17979 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
17980 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
17981 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
17982 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
17983 ep_38C0800->scsi_reset_delay =
17984 adv_dvc_varp->scsi_reset_wait;
17985 ep_38C0800->serial_number_word1 =
17986 adv_dvc_varp->cfg->serial1;
17987 ep_38C0800->serial_number_word2 =
17988 adv_dvc_varp->cfg->serial2;
17989 ep_38C0800->serial_number_word3 =
17990 adv_dvc_varp->cfg->serial3;
17991 } else {
17992 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
17993
17994 ep_38C1600->adapter_scsi_id =
17995 adv_dvc_varp->chip_scsi_id;
17996 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
17997 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17998 ep_38C1600->termination_lvd =
17999 adv_dvc_varp->cfg->termination;
18000 ep_38C1600->disc_enable =
18001 adv_dvc_varp->cfg->disc_enable;
18002 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
18003 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
18004 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
18005 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
18006 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
18007 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
18008 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
18009 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
18010 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
18011 ep_38C1600->scsi_reset_delay =
18012 adv_dvc_varp->scsi_reset_wait;
18013 ep_38C1600->serial_number_word1 =
18014 adv_dvc_varp->cfg->serial1;
18015 ep_38C1600->serial_number_word2 =
18016 adv_dvc_varp->cfg->serial2;
18017 ep_38C1600->serial_number_word3 =
18018 adv_dvc_varp->cfg->serial3;
18019 }
18020
18021 /*
18022 * Set the adapter's target id bit in the 'init_tidmask' field.
18023 */
18024 boardp->init_tidmask |=
18025 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
18026
18027 /*
18028 * Finish initializing the 'Scsi_Host' structure.
18029 */
18030 shost->irq = adv_dvc_varp->irq_no;
18031 }
18032
18033 /*
18034 * Channels are numbered beginning with 0. For AdvanSys one host
18035 * structure supports one channel. Multi-channel boards have a
18036 * separate host structure for each channel.
18037 */
18038 shost->max_channel = 0;
18039 if (ASC_NARROW_BOARD(boardp)) {
18040 shost->max_id = ASC_MAX_TID + 1;
18041 shost->max_lun = ASC_MAX_LUN + 1;
18042
18043 shost->io_port = asc_dvc_varp->iop_base;
18044 boardp->asc_n_io_port = ASC_IOADR_GAP;
18045 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
18046
18047 /* Set maximum number of queues the adapter can handle. */
18048 shost->can_queue = asc_dvc_varp->max_total_qng;
18049 } else {
18050 shost->max_id = ADV_MAX_TID + 1;
18051 shost->max_lun = ADV_MAX_LUN + 1;
18052
18053 /*
18054 * Save the I/O Port address and length even though
18055 * I/O ports are not used to access Wide boards.
18056 * Instead the Wide boards are accessed with
18057 * PCI Memory Mapped I/O.
18058 */
18059 shost->io_port = iop;
18060 boardp->asc_n_io_port = iolen;
18061
18062 shost->this_id = adv_dvc_varp->chip_scsi_id;
18063
18064 /* Set maximum number of queues the adapter can handle. */
18065 shost->can_queue = adv_dvc_varp->max_host_qng;
18066 }
18067
18068 /*
18069 * 'n_io_port' currently is one byte.
18070 *
18071 * Set a value to 'n_io_port', but never referenced it because
18072 * it may be truncated.
18073 */
18074 shost->n_io_port = boardp->asc_n_io_port <= 255 ?
18075 boardp->asc_n_io_port : 255;
18076
18077 /*
18078 * Following v1.3.89, 'cmd_per_lun' is no longer needed
18079 * and should be set to zero.
18080 *
18081 * But because of a bug introduced in v1.3.89 if the driver is
18082 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
18083 * SCSI function 'allocate_device' will panic. To allow the driver
18084 * to work as a module in these kernels set 'cmd_per_lun' to 1.
18085 *
18086 * Note: This is wrong. cmd_per_lun should be set to the depth
18087 * you want on untagged devices always.
18088 #ifdef MODULE
18089 */
18090 shost->cmd_per_lun = 1;
18091/* #else
18092 shost->cmd_per_lun = 0;
18093#endif */
18094
18095 /*
18096 * Set the maximum number of scatter-gather elements the
18097 * adapter can handle.
18098 */
18099 if (ASC_NARROW_BOARD(boardp)) {
18100 /*
18101 * Allow two commands with 'sg_tablesize' scatter-gather
18102 * elements to be executed simultaneously. This value is
18103 * the theoretical hardware limit. It may be decreased
18104 * below.
18105 */
18106 shost->sg_tablesize =
18107 (((asc_dvc_varp->max_total_qng - 2) / 2) *
18108 ASC_SG_LIST_PER_Q) + 1;
18109 } else {
18110 shost->sg_tablesize = ADV_MAX_SG_LIST;
18111 }
18112
18113 /*
18114 * The value of 'sg_tablesize' can not exceed the SCSI
18115 * mid-level driver definition of SG_ALL. SG_ALL also
18116 * must not be exceeded, because it is used to define the
18117 * size of the scatter-gather table in 'struct asc_sg_head'.
18118 */
18119 if (shost->sg_tablesize > SG_ALL) {
18120 shost->sg_tablesize = SG_ALL;
18121 }
18122
18123 ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize);
18124
18125 /* BIOS start address. */
18126 if (ASC_NARROW_BOARD(boardp)) {
b2c16f58
MW
18127 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
18128 asc_dvc_varp->bus_type);
27c868c2
MW
18129 } else {
18130 /*
18131 * Fill-in BIOS board variables. The Wide BIOS saves
18132 * information in LRAM that is used by the driver.
18133 */
18134 AdvReadWordLram(adv_dvc_varp->iop_base,
18135 BIOS_SIGNATURE, boardp->bios_signature);
18136 AdvReadWordLram(adv_dvc_varp->iop_base,
18137 BIOS_VERSION, boardp->bios_version);
18138 AdvReadWordLram(adv_dvc_varp->iop_base,
18139 BIOS_CODESEG, boardp->bios_codeseg);
18140 AdvReadWordLram(adv_dvc_varp->iop_base,
18141 BIOS_CODELEN, boardp->bios_codelen);
18142
18143 ASC_DBG2(1,
18144 "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n",
18145 boardp->bios_signature, boardp->bios_version);
18146
18147 ASC_DBG2(1,
18148 "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n",
18149 boardp->bios_codeseg, boardp->bios_codelen);
18150
18151 /*
18152 * If the BIOS saved a valid signature, then fill in
18153 * the BIOS code segment base address.
18154 */
18155 if (boardp->bios_signature == 0x55AA) {
18156 /*
18157 * Convert x86 realmode code segment to a linear
18158 * address by shifting left 4.
18159 */
18160 shost->base = ((ulong)boardp->bios_codeseg << 4);
18161 } else {
18162 shost->base = 0;
18163 }
18164 }
18165
18166 /*
18167 * Register Board Resources - I/O Port, DMA, IRQ
18168 */
18169
27c868c2
MW
18170 /* Register DMA Channel for Narrow boards. */
18171 shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
18172#ifdef CONFIG_ISA
18173 if (ASC_NARROW_BOARD(boardp)) {
18174 /* Register DMA channel for ISA bus. */
18175 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
18176 shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
b2c16f58
MW
18177 ret = request_dma(shost->dma_channel, "advansys");
18178 if (ret) {
27c868c2
MW
18179 ASC_PRINT3
18180 ("advansys_board_found: board %d: request_dma() %d failed %d\n",
18181 boardp->id, shost->dma_channel, ret);
71f36115 18182 goto err_free_proc;
27c868c2
MW
18183 }
18184 AscEnableIsaDma(shost->dma_channel);
18185 }
18186 }
18187#endif /* CONFIG_ISA */
18188
18189 /* Register IRQ Number. */
18190 ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq);
074c8fe4
MW
18191
18192 ret = request_irq(shost->irq, advansys_interrupt, share_irq,
18193 "advansys", shost);
18194
18195 if (ret) {
27c868c2
MW
18196 if (ret == -EBUSY) {
18197 ASC_PRINT2
18198 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
18199 boardp->id, shost->irq);
18200 } else if (ret == -EINVAL) {
18201 ASC_PRINT2
18202 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
18203 boardp->id, shost->irq);
18204 } else {
18205 ASC_PRINT3
18206 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
18207 boardp->id, shost->irq, ret);
18208 }
b2c16f58 18209 goto err_free_dma;
27c868c2
MW
18210 }
18211
18212 /*
18213 * Initialize board RISC chip and enable interrupts.
18214 */
18215 if (ASC_NARROW_BOARD(boardp)) {
18216 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
18217 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
18218 err_code = asc_dvc_varp->err_code;
18219
18220 if (warn_code || err_code) {
18221 ASC_PRINT4
18222 ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
18223 boardp->id,
18224 asc_dvc_varp->init_state, warn_code, err_code);
18225 }
18226 } else {
b2c16f58 18227 err_code = advansys_wide_init_chip(boardp, adv_dvc_varp);
27c868c2
MW
18228 }
18229
b2c16f58
MW
18230 if (err_code != 0)
18231 goto err_free_wide_mem;
18232
27c868c2
MW
18233 ASC_DBG_PRT_SCSI_HOST(2, shost);
18234
8dfb5379
MW
18235 ret = scsi_add_host(shost, dev);
18236 if (ret)
18237 goto err_free_wide_mem;
18238
18239 scsi_scan_host(shost);
27c868c2 18240 return shost;
b2c16f58
MW
18241
18242 err_free_wide_mem:
18243 advansys_wide_free_mem(boardp);
18244 free_irq(shost->irq, shost);
18245 err_free_dma:
18246 if (shost->dma_channel != NO_ISA_DMA)
18247 free_dma(shost->dma_channel);
b2c16f58
MW
18248 err_free_proc:
18249 kfree(boardp->prtbuf);
18250 err_unmap:
18251 if (boardp->ioremap_addr)
18252 iounmap(boardp->ioremap_addr);
18253 err_shost:
8dfb5379 18254 scsi_host_put(shost);
b2c16f58 18255 return NULL;
27c868c2
MW
18256}
18257
27c868c2
MW
18258/*
18259 * advansys_release()
18260 *
18261 * Release resources allocated for a single AdvanSys adapter.
18262 */
18263static int advansys_release(struct Scsi_Host *shost)
18264{
18265 asc_board_t *boardp;
18266
18267 ASC_DBG(1, "advansys_release: begin\n");
8dfb5379 18268 scsi_remove_host(shost);
27c868c2 18269 boardp = ASC_BOARDP(shost);
074c8fe4 18270 free_irq(shost->irq, shost);
27c868c2
MW
18271 if (shost->dma_channel != NO_ISA_DMA) {
18272 ASC_DBG(1, "advansys_release: free_dma()\n");
18273 free_dma(shost->dma_channel);
18274 }
27c868c2 18275 if (ASC_WIDE_BOARD(boardp)) {
27c868c2 18276 iounmap(boardp->ioremap_addr);
b2c16f58 18277 advansys_wide_free_mem(boardp);
27c868c2 18278 }
27c868c2 18279 kfree(boardp->prtbuf);
8dfb5379 18280 scsi_host_put(shost);
27c868c2
MW
18281 ASC_DBG(1, "advansys_release: end\n");
18282 return 0;
18283}
18284
c304ec94
MW
18285static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
18286 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
18287 0x0210, 0x0230, 0x0250, 0x0330
18288};
18289
18290static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
18291{
18292 PortAddr iop_base = _asc_def_iop_base[id];
18293 struct Scsi_Host *shost;
18294
18295 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
71f36115
MW
18296 ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n",
18297 iop_base);
c304ec94
MW
18298 return -ENODEV;
18299 }
18300 ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base);
c304ec94
MW
18301 if (!AscFindSignature(iop_base))
18302 goto nodev;
18303 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
18304 goto nodev;
18305
18306 shost = advansys_board_found(iop_base, dev, ASC_IS_ISA);
c304ec94
MW
18307 if (!shost)
18308 goto nodev;
18309
18310 dev_set_drvdata(dev, shost);
18311 return 0;
18312
18313 nodev:
71f36115 18314 release_region(iop_base, ASC_IOADR_GAP);
c304ec94
MW
18315 return -ENODEV;
18316}
18317
18318static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
18319{
71f36115 18320 int ioport = _asc_def_iop_base[id];
c304ec94 18321 advansys_release(dev_get_drvdata(dev));
71f36115 18322 release_region(ioport, ASC_IOADR_GAP);
c304ec94
MW
18323 return 0;
18324}
18325
18326static struct isa_driver advansys_isa_driver = {
18327 .probe = advansys_isa_probe,
18328 .remove = __devexit_p(advansys_isa_remove),
18329 .driver = {
18330 .owner = THIS_MODULE,
18331 .name = "advansys",
18332 },
18333};
18334
18335static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
18336{
18337 PortAddr iop_base = _asc_def_iop_base[id];
18338 struct Scsi_Host *shost;
18339
18340 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
71f36115
MW
18341 ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n",
18342 iop_base);
c304ec94
MW
18343 return -ENODEV;
18344 }
18345 ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base);
c304ec94
MW
18346 if (!AscFindSignature(iop_base))
18347 goto nodev;
18348 /*
18349 * I don't think this condition can actually happen, but the old
18350 * driver did it, and the chances of finding a VLB setup in 2007
18351 * to do testing with is slight to none.
18352 */
18353 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
18354 goto nodev;
18355
18356 shost = advansys_board_found(iop_base, dev, ASC_IS_VL);
c304ec94
MW
18357 if (!shost)
18358 goto nodev;
18359
18360 dev_set_drvdata(dev, shost);
18361 return 0;
18362
18363 nodev:
71f36115 18364 release_region(iop_base, ASC_IOADR_GAP);
c304ec94
MW
18365 return -ENODEV;
18366}
18367
18368static struct isa_driver advansys_vlb_driver = {
18369 .probe = advansys_vlb_probe,
18370 .remove = __devexit_p(advansys_isa_remove),
18371 .driver = {
18372 .owner = THIS_MODULE,
18373 .name = "advansys",
18374 },
18375};
18376
b09e05a7
MW
18377static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
18378 { "ABP7401" },
18379 { "ABP7501" },
18380 { "" }
18381};
18382
18383MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
18384
18385/*
18386 * EISA is a little more tricky than PCI; each EISA device may have two
18387 * channels, and this driver is written to make each channel its own Scsi_Host
18388 */
18389struct eisa_scsi_data {
18390 struct Scsi_Host *host[2];
18391};
18392
18393static int __devinit advansys_eisa_probe(struct device *dev)
18394{
18395 int i, ioport;
18396 int err;
18397 struct eisa_device *edev = to_eisa_device(dev);
18398 struct eisa_scsi_data *data;
18399
18400 err = -ENOMEM;
18401 data = kzalloc(sizeof(*data), GFP_KERNEL);
18402 if (!data)
18403 goto fail;
18404 ioport = edev->base_addr + 0xc30;
18405
18406 err = -ENODEV;
18407 for (i = 0; i < 2; i++, ioport += 0x20) {
71f36115
MW
18408 if (!request_region(ioport, ASC_IOADR_GAP, "advansys")) {
18409 printk(KERN_WARNING "Region %x-%x busy\n", ioport,
18410 ioport + ASC_IOADR_GAP - 1);
18411 continue;
18412 }
18413 if (!AscFindSignature(ioport)) {
18414 release_region(ioport, ASC_IOADR_GAP);
b09e05a7 18415 continue;
71f36115
MW
18416 }
18417
b09e05a7
MW
18418 /*
18419 * I don't know why we need to do this for EISA chips, but
18420 * not for any others. It looks to be equivalent to
18421 * AscGetChipCfgMsw, but I may have overlooked something,
18422 * so I'm not converting it until I get an EISA board to
18423 * test with.
18424 */
18425 inw(ioport + 4);
18426 data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA);
71f36115 18427 if (data->host[i]) {
b09e05a7 18428 err = 0;
71f36115
MW
18429 } else {
18430 release_region(ioport, ASC_IOADR_GAP);
18431 }
b09e05a7
MW
18432 }
18433
18434 if (err) {
18435 kfree(data);
18436 } else {
18437 dev_set_drvdata(dev, data);
18438 }
18439
18440 fail:
18441 return err;
18442}
18443
18444static __devexit int advansys_eisa_remove(struct device *dev)
18445{
18446 int i;
18447 struct eisa_scsi_data *data = dev_get_drvdata(dev);
18448
18449 for (i = 0; i < 2; i++) {
71f36115 18450 int ioport;
b09e05a7
MW
18451 struct Scsi_Host *shost = data->host[i];
18452 if (!shost)
18453 continue;
71f36115 18454 ioport = shost->io_port;
b09e05a7 18455 advansys_release(shost);
71f36115 18456 release_region(ioport, ASC_IOADR_GAP);
b09e05a7
MW
18457 }
18458
18459 kfree(data);
18460 return 0;
18461}
18462
18463static struct eisa_driver advansys_eisa_driver = {
18464 .id_table = advansys_eisa_table,
18465 .driver = {
18466 .name = "advansys",
18467 .probe = advansys_eisa_probe,
18468 .remove = __devexit_p(advansys_eisa_remove),
18469 }
18470};
18471
2672ea86
DJ
18472/* PCI Devices supported by this driver */
18473static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
27c868c2
MW
18474 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
18475 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18476 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
18477 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18478 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
18479 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18480 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
18481 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18482 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
18483 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18484 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
18485 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18486 {}
2672ea86 18487};
27c868c2 18488
2672ea86 18489MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
78e77d8b
MW
18490
18491static int __devinit
18492advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
18493{
18494 int err, ioport;
18495 struct Scsi_Host *shost;
18496
18497 err = pci_enable_device(pdev);
18498 if (err)
18499 goto fail;
71f36115
MW
18500 err = pci_request_regions(pdev, "advansys");
18501 if (err)
18502 goto disable_device;
78e77d8b
MW
18503
18504 if (pci_resource_len(pdev, 0) == 0)
18505 goto nodev;
18506
18507 ioport = pci_resource_start(pdev, 0);
18508 shost = advansys_board_found(ioport, &pdev->dev, ASC_IS_PCI);
18509
18510 if (!shost)
18511 goto nodev;
18512
18513 pci_set_drvdata(pdev, shost);
18514 return 0;
18515
18516 nodev:
18517 err = -ENODEV;
71f36115
MW
18518 pci_release_regions(pdev);
18519 disable_device:
78e77d8b
MW
18520 pci_disable_device(pdev);
18521 fail:
18522 return err;
18523}
18524
18525static void __devexit advansys_pci_remove(struct pci_dev *pdev)
18526{
18527 advansys_release(pci_get_drvdata(pdev));
71f36115 18528 pci_release_regions(pdev);
78e77d8b
MW
18529 pci_disable_device(pdev);
18530}
18531
18532static struct pci_driver advansys_pci_driver = {
18533 .name = "advansys",
18534 .id_table = advansys_pci_tbl,
18535 .probe = advansys_pci_probe,
18536 .remove = __devexit_p(advansys_pci_remove),
18537};
8c6af9e1 18538
8dfb5379
MW
18539static int __init advansys_init(void)
18540{
c304ec94 18541 int error;
b09e05a7 18542
c304ec94
MW
18543 error = isa_register_driver(&advansys_isa_driver,
18544 ASC_IOADR_TABLE_MAX_IX);
78e77d8b
MW
18545 if (error)
18546 goto fail;
8dfb5379 18547
c304ec94
MW
18548 error = isa_register_driver(&advansys_vlb_driver,
18549 ASC_IOADR_TABLE_MAX_IX);
18550 if (error)
18551 goto unregister_isa;
18552
18553 error = eisa_driver_register(&advansys_eisa_driver);
18554 if (error)
18555 goto unregister_vlb;
18556
b09e05a7
MW
18557 error = pci_register_driver(&advansys_pci_driver);
18558 if (error)
18559 goto unregister_eisa;
18560
8dfb5379 18561 return 0;
78e77d8b 18562
b09e05a7
MW
18563 unregister_eisa:
18564 eisa_driver_unregister(&advansys_eisa_driver);
c304ec94
MW
18565 unregister_vlb:
18566 isa_unregister_driver(&advansys_vlb_driver);
18567 unregister_isa:
18568 isa_unregister_driver(&advansys_isa_driver);
78e77d8b 18569 fail:
78e77d8b 18570 return error;
8dfb5379
MW
18571}
18572
18573static void __exit advansys_exit(void)
18574{
78e77d8b 18575 pci_unregister_driver(&advansys_pci_driver);
b09e05a7 18576 eisa_driver_unregister(&advansys_eisa_driver);
c304ec94
MW
18577 isa_unregister_driver(&advansys_vlb_driver);
18578 isa_unregister_driver(&advansys_isa_driver);
8dfb5379
MW
18579}
18580
18581module_init(advansys_init);
18582module_exit(advansys_exit);
18583
8c6af9e1 18584MODULE_LICENSE("GPL");