]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/scsi/advansys.c
[SCSI] advansys: Move to scsi hotplug initialisation model
[mirror_ubuntu-bionic-kernel.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
283 /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
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>
8c6af9e1 772#include <linux/pci.h>
1da177e4
LT
773#include <linux/spinlock.h>
774#include <linux/dma-mapping.h>
775
776#include <asm/io.h>
777#include <asm/system.h>
778#include <asm/dma.h>
779
8c6af9e1
MW
780#include <scsi/scsi_cmnd.h>
781#include <scsi/scsi_device.h>
782#include <scsi/scsi_tcq.h>
783#include <scsi/scsi.h>
784#include <scsi/scsi_host.h>
785
1da177e4
LT
786/* FIXME: (by jejb@steeleye.com) This warning is present for two
787 * reasons:
788 *
789 * 1) This driver badly needs converting to the correct driver model
790 * probing API
791 *
792 * 2) Although all of the necessary command mapping places have the
793 * appropriate dma_map.. APIs, the driver still processes its internal
794 * queue using bus_to_virt() and virt_to_bus() which are illegal under
795 * the API. The entire queue processing structure will need to be
796 * altered to fix this.
797 */
798#warning this driver is still not properly converted to the DMA API
799
1da177e4
LT
800/*
801 * --- Driver Options
802 */
803
804/* Enable driver assertions. */
805#define ADVANSYS_ASSERT
806
807/* Enable driver /proc statistics. */
808#define ADVANSYS_STATS
809
810/* Enable driver tracing. */
811/* #define ADVANSYS_DEBUG */
812
1da177e4
LT
813/*
814 * --- Asc Library Constants and Macros
815 */
816
817#define ASC_LIB_VERSION_MAJOR 1
818#define ASC_LIB_VERSION_MINOR 24
819#define ASC_LIB_SERIAL_NUMBER 123
820
821/*
822 * Portable Data Types
823 *
824 * Any instance where a 32-bit long or pointer type is assumed
825 * for precision or HW defined structures, the following define
826 * types must be used. In Linux the char, short, and int types
827 * are all consistent at 8, 16, and 32 bits respectively. Pointers
828 * and long types are 64 bits on Alpha and UltraSPARC.
829 */
27c868c2
MW
830#define ASC_PADDR __u32 /* Physical/Bus address data type. */
831#define ASC_VADDR __u32 /* Virtual address data type. */
832#define ASC_DCNT __u32 /* Unsigned Data count type. */
833#define ASC_SDCNT __s32 /* Signed Data count type. */
1da177e4
LT
834
835/*
836 * These macros are used to convert a virtual address to a
837 * 32-bit value. This currently can be used on Linux Alpha
838 * which uses 64-bit virtual address but a 32-bit bus address.
839 * This is likely to break in the future, but doing this now
840 * will give us time to change the HW and FW to handle 64-bit
841 * addresses.
842 */
843#define ASC_VADDR_TO_U32 virt_to_bus
844#define ASC_U32_TO_VADDR bus_to_virt
845
846typedef unsigned char uchar;
847
848#ifndef TRUE
849#define TRUE (1)
850#endif
851#ifndef FALSE
852#define FALSE (0)
853#endif
854
855#define EOF (-1)
856#define ERR (-1)
857#define UW_ERR (uint)(0xFFFF)
858#define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
859#define AscPCIConfigVendorIDRegister 0x0000
860#define AscPCIConfigDeviceIDRegister 0x0002
861#define AscPCIConfigCommandRegister 0x0004
862#define AscPCIConfigStatusRegister 0x0006
863#define AscPCIConfigRevisionIDRegister 0x0008
864#define AscPCIConfigCacheSize 0x000C
865#define AscPCIConfigLatencyTimer 0x000D
866#define AscPCIIOBaseRegister 0x0010
867#define AscPCICmdRegBits_IOMemBusMaster 0x0007
868#define ASC_PCI_ID2BUS(id) ((id) & 0xFF)
869#define ASC_PCI_ID2DEV(id) (((id) >> 11) & 0x1F)
870#define ASC_PCI_ID2FUNC(id) (((id) >> 8) & 0x7)
871#define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
1da177e4
LT
872#define ASC_PCI_REVISION_3150 0x02
873#define ASC_PCI_REVISION_3050 0x03
874
875#define ASC_DVCLIB_CALL_DONE (1)
876#define ASC_DVCLIB_CALL_FAILED (0)
877#define ASC_DVCLIB_CALL_ERROR (-1)
878
2672ea86
DJ
879#define PCI_VENDOR_ID_ASP 0x10cd
880#define PCI_DEVICE_ID_ASP_1200A 0x1100
881#define PCI_DEVICE_ID_ASP_ABP940 0x1200
882#define PCI_DEVICE_ID_ASP_ABP940U 0x1300
883#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
884#define PCI_DEVICE_ID_38C0800_REV1 0x2500
885#define PCI_DEVICE_ID_38C1600_REV1 0x2700
886
1da177e4
LT
887/*
888 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
889 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
890 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
891 * SRB structure.
892 */
893#define CC_VERY_LONG_SG_LIST 0
894#define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
895
27c868c2 896#define PortAddr unsigned short /* port address size */
1da177e4
LT
897#define inp(port) inb(port)
898#define outp(port, byte) outb((byte), (port))
899
900#define inpw(port) inw(port)
901#define outpw(port, word) outw((word), (port))
902
903#define ASC_MAX_SG_QUEUE 7
904#define ASC_MAX_SG_LIST 255
905
906#define ASC_CS_TYPE unsigned short
907
908#define ASC_IS_ISA (0x0001)
909#define ASC_IS_ISAPNP (0x0081)
910#define ASC_IS_EISA (0x0002)
911#define ASC_IS_PCI (0x0004)
912#define ASC_IS_PCI_ULTRA (0x0104)
913#define ASC_IS_PCMCIA (0x0008)
914#define ASC_IS_MCA (0x0020)
915#define ASC_IS_VL (0x0040)
916#define ASC_ISA_PNP_PORT_ADDR (0x279)
917#define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
918#define ASC_IS_WIDESCSI_16 (0x0100)
919#define ASC_IS_WIDESCSI_32 (0x0200)
920#define ASC_IS_BIG_ENDIAN (0x8000)
921#define ASC_CHIP_MIN_VER_VL (0x01)
922#define ASC_CHIP_MAX_VER_VL (0x07)
923#define ASC_CHIP_MIN_VER_PCI (0x09)
924#define ASC_CHIP_MAX_VER_PCI (0x0F)
925#define ASC_CHIP_VER_PCI_BIT (0x08)
926#define ASC_CHIP_MIN_VER_ISA (0x11)
927#define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
928#define ASC_CHIP_MAX_VER_ISA (0x27)
929#define ASC_CHIP_VER_ISA_BIT (0x30)
930#define ASC_CHIP_VER_ISAPNP_BIT (0x20)
931#define ASC_CHIP_VER_ASYN_BUG (0x21)
932#define ASC_CHIP_VER_PCI 0x08
933#define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
934#define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
935#define ASC_CHIP_MIN_VER_EISA (0x41)
936#define ASC_CHIP_MAX_VER_EISA (0x47)
937#define ASC_CHIP_VER_EISA_BIT (0x40)
938#define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
939#define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER 0x21
940#define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER 0x0A
941#define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL)
942#define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
943#define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL)
944#define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
945#define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL)
946#define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
947#define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL)
948#define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL)
949
950#define ASC_SCSI_ID_BITS 3
951#define ASC_SCSI_TIX_TYPE uchar
952#define ASC_ALL_DEVICE_BIT_SET 0xFF
953#define ASC_SCSI_BIT_ID_TYPE uchar
954#define ASC_MAX_TID 7
955#define ASC_MAX_LUN 7
956#define ASC_SCSI_WIDTH_BIT_SET 0xFF
957#define ASC_MAX_SENSE_LEN 32
958#define ASC_MIN_SENSE_LEN 14
959#define ASC_MAX_CDB_LEN 12
960#define ASC_SCSI_RESET_HOLD_TIME_US 60
961
962#define ADV_INQ_CLOCKING_ST_ONLY 0x0
963#define ADV_INQ_CLOCKING_DT_ONLY 0x1
964#define ADV_INQ_CLOCKING_ST_AND_DT 0x3
965
966/*
967 * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
968 * and CmdDt (Command Support Data) field bit definitions.
969 */
970#define ADV_INQ_RTN_VPD_AND_CMDDT 0x3
971#define ADV_INQ_RTN_CMDDT_FOR_OP_CODE 0x2
972#define ADV_INQ_RTN_VPD_FOR_PG_CODE 0x1
973#define ADV_INQ_RTN_STD_INQUIRY_DATA 0x0
974
975#define ASC_SCSIDIR_NOCHK 0x00
976#define ASC_SCSIDIR_T2H 0x08
977#define ASC_SCSIDIR_H2T 0x10
978#define ASC_SCSIDIR_NODATA 0x18
979#define SCSI_ASC_NOMEDIA 0x3A
980#define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4))
981#define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F))
982#define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13))
983#define PUT_CDB1(x) ((uchar)((uint)(x) >> 8))
984#define MS_CMD_DONE 0x00
985#define MS_EXTEND 0x01
986#define MS_SDTR_LEN 0x03
987#define MS_SDTR_CODE 0x01
988#define MS_WDTR_LEN 0x02
989#define MS_WDTR_CODE 0x03
990#define MS_MDP_LEN 0x05
991#define MS_MDP_CODE 0x00
992
993/*
994 * Inquiry data structure and bitfield macros
995 *
996 * Only quantities of more than 1 bit are shifted, since the others are
997 * just tested for true or false. C bitfields aren't portable between big
998 * and little-endian platforms so they are not used.
999 */
1000
1001#define ASC_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f)
1002#define ASC_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5)
1003#define ASC_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f)
1004#define ASC_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80)
1005#define ASC_INQ_ANSI_VER(inq) ((inq)->ver & 0x07)
1006#define ASC_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3)
1007#define ASC_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6)
1008#define ASC_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f)
1009#define ASC_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40)
1010#define ASC_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80)
1011#define ASC_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01)
1012#define ASC_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02)
1013#define ASC_INQ_LINK_CMD(inq) ((inq)->flags & 0x08)
1014#define ASC_INQ_SYNC(inq) ((inq)->flags & 0x10)
1015#define ASC_INQ_WIDE16(inq) ((inq)->flags & 0x20)
1016#define ASC_INQ_WIDE32(inq) ((inq)->flags & 0x40)
1017#define ASC_INQ_REL_ADDR(inq) ((inq)->flags & 0x80)
1018#define ASC_INQ_INFO_UNIT(inq) ((inq)->info & 0x01)
1019#define ASC_INQ_QUICK_ARB(inq) ((inq)->info & 0x02)
1020#define ASC_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2)
1021
1022typedef struct {
27c868c2
MW
1023 uchar periph;
1024 uchar devtype;
1025 uchar ver;
1026 uchar byte3;
1027 uchar add_len;
1028 uchar res1;
1029 uchar res2;
1030 uchar flags;
1031 uchar vendor_id[8];
1032 uchar product_id[16];
1033 uchar product_rev_level[4];
1da177e4
LT
1034} ASC_SCSI_INQUIRY;
1035
1036#define ASC_SG_LIST_PER_Q 7
1037#define QS_FREE 0x00
1038#define QS_READY 0x01
1039#define QS_DISC1 0x02
1040#define QS_DISC2 0x04
1041#define QS_BUSY 0x08
1042#define QS_ABORTED 0x40
1043#define QS_DONE 0x80
1044#define QC_NO_CALLBACK 0x01
1045#define QC_SG_SWAP_QUEUE 0x02
1046#define QC_SG_HEAD 0x04
1047#define QC_DATA_IN 0x08
1048#define QC_DATA_OUT 0x10
1049#define QC_URGENT 0x20
1050#define QC_MSG_OUT 0x40
1051#define QC_REQ_SENSE 0x80
1052#define QCSG_SG_XFER_LIST 0x02
1053#define QCSG_SG_XFER_MORE 0x04
1054#define QCSG_SG_XFER_END 0x08
1055#define QD_IN_PROGRESS 0x00
1056#define QD_NO_ERROR 0x01
1057#define QD_ABORTED_BY_HOST 0x02
1058#define QD_WITH_ERROR 0x04
1059#define QD_INVALID_REQUEST 0x80
1060#define QD_INVALID_HOST_NUM 0x81
1061#define QD_INVALID_DEVICE 0x82
1062#define QD_ERR_INTERNAL 0xFF
1063#define QHSTA_NO_ERROR 0x00
1064#define QHSTA_M_SEL_TIMEOUT 0x11
1065#define QHSTA_M_DATA_OVER_RUN 0x12
1066#define QHSTA_M_DATA_UNDER_RUN 0x12
1067#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
1068#define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
1069#define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1070#define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
1071#define QHSTA_D_HOST_ABORT_FAILED 0x23
1072#define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
1073#define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1074#define QHSTA_D_ASPI_NO_BUF_POOL 0x26
1075#define QHSTA_M_WTM_TIMEOUT 0x41
1076#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
1077#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
1078#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1079#define QHSTA_M_TARGET_STATUS_BUSY 0x45
1080#define QHSTA_M_BAD_TAG_CODE 0x46
1081#define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
1082#define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1083#define QHSTA_D_LRAM_CMP_ERROR 0x81
1084#define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1085#define ASC_FLAG_SCSIQ_REQ 0x01
1086#define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
1087#define ASC_FLAG_BIOS_ASYNC_IO 0x04
1088#define ASC_FLAG_SRB_LINEAR_ADDR 0x08
1089#define ASC_FLAG_WIN16 0x10
1090#define ASC_FLAG_WIN32 0x20
1091#define ASC_FLAG_ISA_OVER_16MB 0x40
1092#define ASC_FLAG_DOS_VM_CALLBACK 0x80
1093#define ASC_TAG_FLAG_EXTRA_BYTES 0x10
1094#define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
1095#define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
1096#define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1097#define ASC_SCSIQ_CPY_BEG 4
1098#define ASC_SCSIQ_SGHD_CPY_BEG 2
1099#define ASC_SCSIQ_B_FWD 0
1100#define ASC_SCSIQ_B_BWD 1
1101#define ASC_SCSIQ_B_STATUS 2
1102#define ASC_SCSIQ_B_QNO 3
1103#define ASC_SCSIQ_B_CNTL 4
1104#define ASC_SCSIQ_B_SG_QUEUE_CNT 5
1105#define ASC_SCSIQ_D_DATA_ADDR 8
1106#define ASC_SCSIQ_D_DATA_CNT 12
1107#define ASC_SCSIQ_B_SENSE_LEN 20
1108#define ASC_SCSIQ_DONE_INFO_BEG 22
1109#define ASC_SCSIQ_D_SRBPTR 22
1110#define ASC_SCSIQ_B_TARGET_IX 26
1111#define ASC_SCSIQ_B_CDB_LEN 28
1112#define ASC_SCSIQ_B_TAG_CODE 29
1113#define ASC_SCSIQ_W_VM_ID 30
1114#define ASC_SCSIQ_DONE_STATUS 32
1115#define ASC_SCSIQ_HOST_STATUS 33
1116#define ASC_SCSIQ_SCSI_STATUS 34
1117#define ASC_SCSIQ_CDB_BEG 36
1118#define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1119#define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
1120#define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
1121#define ASC_SCSIQ_B_SG_WK_QP 49
1122#define ASC_SCSIQ_B_SG_WK_IX 50
1123#define ASC_SCSIQ_W_ALT_DC1 52
1124#define ASC_SCSIQ_B_LIST_CNT 6
1125#define ASC_SCSIQ_B_CUR_LIST_CNT 7
1126#define ASC_SGQ_B_SG_CNTL 4
1127#define ASC_SGQ_B_SG_HEAD_QP 5
1128#define ASC_SGQ_B_SG_LIST_CNT 6
1129#define ASC_SGQ_B_SG_CUR_LIST_CNT 7
1130#define ASC_SGQ_LIST_BEG 8
1131#define ASC_DEF_SCSI1_QNG 4
1132#define ASC_MAX_SCSI1_QNG 4
1133#define ASC_DEF_SCSI2_QNG 16
1134#define ASC_MAX_SCSI2_QNG 32
1135#define ASC_TAG_CODE_MASK 0x23
1136#define ASC_STOP_REQ_RISC_STOP 0x01
1137#define ASC_STOP_ACK_RISC_STOP 0x03
1138#define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
1139#define ASC_STOP_CLEAN_UP_DISC_Q 0x20
1140#define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1141#define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1142#define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1143#define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
1144#define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
1145#define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
1146#define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1147#define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
1148
1149typedef struct asc_scsiq_1 {
27c868c2
MW
1150 uchar status;
1151 uchar q_no;
1152 uchar cntl;
1153 uchar sg_queue_cnt;
1154 uchar target_id;
1155 uchar target_lun;
1156 ASC_PADDR data_addr;
1157 ASC_DCNT data_cnt;
1158 ASC_PADDR sense_addr;
1159 uchar sense_len;
1160 uchar extra_bytes;
1da177e4
LT
1161} ASC_SCSIQ_1;
1162
1163typedef struct asc_scsiq_2 {
27c868c2
MW
1164 ASC_VADDR srb_ptr;
1165 uchar target_ix;
1166 uchar flag;
1167 uchar cdb_len;
1168 uchar tag_code;
1169 ushort vm_id;
1da177e4
LT
1170} ASC_SCSIQ_2;
1171
1172typedef struct asc_scsiq_3 {
27c868c2
MW
1173 uchar done_stat;
1174 uchar host_stat;
1175 uchar scsi_stat;
1176 uchar scsi_msg;
1da177e4
LT
1177} ASC_SCSIQ_3;
1178
1179typedef struct asc_scsiq_4 {
27c868c2
MW
1180 uchar cdb[ASC_MAX_CDB_LEN];
1181 uchar y_first_sg_list_qp;
1182 uchar y_working_sg_qp;
1183 uchar y_working_sg_ix;
1184 uchar y_res;
1185 ushort x_req_count;
1186 ushort x_reconnect_rtn;
1187 ASC_PADDR x_saved_data_addr;
1188 ASC_DCNT x_saved_data_cnt;
1da177e4
LT
1189} ASC_SCSIQ_4;
1190
1191typedef struct asc_q_done_info {
27c868c2
MW
1192 ASC_SCSIQ_2 d2;
1193 ASC_SCSIQ_3 d3;
1194 uchar q_status;
1195 uchar q_no;
1196 uchar cntl;
1197 uchar sense_len;
1198 uchar extra_bytes;
1199 uchar res;
1200 ASC_DCNT remain_bytes;
1da177e4
LT
1201} ASC_QDONE_INFO;
1202
1203typedef struct asc_sg_list {
27c868c2
MW
1204 ASC_PADDR addr;
1205 ASC_DCNT bytes;
1da177e4
LT
1206} ASC_SG_LIST;
1207
1208typedef struct asc_sg_head {
27c868c2
MW
1209 ushort entry_cnt;
1210 ushort queue_cnt;
1211 ushort entry_to_copy;
1212 ushort res;
1213 ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1da177e4
LT
1214} ASC_SG_HEAD;
1215
1216#define ASC_MIN_SG_LIST 2
1217
1218typedef struct asc_min_sg_head {
27c868c2
MW
1219 ushort entry_cnt;
1220 ushort queue_cnt;
1221 ushort entry_to_copy;
1222 ushort res;
1223 ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
1da177e4
LT
1224} ASC_MIN_SG_HEAD;
1225
1226#define QCX_SORT (0x0001)
1227#define QCX_COALEASE (0x0002)
1228
1229typedef struct asc_scsi_q {
27c868c2
MW
1230 ASC_SCSIQ_1 q1;
1231 ASC_SCSIQ_2 q2;
1232 uchar *cdbptr;
1233 ASC_SG_HEAD *sg_head;
1234 ushort remain_sg_entry_cnt;
1235 ushort next_sg_index;
1da177e4
LT
1236} ASC_SCSI_Q;
1237
1238typedef struct asc_scsi_req_q {
27c868c2
MW
1239 ASC_SCSIQ_1 r1;
1240 ASC_SCSIQ_2 r2;
1241 uchar *cdbptr;
1242 ASC_SG_HEAD *sg_head;
1243 uchar *sense_ptr;
1244 ASC_SCSIQ_3 r3;
1245 uchar cdb[ASC_MAX_CDB_LEN];
1246 uchar sense[ASC_MIN_SENSE_LEN];
1da177e4
LT
1247} ASC_SCSI_REQ_Q;
1248
1249typedef struct asc_scsi_bios_req_q {
27c868c2
MW
1250 ASC_SCSIQ_1 r1;
1251 ASC_SCSIQ_2 r2;
1252 uchar *cdbptr;
1253 ASC_SG_HEAD *sg_head;
1254 uchar *sense_ptr;
1255 ASC_SCSIQ_3 r3;
1256 uchar cdb[ASC_MAX_CDB_LEN];
1257 uchar sense[ASC_MIN_SENSE_LEN];
1da177e4
LT
1258} ASC_SCSI_BIOS_REQ_Q;
1259
1260typedef struct asc_risc_q {
27c868c2
MW
1261 uchar fwd;
1262 uchar bwd;
1263 ASC_SCSIQ_1 i1;
1264 ASC_SCSIQ_2 i2;
1265 ASC_SCSIQ_3 i3;
1266 ASC_SCSIQ_4 i4;
1da177e4
LT
1267} ASC_RISC_Q;
1268
1269typedef struct asc_sg_list_q {
27c868c2
MW
1270 uchar seq_no;
1271 uchar q_no;
1272 uchar cntl;
1273 uchar sg_head_qp;
1274 uchar sg_list_cnt;
1275 uchar sg_cur_list_cnt;
1da177e4
LT
1276} ASC_SG_LIST_Q;
1277
1278typedef struct asc_risc_sg_list_q {
27c868c2
MW
1279 uchar fwd;
1280 uchar bwd;
1281 ASC_SG_LIST_Q sg;
1282 ASC_SG_LIST sg_list[7];
1da177e4
LT
1283} ASC_RISC_SG_LIST_Q;
1284
1285#define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL
1286#define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024
1287#define ASCQ_ERR_NO_ERROR 0
1288#define ASCQ_ERR_IO_NOT_FOUND 1
1289#define ASCQ_ERR_LOCAL_MEM 2
1290#define ASCQ_ERR_CHKSUM 3
1291#define ASCQ_ERR_START_CHIP 4
1292#define ASCQ_ERR_INT_TARGET_ID 5
1293#define ASCQ_ERR_INT_LOCAL_MEM 6
1294#define ASCQ_ERR_HALT_RISC 7
1295#define ASCQ_ERR_GET_ASPI_ENTRY 8
1296#define ASCQ_ERR_CLOSE_ASPI 9
1297#define ASCQ_ERR_HOST_INQUIRY 0x0A
1298#define ASCQ_ERR_SAVED_SRB_BAD 0x0B
1299#define ASCQ_ERR_QCNTL_SG_LIST 0x0C
1300#define ASCQ_ERR_Q_STATUS 0x0D
1301#define ASCQ_ERR_WR_SCSIQ 0x0E
1302#define ASCQ_ERR_PC_ADDR 0x0F
1303#define ASCQ_ERR_SYN_OFFSET 0x10
1304#define ASCQ_ERR_SYN_XFER_TIME 0x11
1305#define ASCQ_ERR_LOCK_DMA 0x12
1306#define ASCQ_ERR_UNLOCK_DMA 0x13
1307#define ASCQ_ERR_VDS_CHK_INSTALL 0x14
1308#define ASCQ_ERR_MICRO_CODE_HALT 0x15
1309#define ASCQ_ERR_SET_LRAM_ADDR 0x16
1310#define ASCQ_ERR_CUR_QNG 0x17
1311#define ASCQ_ERR_SG_Q_LINKS 0x18
1312#define ASCQ_ERR_SCSIQ_PTR 0x19
1313#define ASCQ_ERR_ISR_RE_ENTRY 0x1A
1314#define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
1315#define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
1316#define ASCQ_ERR_SG_LIST_ODD_ADDRESS 0x1D
1317#define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1318#define ASCQ_ERR_SCSIQ_NULL_PTR 0x1F
1319#define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR 0x20
1320#define ASCQ_ERR_GET_NUM_OF_FREE_Q 0x21
1321#define ASCQ_ERR_SEND_SCSI_Q 0x22
1322#define ASCQ_ERR_HOST_REQ_RISC_HALT 0x23
1323#define ASCQ_ERR_RESET_SDTR 0x24
1324
1325/*
1326 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
1327 */
1328#define ASC_WARN_NO_ERROR 0x0000
1329#define ASC_WARN_IO_PORT_ROTATE 0x0001
1330#define ASC_WARN_EEPROM_CHKSUM 0x0002
1331#define ASC_WARN_IRQ_MODIFIED 0x0004
1332#define ASC_WARN_AUTO_CONFIG 0x0008
1333#define ASC_WARN_CMD_QNG_CONFLICT 0x0010
1334#define ASC_WARN_EEPROM_RECOVER 0x0020
1335#define ASC_WARN_CFG_MSW_RECOVER 0x0040
1336#define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1337
1338/*
1339 * Error code values are set in ASC_DVC_VAR 'err_code'.
1340 */
1341#define ASC_IERR_WRITE_EEPROM 0x0001
1342#define ASC_IERR_MCODE_CHKSUM 0x0002
1343#define ASC_IERR_SET_PC_ADDR 0x0004
1344#define ASC_IERR_START_STOP_CHIP 0x0008
1345#define ASC_IERR_IRQ_NO 0x0010
1346#define ASC_IERR_SET_IRQ_NO 0x0020
1347#define ASC_IERR_CHIP_VERSION 0x0040
1348#define ASC_IERR_SET_SCSI_ID 0x0080
1349#define ASC_IERR_GET_PHY_ADDR 0x0100
1350#define ASC_IERR_BAD_SIGNATURE 0x0200
1351#define ASC_IERR_NO_BUS_TYPE 0x0400
1352#define ASC_IERR_SCAM 0x0800
1353#define ASC_IERR_SET_SDTR 0x1000
1354#define ASC_IERR_RW_LRAM 0x8000
1355
1356#define ASC_DEF_IRQ_NO 10
1357#define ASC_MAX_IRQ_NO 15
1358#define ASC_MIN_IRQ_NO 10
1359#define ASC_MIN_REMAIN_Q (0x02)
1360#define ASC_DEF_MAX_TOTAL_QNG (0xF0)
1361#define ASC_MIN_TAG_Q_PER_DVC (0x04)
1362#define ASC_DEF_TAG_Q_PER_DVC (0x04)
1363#define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q
1364#define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1365#define ASC_MAX_TOTAL_QNG 240
1366#define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1367#define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
1368#define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
1369#define ASC_MAX_INRAM_TAG_QNG 16
1370#define ASC_IOADR_TABLE_MAX_IX 11
1371#define ASC_IOADR_GAP 0x10
1372#define ASC_SEARCH_IOP_GAP 0x10
1373#define ASC_MIN_IOP_ADDR (PortAddr)0x0100
1374#define ASC_MAX_IOP_ADDR (PortAddr)0x3F0
1375#define ASC_IOADR_1 (PortAddr)0x0110
1376#define ASC_IOADR_2 (PortAddr)0x0130
1377#define ASC_IOADR_3 (PortAddr)0x0150
1378#define ASC_IOADR_4 (PortAddr)0x0190
1379#define ASC_IOADR_5 (PortAddr)0x0210
1380#define ASC_IOADR_6 (PortAddr)0x0230
1381#define ASC_IOADR_7 (PortAddr)0x0250
1382#define ASC_IOADR_8 (PortAddr)0x0330
1383#define ASC_IOADR_DEF ASC_IOADR_8
1384#define ASC_LIB_SCSIQ_WK_SP 256
1385#define ASC_MAX_SYN_XFER_NO 16
1386#define ASC_SYN_MAX_OFFSET 0x0F
1387#define ASC_DEF_SDTR_OFFSET 0x0F
1388#define ASC_DEF_SDTR_INDEX 0x00
1389#define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
1390#define SYN_XFER_NS_0 25
1391#define SYN_XFER_NS_1 30
1392#define SYN_XFER_NS_2 35
1393#define SYN_XFER_NS_3 40
1394#define SYN_XFER_NS_4 50
1395#define SYN_XFER_NS_5 60
1396#define SYN_XFER_NS_6 70
1397#define SYN_XFER_NS_7 85
1398#define SYN_ULTRA_XFER_NS_0 12
1399#define SYN_ULTRA_XFER_NS_1 19
1400#define SYN_ULTRA_XFER_NS_2 25
1401#define SYN_ULTRA_XFER_NS_3 32
1402#define SYN_ULTRA_XFER_NS_4 38
1403#define SYN_ULTRA_XFER_NS_5 44
1404#define SYN_ULTRA_XFER_NS_6 50
1405#define SYN_ULTRA_XFER_NS_7 57
1406#define SYN_ULTRA_XFER_NS_8 63
1407#define SYN_ULTRA_XFER_NS_9 69
1408#define SYN_ULTRA_XFER_NS_10 75
1409#define SYN_ULTRA_XFER_NS_11 82
1410#define SYN_ULTRA_XFER_NS_12 88
1411#define SYN_ULTRA_XFER_NS_13 94
1412#define SYN_ULTRA_XFER_NS_14 100
1413#define SYN_ULTRA_XFER_NS_15 107
1414
1415typedef struct ext_msg {
27c868c2
MW
1416 uchar msg_type;
1417 uchar msg_len;
1418 uchar msg_req;
1419 union {
1420 struct {
1421 uchar sdtr_xfer_period;
1422 uchar sdtr_req_ack_offset;
1423 } sdtr;
1424 struct {
1425 uchar wdtr_width;
1426 } wdtr;
1427 struct {
1428 uchar mdp_b3;
1429 uchar mdp_b2;
1430 uchar mdp_b1;
1431 uchar mdp_b0;
1432 } mdp;
1433 } u_ext_msg;
1434 uchar res;
1da177e4
LT
1435} EXT_MSG;
1436
1437#define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
1438#define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
1439#define wdtr_width u_ext_msg.wdtr.wdtr_width
1440#define mdp_b3 u_ext_msg.mdp_b3
1441#define mdp_b2 u_ext_msg.mdp_b2
1442#define mdp_b1 u_ext_msg.mdp_b1
1443#define mdp_b0 u_ext_msg.mdp_b0
1444
1445typedef struct asc_dvc_cfg {
27c868c2
MW
1446 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1447 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1448 ASC_SCSI_BIT_ID_TYPE disc_enable;
1449 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1450 uchar chip_scsi_id;
1451 uchar isa_dma_speed;
1452 uchar isa_dma_channel;
1453 uchar chip_version;
1454 ushort lib_serial_no;
1455 ushort lib_version;
1456 ushort mcode_date;
1457 ushort mcode_version;
1458 uchar max_tag_qng[ASC_MAX_TID + 1];
1459 uchar *overrun_buf;
1460 uchar sdtr_period_offset[ASC_MAX_TID + 1];
1461 ushort pci_slot_info;
1462 uchar adapter_info[6];
1463 struct device *dev;
1da177e4
LT
1464} ASC_DVC_CFG;
1465
1466#define ASC_DEF_DVC_CNTL 0xFFFF
1467#define ASC_DEF_CHIP_SCSI_ID 7
1468#define ASC_DEF_ISA_DMA_SPEED 4
1469#define ASC_INIT_STATE_NULL 0x0000
1470#define ASC_INIT_STATE_BEG_GET_CFG 0x0001
1471#define ASC_INIT_STATE_END_GET_CFG 0x0002
1472#define ASC_INIT_STATE_BEG_SET_CFG 0x0004
1473#define ASC_INIT_STATE_END_SET_CFG 0x0008
1474#define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
1475#define ASC_INIT_STATE_END_LOAD_MC 0x0020
1476#define ASC_INIT_STATE_BEG_INQUIRY 0x0040
1477#define ASC_INIT_STATE_END_INQUIRY 0x0080
1478#define ASC_INIT_RESET_SCSI_DONE 0x0100
1479#define ASC_INIT_STATE_WITHOUT_EEP 0x8000
1da177e4
LT
1480#define ASC_BUG_FIX_IF_NOT_DWB 0x0001
1481#define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
1482#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1483#define ASC_MIN_TAGGED_CMD 7
1484#define ASC_MAX_SCSI_RESET_WAIT 30
1485
27c868c2 1486struct asc_dvc_var; /* Forward Declaration. */
1da177e4 1487
27c868c2
MW
1488typedef void (*ASC_ISR_CALLBACK) (struct asc_dvc_var *, ASC_QDONE_INFO *);
1489typedef int (*ASC_EXE_CALLBACK) (struct asc_dvc_var *, ASC_SCSI_Q *);
1da177e4
LT
1490
1491typedef struct asc_dvc_var {
27c868c2
MW
1492 PortAddr iop_base;
1493 ushort err_code;
1494 ushort dvc_cntl;
1495 ushort bug_fix_cntl;
1496 ushort bus_type;
1497 ASC_ISR_CALLBACK isr_callback;
1498 ASC_EXE_CALLBACK exe_callback;
1499 ASC_SCSI_BIT_ID_TYPE init_sdtr;
1500 ASC_SCSI_BIT_ID_TYPE sdtr_done;
1501 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1502 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1503 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1504 ASC_SCSI_BIT_ID_TYPE start_motor;
1505 uchar scsi_reset_wait;
1506 uchar chip_no;
1507 char is_in_int;
1508 uchar max_total_qng;
1509 uchar cur_total_qng;
1510 uchar in_critical_cnt;
1511 uchar irq_no;
1512 uchar last_q_shortage;
1513 ushort init_state;
1514 uchar cur_dvc_qng[ASC_MAX_TID + 1];
1515 uchar max_dvc_qng[ASC_MAX_TID + 1];
1516 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
1517 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
1518 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1519 ASC_DVC_CFG *cfg;
1520 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1521 char redo_scam;
1522 ushort res2;
1523 uchar dos_int13_table[ASC_MAX_TID + 1];
1524 ASC_DCNT max_dma_count;
1525 ASC_SCSI_BIT_ID_TYPE no_scam;
1526 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1527 uchar max_sdtr_index;
1528 uchar host_init_sdtr_index;
1529 struct asc_board *drv_ptr;
1530 ASC_DCNT uc_break;
1da177e4
LT
1531} ASC_DVC_VAR;
1532
1533typedef struct asc_dvc_inq_info {
27c868c2 1534 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1da177e4
LT
1535} ASC_DVC_INQ_INFO;
1536
1537typedef struct asc_cap_info {
27c868c2
MW
1538 ASC_DCNT lba;
1539 ASC_DCNT blk_size;
1da177e4
LT
1540} ASC_CAP_INFO;
1541
1542typedef struct asc_cap_info_array {
27c868c2 1543 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1da177e4
LT
1544} ASC_CAP_INFO_ARRAY;
1545
1546#define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
1547#define ASC_MCNTL_NULL_TARGET (ushort)0x0002
1548#define ASC_CNTL_INITIATOR (ushort)0x0001
1549#define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
1550#define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
1551#define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
1552#define ASC_CNTL_NO_SCAM (ushort)0x0010
1553#define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
1554#define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
1555#define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
1556#define ASC_CNTL_RESET_SCSI (ushort)0x0200
1557#define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
1558#define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
1559#define ASC_CNTL_SCSI_PARITY (ushort)0x1000
1560#define ASC_CNTL_BURST_MODE (ushort)0x2000
1561#define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1562#define ASC_EEP_DVC_CFG_BEG_VL 2
1563#define ASC_EEP_MAX_DVC_ADDR_VL 15
1564#define ASC_EEP_DVC_CFG_BEG 32
1565#define ASC_EEP_MAX_DVC_ADDR 45
1566#define ASC_EEP_DEFINED_WORDS 10
1567#define ASC_EEP_MAX_ADDR 63
1568#define ASC_EEP_RES_WORDS 0
1569#define ASC_EEP_MAX_RETRY 20
1570#define ASC_MAX_INIT_BUSY_RETRY 8
1571#define ASC_EEP_ISA_PNP_WSIZE 16
1572
1573/*
1574 * These macros keep the chip SCSI id and ISA DMA speed
1575 * bitfields in board order. C bitfields aren't portable
1576 * between big and little-endian platforms so they are
1577 * not used.
1578 */
1579
1580#define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
1581#define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
1582#define ASC_EEP_SET_CHIP_ID(cfg, sid) \
1583 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
1584#define ASC_EEP_SET_DMA_SPD(cfg, spd) \
1585 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
1586
1587typedef struct asceep_config {
27c868c2
MW
1588 ushort cfg_lsw;
1589 ushort cfg_msw;
1590 uchar init_sdtr;
1591 uchar disc_enable;
1592 uchar use_cmd_qng;
1593 uchar start_motor;
1594 uchar max_total_qng;
1595 uchar max_tag_qng;
1596 uchar bios_scan;
1597 uchar power_up_wait;
1598 uchar no_scam;
1599 uchar id_speed; /* low order 4 bits is chip scsi id */
1600 /* high order 4 bits is isa dma speed */
1601 uchar dos_int13_table[ASC_MAX_TID + 1];
1602 uchar adapter_info[6];
1603 ushort cntl;
1604 ushort chksum;
1da177e4
LT
1605} ASCEEP_CONFIG;
1606
1607#define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800
1608#define ASC_PCI_CFG_LSW_BURST_MODE 0x0080
1609#define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020
1610
1611#define ASC_EEP_CMD_READ 0x80
1612#define ASC_EEP_CMD_WRITE 0x40
1613#define ASC_EEP_CMD_WRITE_ABLE 0x30
1614#define ASC_EEP_CMD_WRITE_DISABLE 0x00
1615#define ASC_OVERRUN_BSIZE 0x00000048UL
1616#define ASC_CTRL_BREAK_ONCE 0x0001
1617#define ASC_CTRL_BREAK_STAY_IDLE 0x0002
1618#define ASCV_MSGOUT_BEG 0x0000
1619#define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1620#define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1621#define ASCV_BREAK_SAVED_CODE (ushort)0x0006
1622#define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
1623#define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
1624#define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
1625#define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
1626#define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
1627#define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
1628#define ASCV_BREAK_ADDR (ushort)0x0028
1629#define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
1630#define ASCV_BREAK_CONTROL (ushort)0x002C
1631#define ASCV_BREAK_HIT_COUNT (ushort)0x002E
1632
1633#define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
1634#define ASCV_MCODE_CHKSUM_W (ushort)0x0032
1635#define ASCV_MCODE_SIZE_W (ushort)0x0034
1636#define ASCV_STOP_CODE_B (ushort)0x0036
1637#define ASCV_DVC_ERR_CODE_B (ushort)0x0037
1638#define ASCV_OVERRUN_PADDR_D (ushort)0x0038
1639#define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
1640#define ASCV_HALTCODE_W (ushort)0x0040
1641#define ASCV_CHKSUM_W (ushort)0x0042
1642#define ASCV_MC_DATE_W (ushort)0x0044
1643#define ASCV_MC_VER_W (ushort)0x0046
1644#define ASCV_NEXTRDY_B (ushort)0x0048
1645#define ASCV_DONENEXT_B (ushort)0x0049
1646#define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1647#define ASCV_SCSIBUSY_B (ushort)0x004B
1648#define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
1649#define ASCV_CURCDB_B (ushort)0x004D
1650#define ASCV_RCLUN_B (ushort)0x004E
1651#define ASCV_BUSY_QHEAD_B (ushort)0x004F
1652#define ASCV_DISC1_QHEAD_B (ushort)0x0050
1653#define ASCV_DISC_ENABLE_B (ushort)0x0052
1654#define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1655#define ASCV_HOSTSCSI_ID_B (ushort)0x0055
1656#define ASCV_MCODE_CNTL_B (ushort)0x0056
1657#define ASCV_NULL_TARGET_B (ushort)0x0057
1658#define ASCV_FREE_Q_HEAD_W (ushort)0x0058
1659#define ASCV_DONE_Q_TAIL_W (ushort)0x005A
1660#define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
1661#define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
1662#define ASCV_HOST_FLAG_B (ushort)0x005D
1663#define ASCV_TOTAL_READY_Q_B (ushort)0x0064
1664#define ASCV_VER_SERIAL_B (ushort)0x0065
1665#define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1666#define ASCV_WTM_FLAG_B (ushort)0x0068
1667#define ASCV_RISC_FLAG_B (ushort)0x006A
1668#define ASCV_REQ_SG_LIST_QP (ushort)0x006B
1669#define ASC_HOST_FLAG_IN_ISR 0x01
1670#define ASC_HOST_FLAG_ACK_INT 0x02
1671#define ASC_RISC_FLAG_GEN_INT 0x01
1672#define ASC_RISC_FLAG_REQ_SG_LIST 0x02
1673#define IOP_CTRL (0x0F)
1674#define IOP_STATUS (0x0E)
1675#define IOP_INT_ACK IOP_STATUS
1676#define IOP_REG_IFC (0x0D)
1677#define IOP_SYN_OFFSET (0x0B)
1678#define IOP_EXTRA_CONTROL (0x0D)
1679#define IOP_REG_PC (0x0C)
1680#define IOP_RAM_ADDR (0x0A)
1681#define IOP_RAM_DATA (0x08)
1682#define IOP_EEP_DATA (0x06)
1683#define IOP_EEP_CMD (0x07)
1684#define IOP_VERSION (0x03)
1685#define IOP_CONFIG_HIGH (0x04)
1686#define IOP_CONFIG_LOW (0x02)
1687#define IOP_SIG_BYTE (0x01)
1688#define IOP_SIG_WORD (0x00)
1689#define IOP_REG_DC1 (0x0E)
1690#define IOP_REG_DC0 (0x0C)
1691#define IOP_REG_SB (0x0B)
1692#define IOP_REG_DA1 (0x0A)
1693#define IOP_REG_DA0 (0x08)
1694#define IOP_REG_SC (0x09)
1695#define IOP_DMA_SPEED (0x07)
1696#define IOP_REG_FLAG (0x07)
1697#define IOP_FIFO_H (0x06)
1698#define IOP_FIFO_L (0x04)
1699#define IOP_REG_ID (0x05)
1700#define IOP_REG_QP (0x03)
1701#define IOP_REG_IH (0x02)
1702#define IOP_REG_IX (0x01)
1703#define IOP_REG_AX (0x00)
1704#define IFC_REG_LOCK (0x00)
1705#define IFC_REG_UNLOCK (0x09)
1706#define IFC_WR_EN_FILTER (0x10)
1707#define IFC_RD_NO_EEPROM (0x10)
1708#define IFC_SLEW_RATE (0x20)
1709#define IFC_ACT_NEG (0x40)
1710#define IFC_INP_FILTER (0x80)
1711#define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
1712#define SC_SEL (uchar)(0x80)
1713#define SC_BSY (uchar)(0x40)
1714#define SC_ACK (uchar)(0x20)
1715#define SC_REQ (uchar)(0x10)
1716#define SC_ATN (uchar)(0x08)
1717#define SC_IO (uchar)(0x04)
1718#define SC_CD (uchar)(0x02)
1719#define SC_MSG (uchar)(0x01)
1720#define SEC_SCSI_CTL (uchar)(0x80)
1721#define SEC_ACTIVE_NEGATE (uchar)(0x40)
1722#define SEC_SLEW_RATE (uchar)(0x20)
1723#define SEC_ENABLE_FILTER (uchar)(0x10)
1724#define ASC_HALT_EXTMSG_IN (ushort)0x8000
1725#define ASC_HALT_CHK_CONDITION (ushort)0x8100
1726#define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1727#define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
1728#define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
1729#define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1730#define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1731#define ASC_MAX_QNO 0xF8
1732#define ASC_DATA_SEC_BEG (ushort)0x0080
1733#define ASC_DATA_SEC_END (ushort)0x0080
1734#define ASC_CODE_SEC_BEG (ushort)0x0080
1735#define ASC_CODE_SEC_END (ushort)0x0080
1736#define ASC_QADR_BEG (0x4000)
1737#define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
1738#define ASC_QADR_END (ushort)0x7FFF
1739#define ASC_QLAST_ADR (ushort)0x7FC0
1740#define ASC_QBLK_SIZE 0x40
1741#define ASC_BIOS_DATA_QBEG 0xF8
1742#define ASC_MIN_ACTIVE_QNO 0x01
1743#define ASC_QLINK_END 0xFF
1744#define ASC_EEPROM_WORDS 0x10
1745#define ASC_MAX_MGS_LEN 0x10
1746#define ASC_BIOS_ADDR_DEF 0xDC00
1747#define ASC_BIOS_SIZE 0x3800
1748#define ASC_BIOS_RAM_OFF 0x3800
1749#define ASC_BIOS_RAM_SIZE 0x800
1750#define ASC_BIOS_MIN_ADDR 0xC000
1751#define ASC_BIOS_MAX_ADDR 0xEC00
1752#define ASC_BIOS_BANK_SIZE 0x0400
1753#define ASC_MCODE_START_ADDR 0x0080
1754#define ASC_CFG0_HOST_INT_ON 0x0020
1755#define ASC_CFG0_BIOS_ON 0x0040
1756#define ASC_CFG0_VERA_BURST_ON 0x0080
1757#define ASC_CFG0_SCSI_PARITY_ON 0x0800
1758#define ASC_CFG1_SCSI_TARGET_ON 0x0080
1759#define ASC_CFG1_LRAM_8BITS_ON 0x0800
1760#define ASC_CFG_MSW_CLR_MASK 0x3080
1761#define CSW_TEST1 (ASC_CS_TYPE)0x8000
1762#define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
1763#define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
1764#define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
1765#define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
1766#define CSW_TEST2 (ASC_CS_TYPE)0x0400
1767#define CSW_TEST3 (ASC_CS_TYPE)0x0200
1768#define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
1769#define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
1770#define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
1771#define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
1772#define CSW_HALTED (ASC_CS_TYPE)0x0010
1773#define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1774#define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
1775#define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
1776#define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
1777#define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1778#define CIW_INT_ACK (ASC_CS_TYPE)0x0100
1779#define CIW_TEST1 (ASC_CS_TYPE)0x0200
1780#define CIW_TEST2 (ASC_CS_TYPE)0x0400
1781#define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
1782#define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
1783#define CC_CHIP_RESET (uchar)0x80
1784#define CC_SCSI_RESET (uchar)0x40
1785#define CC_HALT (uchar)0x20
1786#define CC_SINGLE_STEP (uchar)0x10
1787#define CC_DMA_ABLE (uchar)0x08
1788#define CC_TEST (uchar)0x04
1789#define CC_BANK_ONE (uchar)0x02
1790#define CC_DIAG (uchar)0x01
1791#define ASC_1000_ID0W 0x04C1
1792#define ASC_1000_ID0W_FIX 0x00C1
1793#define ASC_1000_ID1B 0x25
1794#define ASC_EISA_BIG_IOP_GAP (0x1C30-0x0C50)
1795#define ASC_EISA_SMALL_IOP_GAP (0x0020)
1796#define ASC_EISA_MIN_IOP_ADDR (0x0C30)
1797#define ASC_EISA_MAX_IOP_ADDR (0xFC50)
1798#define ASC_EISA_REV_IOP_MASK (0x0C83)
1799#define ASC_EISA_PID_IOP_MASK (0x0C80)
1800#define ASC_EISA_CFG_IOP_MASK (0x0C86)
1801#define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
1802#define ASC_EISA_ID_740 0x01745004UL
1803#define ASC_EISA_ID_750 0x01755004UL
1804#define INS_HALTINT (ushort)0x6281
1805#define INS_HALT (ushort)0x6280
1806#define INS_SINT (ushort)0x6200
1807#define INS_RFLAG_WTM (ushort)0x7380
1808#define ASC_MC_SAVE_CODE_WSIZE 0x500
1809#define ASC_MC_SAVE_DATA_WSIZE 0x40
1810
1811typedef struct asc_mc_saved {
27c868c2
MW
1812 ushort data[ASC_MC_SAVE_DATA_WSIZE];
1813 ushort code[ASC_MC_SAVE_CODE_WSIZE];
1da177e4
LT
1814} ASC_MC_SAVED;
1815
1816#define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1817#define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1818#define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1819#define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1820#define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1821#define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1822#define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
1823#define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
1824#define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1825#define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1826#define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1827#define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1828#define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1829#define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1830#define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1831#define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
1832#define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
1833#define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
1834#define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
1835#define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
1836#define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
1837#define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
1838#define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
1839#define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
1840#define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
1841#define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
1842#define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1843#define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1844#define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
1845#define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
1846#define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
1847#define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
1848#define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1849#define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
1850#define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
1851#define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
1852#define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
1853#define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
1854#define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
1855#define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
1856#define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1857#define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1858#define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
1859#define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
1860#define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
1861#define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
1862#define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
1863#define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
1864#define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
1865#define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
1866#define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
1867#define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
1868#define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
1869#define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
1870#define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
1871#define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
1872#define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
1873#define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
1874#define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
1875#define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
1876#define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
1877#define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
1878#define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
1879#define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
1880#define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
1881#define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
1882#define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
1883#define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
1884
27c868c2
MW
1885static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1886static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1887static void AscWaitEEPRead(void);
1888static void AscWaitEEPWrite(void);
1889static ushort AscReadEEPWord(PortAddr, uchar);
1890static ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1891static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1892static int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1893static int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1894static int AscStartChip(PortAddr);
1895static int AscStopChip(PortAddr);
1896static void AscSetChipIH(PortAddr, ushort);
1897static int AscIsChipHalted(PortAddr);
1898static void AscAckInterrupt(PortAddr);
1899static void AscDisableInterrupt(PortAddr);
1900static void AscEnableInterrupt(PortAddr);
1901static void AscSetBank(PortAddr, uchar);
1902static int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1da177e4 1903#ifdef CONFIG_ISA
27c868c2
MW
1904static ushort AscGetIsaDmaChannel(PortAddr);
1905static ushort AscSetIsaDmaChannel(PortAddr, ushort);
1906static uchar AscSetIsaDmaSpeed(PortAddr, uchar);
1907static uchar AscGetIsaDmaSpeed(PortAddr);
1da177e4 1908#endif /* CONFIG_ISA */
27c868c2
MW
1909static uchar AscReadLramByte(PortAddr, ushort);
1910static ushort AscReadLramWord(PortAddr, ushort);
1da177e4 1911#if CC_VERY_LONG_SG_LIST
27c868c2 1912static ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1da177e4 1913#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
1914static void AscWriteLramWord(PortAddr, ushort, ushort);
1915static void AscWriteLramByte(PortAddr, ushort, uchar);
1916static ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
1917static void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1918static void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1919static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1920static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
1921static ushort AscInitAscDvcVar(ASC_DVC_VAR *);
1922static ushort AscInitFromEEP(ASC_DVC_VAR *);
1923static ushort AscInitFromAscDvcVar(ASC_DVC_VAR *);
1924static ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1925static int AscTestExternalLram(ASC_DVC_VAR *);
1926static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1927static uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1928static void AscSetChipSDTR(PortAddr, uchar, uchar);
1929static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1930static uchar AscAllocFreeQueue(PortAddr, uchar);
1931static uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1932static int AscHostReqRiscHalt(PortAddr);
1933static int AscStopQueueExe(PortAddr);
1934static int AscSendScsiQueue(ASC_DVC_VAR *,
1935 ASC_SCSI_Q *scsiq, uchar n_q_required);
1936static int AscPutReadyQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1937static int AscPutReadySgListQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1938static int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1939static int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1940static ushort AscInitLram(ASC_DVC_VAR *);
1941static ushort AscInitQLinkVar(ASC_DVC_VAR *);
1942static int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1943static int AscIsrChipHalted(ASC_DVC_VAR *);
1944static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1945 ASC_QDONE_INFO *, ASC_DCNT);
1946static int AscIsrQDone(ASC_DVC_VAR *);
1947static int AscCompareString(uchar *, uchar *, int);
1da177e4 1948#ifdef CONFIG_ISA
27c868c2
MW
1949static ushort AscGetEisaChipCfg(PortAddr);
1950static ASC_DCNT AscGetEisaProductID(PortAddr);
1951static PortAddr AscSearchIOPortAddrEISA(PortAddr);
1952static PortAddr AscSearchIOPortAddr11(PortAddr);
1953static PortAddr AscSearchIOPortAddr(PortAddr, ushort);
1954static void AscSetISAPNPWaitForKey(void);
1da177e4 1955#endif /* CONFIG_ISA */
27c868c2
MW
1956static uchar AscGetChipScsiCtrl(PortAddr);
1957static uchar AscSetChipScsiID(PortAddr, uchar);
1958static uchar AscGetChipVersion(PortAddr, ushort);
1959static ushort AscGetChipBusType(PortAddr);
1960static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
1961static int AscFindSignature(PortAddr);
1962static void AscToggleIRQAct(PortAddr);
1963static uchar AscGetChipIRQ(PortAddr, ushort);
1964static uchar AscSetChipIRQ(PortAddr, uchar, ushort);
1965static ushort AscGetChipBiosAddress(PortAddr, ushort);
1966static inline ulong DvcEnterCritical(void);
1967static inline void DvcLeaveCritical(ulong);
1da177e4 1968#ifdef CONFIG_PCI
27c868c2
MW
1969static uchar DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort);
1970static void DvcWritePCIConfigByte(ASC_DVC_VAR *, ushort, uchar);
1da177e4 1971#endif /* CONFIG_PCI */
27c868c2
MW
1972static ushort AscGetChipBiosAddress(PortAddr, ushort);
1973static void DvcSleepMilliSecond(ASC_DCNT);
1974static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
1975static void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1976static void DvcGetQinfo(PortAddr, ushort, uchar *, int);
1977static ushort AscInitGetConfig(ASC_DVC_VAR *);
1978static ushort AscInitSetConfig(ASC_DVC_VAR *);
1979static ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
1980static void AscAsyncFix(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *);
1981static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
1982static void AscInquiryHandling(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *);
1983static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
1984static int AscISR(ASC_DVC_VAR *);
1985static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar);
1986static int AscSgListToQueue(int);
1da177e4 1987#ifdef CONFIG_ISA
27c868c2 1988static void AscEnableIsaDma(uchar);
1da177e4 1989#endif /* CONFIG_ISA */
27c868c2
MW
1990static ASC_DCNT AscGetMaxDmaCount(ushort);
1991static const char *advansys_info(struct Scsi_Host *shost);
1da177e4
LT
1992
1993/*
1994 * --- Adv Library Constants and Macros
1995 */
1996
1997#define ADV_LIB_VERSION_MAJOR 5
1998#define ADV_LIB_VERSION_MINOR 14
1999
2000/*
2001 * Define Adv Library required special types.
2002 */
2003
2004/*
2005 * Portable Data Types
2006 *
2007 * Any instance where a 32-bit long or pointer type is assumed
2008 * for precision or HW defined structures, the following define
2009 * types must be used. In Linux the char, short, and int types
2010 * are all consistent at 8, 16, and 32 bits respectively. Pointers
2011 * and long types are 64 bits on Alpha and UltraSPARC.
2012 */
27c868c2
MW
2013#define ADV_PADDR __u32 /* Physical address data type. */
2014#define ADV_VADDR __u32 /* Virtual address data type. */
2015#define ADV_DCNT __u32 /* Unsigned Data count type. */
2016#define ADV_SDCNT __s32 /* Signed Data count type. */
1da177e4
LT
2017
2018/*
2019 * These macros are used to convert a virtual address to a
2020 * 32-bit value. This currently can be used on Linux Alpha
2021 * which uses 64-bit virtual address but a 32-bit bus address.
2022 * This is likely to break in the future, but doing this now
2023 * will give us time to change the HW and FW to handle 64-bit
2024 * addresses.
2025 */
2026#define ADV_VADDR_TO_U32 virt_to_bus
2027#define ADV_U32_TO_VADDR bus_to_virt
2028
27c868c2 2029#define AdvPortAddr void __iomem * /* Virtual memory address size */
1da177e4
LT
2030
2031/*
2032 * Define Adv Library required memory access macros.
2033 */
2034#define ADV_MEM_READB(addr) readb(addr)
2035#define ADV_MEM_READW(addr) readw(addr)
2036#define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
2037#define ADV_MEM_WRITEW(addr, word) writew(word, addr)
2038#define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
2039
2040#define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
2041
2042/*
2043 * For wide boards a CDB length maximum of 16 bytes
2044 * is supported.
2045 */
2046#define ADV_MAX_CDB_LEN 16
2047
2048/*
2049 * Define total number of simultaneous maximum element scatter-gather
2050 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
2051 * maximum number of outstanding commands per wide host adapter. Each
2052 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
2053 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
2054 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
2055 * structures or 255 scatter-gather elements.
2056 *
2057 */
2058#define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
2059
2060/*
2061 * Define Adv Library required maximum number of scatter-gather
2062 * elements per request.
2063 */
2064#define ADV_MAX_SG_LIST 255
2065
2066/* Number of SG blocks needed. */
2067#define ADV_NUM_SG_BLOCK \
2068 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
2069
2070/* Total contiguous memory needed for SG blocks. */
2071#define ADV_SG_TOTAL_MEM_SIZE \
2072 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
2073
2074#define ADV_PAGE_SIZE PAGE_SIZE
2075
2076#define ADV_NUM_PAGE_CROSSING \
2077 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2078
1da177e4
LT
2079#define ADV_EEP_DVC_CFG_BEGIN (0x00)
2080#define ADV_EEP_DVC_CFG_END (0x15)
27c868c2 2081#define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
1da177e4
LT
2082#define ADV_EEP_MAX_WORD_ADDR (0x1E)
2083
2084#define ADV_EEP_DELAY_MS 100
2085
27c868c2
MW
2086#define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
2087#define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
1da177e4
LT
2088/*
2089 * For the ASC3550 Bit 13 is Termination Polarity control bit.
2090 * For later ICs Bit 13 controls whether the CIS (Card Information
2091 * Service Section) is loaded from EEPROM.
2092 */
27c868c2
MW
2093#define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
2094#define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
1da177e4
LT
2095/*
2096 * ASC38C1600 Bit 11
2097 *
2098 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
2099 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
2100 * Function 0 will specify INT B.
2101 *
2102 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
2103 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
2104 * Function 1 will specify INT A.
2105 */
27c868c2
MW
2106#define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
2107
2108typedef struct adveep_3550_config {
2109 /* Word Offset, Description */
2110
2111 ushort cfg_lsw; /* 00 power up initialization */
2112 /* bit 13 set - Term Polarity Control */
2113 /* bit 14 set - BIOS Enable */
2114 /* bit 15 set - Big Endian Mode */
2115 ushort cfg_msw; /* 01 unused */
2116 ushort disc_enable; /* 02 disconnect enable */
2117 ushort wdtr_able; /* 03 Wide DTR able */
2118 ushort sdtr_able; /* 04 Synchronous DTR able */
2119 ushort start_motor; /* 05 send start up motor */
2120 ushort tagqng_able; /* 06 tag queuing able */
2121 ushort bios_scan; /* 07 BIOS device control */
2122 ushort scam_tolerant; /* 08 no scam */
2123
2124 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2125 uchar bios_boot_delay; /* power up wait */
2126
2127 uchar scsi_reset_delay; /* 10 reset delay */
2128 uchar bios_id_lun; /* first boot device scsi id & lun */
2129 /* high nibble is lun */
2130 /* low nibble is scsi id */
2131
2132 uchar termination; /* 11 0 - automatic */
2133 /* 1 - low off / high off */
2134 /* 2 - low off / high on */
2135 /* 3 - low on / high on */
2136 /* There is no low on / high off */
2137
2138 uchar reserved1; /* reserved byte (not used) */
2139
2140 ushort bios_ctrl; /* 12 BIOS control bits */
2141 /* bit 0 BIOS don't act as initiator. */
2142 /* bit 1 BIOS > 1 GB support */
2143 /* bit 2 BIOS > 2 Disk Support */
2144 /* bit 3 BIOS don't support removables */
2145 /* bit 4 BIOS support bootable CD */
2146 /* bit 5 BIOS scan enabled */
2147 /* bit 6 BIOS support multiple LUNs */
2148 /* bit 7 BIOS display of message */
2149 /* bit 8 SCAM disabled */
2150 /* bit 9 Reset SCSI bus during init. */
2151 /* bit 10 */
2152 /* bit 11 No verbose initialization. */
2153 /* bit 12 SCSI parity enabled */
2154 /* bit 13 */
2155 /* bit 14 */
2156 /* bit 15 */
2157 ushort ultra_able; /* 13 ULTRA speed able */
2158 ushort reserved2; /* 14 reserved */
2159 uchar max_host_qng; /* 15 maximum host queuing */
2160 uchar max_dvc_qng; /* maximum per device queuing */
2161 ushort dvc_cntl; /* 16 control bit for driver */
2162 ushort bug_fix; /* 17 control bit for bug fix */
2163 ushort serial_number_word1; /* 18 Board serial number word 1 */
2164 ushort serial_number_word2; /* 19 Board serial number word 2 */
2165 ushort serial_number_word3; /* 20 Board serial number word 3 */
2166 ushort check_sum; /* 21 EEP check sum */
2167 uchar oem_name[16]; /* 22 OEM name */
2168 ushort dvc_err_code; /* 30 last device driver error code */
2169 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2170 ushort adv_err_addr; /* 32 last uc error address */
2171 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2172 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2173 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2174 ushort num_of_err; /* 36 number of error */
1da177e4
LT
2175} ADVEEP_3550_CONFIG;
2176
27c868c2
MW
2177typedef struct adveep_38C0800_config {
2178 /* Word Offset, Description */
2179
2180 ushort cfg_lsw; /* 00 power up initialization */
2181 /* bit 13 set - Load CIS */
2182 /* bit 14 set - BIOS Enable */
2183 /* bit 15 set - Big Endian Mode */
2184 ushort cfg_msw; /* 01 unused */
2185 ushort disc_enable; /* 02 disconnect enable */
2186 ushort wdtr_able; /* 03 Wide DTR able */
2187 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2188 ushort start_motor; /* 05 send start up motor */
2189 ushort tagqng_able; /* 06 tag queuing able */
2190 ushort bios_scan; /* 07 BIOS device control */
2191 ushort scam_tolerant; /* 08 no scam */
2192
2193 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2194 uchar bios_boot_delay; /* power up wait */
2195
2196 uchar scsi_reset_delay; /* 10 reset delay */
2197 uchar bios_id_lun; /* first boot device scsi id & lun */
2198 /* high nibble is lun */
2199 /* low nibble is scsi id */
2200
2201 uchar termination_se; /* 11 0 - automatic */
2202 /* 1 - low off / high off */
2203 /* 2 - low off / high on */
2204 /* 3 - low on / high on */
2205 /* There is no low on / high off */
2206
2207 uchar termination_lvd; /* 11 0 - automatic */
2208 /* 1 - low off / high off */
2209 /* 2 - low off / high on */
2210 /* 3 - low on / high on */
2211 /* There is no low on / high off */
2212
2213 ushort bios_ctrl; /* 12 BIOS control bits */
2214 /* bit 0 BIOS don't act as initiator. */
2215 /* bit 1 BIOS > 1 GB support */
2216 /* bit 2 BIOS > 2 Disk Support */
2217 /* bit 3 BIOS don't support removables */
2218 /* bit 4 BIOS support bootable CD */
2219 /* bit 5 BIOS scan enabled */
2220 /* bit 6 BIOS support multiple LUNs */
2221 /* bit 7 BIOS display of message */
2222 /* bit 8 SCAM disabled */
2223 /* bit 9 Reset SCSI bus during init. */
2224 /* bit 10 */
2225 /* bit 11 No verbose initialization. */
2226 /* bit 12 SCSI parity enabled */
2227 /* bit 13 */
2228 /* bit 14 */
2229 /* bit 15 */
2230 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2231 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2232 uchar max_host_qng; /* 15 maximum host queueing */
2233 uchar max_dvc_qng; /* maximum per device queuing */
2234 ushort dvc_cntl; /* 16 control bit for driver */
2235 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2236 ushort serial_number_word1; /* 18 Board serial number word 1 */
2237 ushort serial_number_word2; /* 19 Board serial number word 2 */
2238 ushort serial_number_word3; /* 20 Board serial number word 3 */
2239 ushort check_sum; /* 21 EEP check sum */
2240 uchar oem_name[16]; /* 22 OEM name */
2241 ushort dvc_err_code; /* 30 last device driver error code */
2242 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2243 ushort adv_err_addr; /* 32 last uc error address */
2244 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2245 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2246 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2247 ushort reserved36; /* 36 reserved */
2248 ushort reserved37; /* 37 reserved */
2249 ushort reserved38; /* 38 reserved */
2250 ushort reserved39; /* 39 reserved */
2251 ushort reserved40; /* 40 reserved */
2252 ushort reserved41; /* 41 reserved */
2253 ushort reserved42; /* 42 reserved */
2254 ushort reserved43; /* 43 reserved */
2255 ushort reserved44; /* 44 reserved */
2256 ushort reserved45; /* 45 reserved */
2257 ushort reserved46; /* 46 reserved */
2258 ushort reserved47; /* 47 reserved */
2259 ushort reserved48; /* 48 reserved */
2260 ushort reserved49; /* 49 reserved */
2261 ushort reserved50; /* 50 reserved */
2262 ushort reserved51; /* 51 reserved */
2263 ushort reserved52; /* 52 reserved */
2264 ushort reserved53; /* 53 reserved */
2265 ushort reserved54; /* 54 reserved */
2266 ushort reserved55; /* 55 reserved */
2267 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2268 ushort cisprt_msw; /* 57 CIS PTR MSW */
2269 ushort subsysvid; /* 58 SubSystem Vendor ID */
2270 ushort subsysid; /* 59 SubSystem ID */
2271 ushort reserved60; /* 60 reserved */
2272 ushort reserved61; /* 61 reserved */
2273 ushort reserved62; /* 62 reserved */
2274 ushort reserved63; /* 63 reserved */
1da177e4
LT
2275} ADVEEP_38C0800_CONFIG;
2276
27c868c2
MW
2277typedef struct adveep_38C1600_config {
2278 /* Word Offset, Description */
2279
2280 ushort cfg_lsw; /* 00 power up initialization */
2281 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
2282 /* clear - Func. 0 INTA, Func. 1 INTB */
2283 /* bit 13 set - Load CIS */
2284 /* bit 14 set - BIOS Enable */
2285 /* bit 15 set - Big Endian Mode */
2286 ushort cfg_msw; /* 01 unused */
2287 ushort disc_enable; /* 02 disconnect enable */
2288 ushort wdtr_able; /* 03 Wide DTR able */
2289 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2290 ushort start_motor; /* 05 send start up motor */
2291 ushort tagqng_able; /* 06 tag queuing able */
2292 ushort bios_scan; /* 07 BIOS device control */
2293 ushort scam_tolerant; /* 08 no scam */
2294
2295 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2296 uchar bios_boot_delay; /* power up wait */
2297
2298 uchar scsi_reset_delay; /* 10 reset delay */
2299 uchar bios_id_lun; /* first boot device scsi id & lun */
2300 /* high nibble is lun */
2301 /* low nibble is scsi id */
2302
2303 uchar termination_se; /* 11 0 - automatic */
2304 /* 1 - low off / high off */
2305 /* 2 - low off / high on */
2306 /* 3 - low on / high on */
2307 /* There is no low on / high off */
2308
2309 uchar termination_lvd; /* 11 0 - automatic */
2310 /* 1 - low off / high off */
2311 /* 2 - low off / high on */
2312 /* 3 - low on / high on */
2313 /* There is no low on / high off */
2314
2315 ushort bios_ctrl; /* 12 BIOS control bits */
2316 /* bit 0 BIOS don't act as initiator. */
2317 /* bit 1 BIOS > 1 GB support */
2318 /* bit 2 BIOS > 2 Disk Support */
2319 /* bit 3 BIOS don't support removables */
2320 /* bit 4 BIOS support bootable CD */
2321 /* bit 5 BIOS scan enabled */
2322 /* bit 6 BIOS support multiple LUNs */
2323 /* bit 7 BIOS display of message */
2324 /* bit 8 SCAM disabled */
2325 /* bit 9 Reset SCSI bus during init. */
2326 /* bit 10 Basic Integrity Checking disabled */
2327 /* bit 11 No verbose initialization. */
2328 /* bit 12 SCSI parity enabled */
2329 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
2330 /* bit 14 */
2331 /* bit 15 */
2332 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2333 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2334 uchar max_host_qng; /* 15 maximum host queueing */
2335 uchar max_dvc_qng; /* maximum per device queuing */
2336 ushort dvc_cntl; /* 16 control bit for driver */
2337 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2338 ushort serial_number_word1; /* 18 Board serial number word 1 */
2339 ushort serial_number_word2; /* 19 Board serial number word 2 */
2340 ushort serial_number_word3; /* 20 Board serial number word 3 */
2341 ushort check_sum; /* 21 EEP check sum */
2342 uchar oem_name[16]; /* 22 OEM name */
2343 ushort dvc_err_code; /* 30 last device driver error code */
2344 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2345 ushort adv_err_addr; /* 32 last uc error address */
2346 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2347 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2348 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2349 ushort reserved36; /* 36 reserved */
2350 ushort reserved37; /* 37 reserved */
2351 ushort reserved38; /* 38 reserved */
2352 ushort reserved39; /* 39 reserved */
2353 ushort reserved40; /* 40 reserved */
2354 ushort reserved41; /* 41 reserved */
2355 ushort reserved42; /* 42 reserved */
2356 ushort reserved43; /* 43 reserved */
2357 ushort reserved44; /* 44 reserved */
2358 ushort reserved45; /* 45 reserved */
2359 ushort reserved46; /* 46 reserved */
2360 ushort reserved47; /* 47 reserved */
2361 ushort reserved48; /* 48 reserved */
2362 ushort reserved49; /* 49 reserved */
2363 ushort reserved50; /* 50 reserved */
2364 ushort reserved51; /* 51 reserved */
2365 ushort reserved52; /* 52 reserved */
2366 ushort reserved53; /* 53 reserved */
2367 ushort reserved54; /* 54 reserved */
2368 ushort reserved55; /* 55 reserved */
2369 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2370 ushort cisprt_msw; /* 57 CIS PTR MSW */
2371 ushort subsysvid; /* 58 SubSystem Vendor ID */
2372 ushort subsysid; /* 59 SubSystem ID */
2373 ushort reserved60; /* 60 reserved */
2374 ushort reserved61; /* 61 reserved */
2375 ushort reserved62; /* 62 reserved */
2376 ushort reserved63; /* 63 reserved */
1da177e4
LT
2377} ADVEEP_38C1600_CONFIG;
2378
2379/*
2380 * EEPROM Commands
2381 */
2382#define ASC_EEP_CMD_DONE 0x0200
2383#define ASC_EEP_CMD_DONE_ERR 0x0001
2384
2385/* cfg_word */
2386#define EEP_CFG_WORD_BIG_ENDIAN 0x8000
2387
2388/* bios_ctrl */
2389#define BIOS_CTRL_BIOS 0x0001
2390#define BIOS_CTRL_EXTENDED_XLAT 0x0002
2391#define BIOS_CTRL_GT_2_DISK 0x0004
2392#define BIOS_CTRL_BIOS_REMOVABLE 0x0008
2393#define BIOS_CTRL_BOOTABLE_CD 0x0010
2394#define BIOS_CTRL_MULTIPLE_LUN 0x0040
2395#define BIOS_CTRL_DISPLAY_MSG 0x0080
2396#define BIOS_CTRL_NO_SCAM 0x0100
2397#define BIOS_CTRL_RESET_SCSI_BUS 0x0200
2398#define BIOS_CTRL_INIT_VERBOSE 0x0800
2399#define BIOS_CTRL_SCSI_PARITY 0x1000
2400#define BIOS_CTRL_AIPP_DIS 0x2000
2401
27c868c2
MW
2402#define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
2403#define ADV_3550_IOLEN 0x40 /* I/O Port Range in bytes */
1da177e4 2404
27c868c2
MW
2405#define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2406#define ADV_38C0800_IOLEN 0x100 /* I/O Port Range in bytes */
1da177e4
LT
2407
2408/*
2409 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
2410 * a special 16K Adv Library and Microcode version. After the issue is
2411 * resolved, should restore 32K support.
2412 *
2413 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
2414 */
27c868c2
MW
2415#define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2416#define ADV_38C1600_IOLEN 0x100 /* I/O Port Range 256 bytes */
2417#define ADV_38C1600_MEMLEN 0x1000 /* Memory Range 4KB bytes */
1da177e4
LT
2418
2419/*
2420 * Byte I/O register address from base of 'iop_base'.
2421 */
2422#define IOPB_INTR_STATUS_REG 0x00
2423#define IOPB_CHIP_ID_1 0x01
2424#define IOPB_INTR_ENABLES 0x02
2425#define IOPB_CHIP_TYPE_REV 0x03
2426#define IOPB_RES_ADDR_4 0x04
2427#define IOPB_RES_ADDR_5 0x05
2428#define IOPB_RAM_DATA 0x06
2429#define IOPB_RES_ADDR_7 0x07
2430#define IOPB_FLAG_REG 0x08
2431#define IOPB_RES_ADDR_9 0x09
2432#define IOPB_RISC_CSR 0x0A
2433#define IOPB_RES_ADDR_B 0x0B
2434#define IOPB_RES_ADDR_C 0x0C
2435#define IOPB_RES_ADDR_D 0x0D
2436#define IOPB_SOFT_OVER_WR 0x0E
2437#define IOPB_RES_ADDR_F 0x0F
2438#define IOPB_MEM_CFG 0x10
2439#define IOPB_RES_ADDR_11 0x11
2440#define IOPB_GPIO_DATA 0x12
2441#define IOPB_RES_ADDR_13 0x13
2442#define IOPB_FLASH_PAGE 0x14
2443#define IOPB_RES_ADDR_15 0x15
2444#define IOPB_GPIO_CNTL 0x16
2445#define IOPB_RES_ADDR_17 0x17
2446#define IOPB_FLASH_DATA 0x18
2447#define IOPB_RES_ADDR_19 0x19
2448#define IOPB_RES_ADDR_1A 0x1A
2449#define IOPB_RES_ADDR_1B 0x1B
2450#define IOPB_RES_ADDR_1C 0x1C
2451#define IOPB_RES_ADDR_1D 0x1D
2452#define IOPB_RES_ADDR_1E 0x1E
2453#define IOPB_RES_ADDR_1F 0x1F
2454#define IOPB_DMA_CFG0 0x20
2455#define IOPB_DMA_CFG1 0x21
2456#define IOPB_TICKLE 0x22
2457#define IOPB_DMA_REG_WR 0x23
2458#define IOPB_SDMA_STATUS 0x24
2459#define IOPB_SCSI_BYTE_CNT 0x25
2460#define IOPB_HOST_BYTE_CNT 0x26
2461#define IOPB_BYTE_LEFT_TO_XFER 0x27
2462#define IOPB_BYTE_TO_XFER_0 0x28
2463#define IOPB_BYTE_TO_XFER_1 0x29
2464#define IOPB_BYTE_TO_XFER_2 0x2A
2465#define IOPB_BYTE_TO_XFER_3 0x2B
2466#define IOPB_ACC_GRP 0x2C
2467#define IOPB_RES_ADDR_2D 0x2D
2468#define IOPB_DEV_ID 0x2E
2469#define IOPB_RES_ADDR_2F 0x2F
2470#define IOPB_SCSI_DATA 0x30
2471#define IOPB_RES_ADDR_31 0x31
2472#define IOPB_RES_ADDR_32 0x32
2473#define IOPB_SCSI_DATA_HSHK 0x33
2474#define IOPB_SCSI_CTRL 0x34
2475#define IOPB_RES_ADDR_35 0x35
2476#define IOPB_RES_ADDR_36 0x36
2477#define IOPB_RES_ADDR_37 0x37
2478#define IOPB_RAM_BIST 0x38
2479#define IOPB_PLL_TEST 0x39
2480#define IOPB_PCI_INT_CFG 0x3A
2481#define IOPB_RES_ADDR_3B 0x3B
2482#define IOPB_RFIFO_CNT 0x3C
2483#define IOPB_RES_ADDR_3D 0x3D
2484#define IOPB_RES_ADDR_3E 0x3E
2485#define IOPB_RES_ADDR_3F 0x3F
2486
2487/*
2488 * Word I/O register address from base of 'iop_base'.
2489 */
27c868c2
MW
2490#define IOPW_CHIP_ID_0 0x00 /* CID0 */
2491#define IOPW_CTRL_REG 0x02 /* CC */
2492#define IOPW_RAM_ADDR 0x04 /* LA */
2493#define IOPW_RAM_DATA 0x06 /* LD */
1da177e4 2494#define IOPW_RES_ADDR_08 0x08
27c868c2
MW
2495#define IOPW_RISC_CSR 0x0A /* CSR */
2496#define IOPW_SCSI_CFG0 0x0C /* CFG0 */
2497#define IOPW_SCSI_CFG1 0x0E /* CFG1 */
1da177e4 2498#define IOPW_RES_ADDR_10 0x10
27c868c2 2499#define IOPW_SEL_MASK 0x12 /* SM */
1da177e4 2500#define IOPW_RES_ADDR_14 0x14
27c868c2 2501#define IOPW_FLASH_ADDR 0x16 /* FA */
1da177e4 2502#define IOPW_RES_ADDR_18 0x18
27c868c2
MW
2503#define IOPW_EE_CMD 0x1A /* EC */
2504#define IOPW_EE_DATA 0x1C /* ED */
2505#define IOPW_SFIFO_CNT 0x1E /* SFC */
1da177e4 2506#define IOPW_RES_ADDR_20 0x20
27c868c2
MW
2507#define IOPW_Q_BASE 0x22 /* QB */
2508#define IOPW_QP 0x24 /* QP */
2509#define IOPW_IX 0x26 /* IX */
2510#define IOPW_SP 0x28 /* SP */
2511#define IOPW_PC 0x2A /* PC */
1da177e4
LT
2512#define IOPW_RES_ADDR_2C 0x2C
2513#define IOPW_RES_ADDR_2E 0x2E
27c868c2
MW
2514#define IOPW_SCSI_DATA 0x30 /* SD */
2515#define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
2516#define IOPW_SCSI_CTRL 0x34 /* SC */
2517#define IOPW_HSHK_CFG 0x36 /* HCFG */
2518#define IOPW_SXFR_STATUS 0x36 /* SXS */
2519#define IOPW_SXFR_CNTL 0x38 /* SXL */
2520#define IOPW_SXFR_CNTH 0x3A /* SXH */
1da177e4 2521#define IOPW_RES_ADDR_3C 0x3C
27c868c2 2522#define IOPW_RFIFO_DATA 0x3E /* RFD */
1da177e4
LT
2523
2524/*
2525 * Doubleword I/O register address from base of 'iop_base'.
2526 */
2527#define IOPDW_RES_ADDR_0 0x00
2528#define IOPDW_RAM_DATA 0x04
2529#define IOPDW_RES_ADDR_8 0x08
2530#define IOPDW_RES_ADDR_C 0x0C
2531#define IOPDW_RES_ADDR_10 0x10
2532#define IOPDW_COMMA 0x14
2533#define IOPDW_COMMB 0x18
2534#define IOPDW_RES_ADDR_1C 0x1C
2535#define IOPDW_SDMA_ADDR0 0x20
2536#define IOPDW_SDMA_ADDR1 0x24
2537#define IOPDW_SDMA_COUNT 0x28
2538#define IOPDW_SDMA_ERROR 0x2C
2539#define IOPDW_RDMA_ADDR0 0x30
2540#define IOPDW_RDMA_ADDR1 0x34
2541#define IOPDW_RDMA_COUNT 0x38
2542#define IOPDW_RDMA_ERROR 0x3C
2543
2544#define ADV_CHIP_ID_BYTE 0x25
2545#define ADV_CHIP_ID_WORD 0x04C1
2546
2547#define ADV_SC_SCSI_BUS_RESET 0x2000
2548
2549#define ADV_INTR_ENABLE_HOST_INTR 0x01
2550#define ADV_INTR_ENABLE_SEL_INTR 0x02
2551#define ADV_INTR_ENABLE_DPR_INTR 0x04
2552#define ADV_INTR_ENABLE_RTA_INTR 0x08
2553#define ADV_INTR_ENABLE_RMA_INTR 0x10
2554#define ADV_INTR_ENABLE_RST_INTR 0x20
2555#define ADV_INTR_ENABLE_DPE_INTR 0x40
2556#define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
2557
2558#define ADV_INTR_STATUS_INTRA 0x01
2559#define ADV_INTR_STATUS_INTRB 0x02
2560#define ADV_INTR_STATUS_INTRC 0x04
2561
2562#define ADV_RISC_CSR_STOP (0x0000)
2563#define ADV_RISC_TEST_COND (0x2000)
2564#define ADV_RISC_CSR_RUN (0x4000)
2565#define ADV_RISC_CSR_SINGLE_STEP (0x8000)
2566
2567#define ADV_CTRL_REG_HOST_INTR 0x0100
2568#define ADV_CTRL_REG_SEL_INTR 0x0200
2569#define ADV_CTRL_REG_DPR_INTR 0x0400
2570#define ADV_CTRL_REG_RTA_INTR 0x0800
2571#define ADV_CTRL_REG_RMA_INTR 0x1000
2572#define ADV_CTRL_REG_RES_BIT14 0x2000
2573#define ADV_CTRL_REG_DPE_INTR 0x4000
2574#define ADV_CTRL_REG_POWER_DONE 0x8000
2575#define ADV_CTRL_REG_ANY_INTR 0xFF00
2576
2577#define ADV_CTRL_REG_CMD_RESET 0x00C6
2578#define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
2579#define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
2580#define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
2581#define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
2582
2583#define ADV_TICKLE_NOP 0x00
2584#define ADV_TICKLE_A 0x01
2585#define ADV_TICKLE_B 0x02
2586#define ADV_TICKLE_C 0x03
2587
2588#define ADV_SCSI_CTRL_RSTOUT 0x2000
2589
2590#define AdvIsIntPending(port) \
2591 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2592
2593/*
2594 * SCSI_CFG0 Register bit definitions
2595 */
27c868c2
MW
2596#define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
2597#define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
2598#define EVEN_PARITY 0x1000 /* Select Even Parity */
2599#define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2600#define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
2601#define PRIM_MODE 0x0100 /* Primitive SCSI mode */
2602#define SCAM_EN 0x0080 /* Enable SCAM selection */
2603#define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2604#define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2605#define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
2606#define OUR_ID 0x000F /* SCSI ID */
1da177e4
LT
2607
2608/*
2609 * SCSI_CFG1 Register bit definitions
2610 */
27c868c2
MW
2611#define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
2612#define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2613#define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
2614#define FILTER_SEL 0x0C00 /* Filter Period Selection */
2615#define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
2616#define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
2617#define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
2618#define ACTIVE_DBL 0x0200 /* Disable Active Negation */
2619#define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
2620#define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
2621#define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
2622#define TERM_CTL 0x0030 /* External SCSI Termination Bits */
2623#define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
2624#define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
2625#define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
1da177e4
LT
2626
2627/*
2628 * Addendum for ASC-38C0800 Chip
2629 *
2630 * The ASC-38C1600 Chip uses the same definitions except that the
2631 * bus mode override bits [12:10] have been moved to byte register
2632 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
2633 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
2634 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
2635 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
2636 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
2637 */
27c868c2
MW
2638#define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
2639#define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
2640#define HVD 0x1000 /* HVD Device Detect */
2641#define LVD 0x0800 /* LVD Device Detect */
2642#define SE 0x0400 /* SE Device Detect */
2643#define TERM_LVD 0x00C0 /* LVD Termination Bits */
2644#define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
2645#define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
2646#define TERM_SE 0x0030 /* SE Termination Bits */
2647#define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
2648#define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
2649#define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
2650#define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
2651#define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
2652#define C_DET_SE 0x0003 /* SE Cable Detect Bits */
2653#define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
2654#define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
1da177e4
LT
2655
2656#define CABLE_ILLEGAL_A 0x7
2657 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
2658
2659#define CABLE_ILLEGAL_B 0xB
2660 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
2661
2662/*
2663 * MEM_CFG Register bit definitions
2664 */
27c868c2
MW
2665#define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
2666#define FAST_EE_CLK 0x20 /* Diagnostic Bit */
2667#define RAM_SZ 0x1C /* Specify size of RAM to RISC */
2668#define RAM_SZ_2KB 0x00 /* 2 KB */
2669#define RAM_SZ_4KB 0x04 /* 4 KB */
2670#define RAM_SZ_8KB 0x08 /* 8 KB */
2671#define RAM_SZ_16KB 0x0C /* 16 KB */
2672#define RAM_SZ_32KB 0x10 /* 32 KB */
2673#define RAM_SZ_64KB 0x14 /* 64 KB */
1da177e4
LT
2674
2675/*
2676 * DMA_CFG0 Register bit definitions
2677 *
2678 * This register is only accessible to the host.
2679 */
27c868c2
MW
2680#define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
2681#define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
2682#define FIFO_THRESH_16B 0x00 /* 16 bytes */
2683#define FIFO_THRESH_32B 0x20 /* 32 bytes */
2684#define FIFO_THRESH_48B 0x30 /* 48 bytes */
2685#define FIFO_THRESH_64B 0x40 /* 64 bytes */
2686#define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
2687#define FIFO_THRESH_96B 0x60 /* 96 bytes */
2688#define FIFO_THRESH_112B 0x70 /* 112 bytes */
2689#define START_CTL 0x0C /* DMA start conditions */
2690#define START_CTL_TH 0x00 /* Wait threshold level (default) */
2691#define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
2692#define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
2693#define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
2694#define READ_CMD 0x03 /* Memory Read Method */
2695#define READ_CMD_MR 0x00 /* Memory Read */
2696#define READ_CMD_MRL 0x02 /* Memory Read Long */
2697#define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
1da177e4
LT
2698
2699/*
2700 * ASC-38C0800 RAM BIST Register bit definitions
2701 */
2702#define RAM_TEST_MODE 0x80
2703#define PRE_TEST_MODE 0x40
2704#define NORMAL_MODE 0x00
2705#define RAM_TEST_DONE 0x10
2706#define RAM_TEST_STATUS 0x0F
2707#define RAM_TEST_HOST_ERROR 0x08
2708#define RAM_TEST_INTRAM_ERROR 0x04
2709#define RAM_TEST_RISC_ERROR 0x02
2710#define RAM_TEST_SCSI_ERROR 0x01
2711#define RAM_TEST_SUCCESS 0x00
2712#define PRE_TEST_VALUE 0x05
2713#define NORMAL_VALUE 0x00
2714
2715/*
2716 * ASC38C1600 Definitions
2717 *
2718 * IOPB_PCI_INT_CFG Bit Field Definitions
2719 */
2720
27c868c2 2721#define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
1da177e4
LT
2722
2723/*
2724 * Bit 1 can be set to change the interrupt for the Function to operate in
2725 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
2726 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
2727 * mode, otherwise the operating mode is undefined.
2728 */
2729#define TOTEMPOLE 0x02
2730
2731/*
2732 * Bit 0 can be used to change the Int Pin for the Function. The value is
2733 * 0 by default for both Functions with Function 0 using INT A and Function
2734 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
2735 * INT A is used.
2736 *
2737 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
2738 * value specified in the PCI Configuration Space.
2739 */
2740#define INTAB 0x01
2741
2742/* a_advlib.h */
2743
2744/*
2745 * Adv Library Status Definitions
2746 */
2747#define ADV_TRUE 1
2748#define ADV_FALSE 0
2749#define ADV_NOERROR 1
2750#define ADV_SUCCESS 1
2751#define ADV_BUSY 0
2752#define ADV_ERROR (-1)
2753
1da177e4
LT
2754/*
2755 * ADV_DVC_VAR 'warn_code' values
2756 */
27c868c2
MW
2757#define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
2758#define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
2759#define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
2760#define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */
2761#define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
1da177e4 2762
27c868c2
MW
2763#define ADV_MAX_TID 15 /* max. target identifier */
2764#define ADV_MAX_LUN 7 /* max. logical unit number */
1da177e4
LT
2765
2766/*
2767 * Error code values are set in ADV_DVC_VAR 'err_code'.
2768 */
27c868c2
MW
2769#define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */
2770#define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
2771#define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */
2772#define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
2773#define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */
2774#define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
2775#define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */
2776#define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
2777#define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
2778#define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */
2779#define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */
2780#define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */
2781#define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */
2782#define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */
1da177e4
LT
2783
2784/*
2785 * Fixed locations of microcode operating variables.
2786 */
27c868c2
MW
2787#define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
2788#define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
2789#define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
2790#define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
2791#define ASC_MC_VERSION_NUM 0x003A /* microcode number */
2792#define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
2793#define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
2794#define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
2795#define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
2796#define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
2797#define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
2798#define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
2799#define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
1da177e4
LT
2800#define ASC_MC_CHIP_TYPE 0x009A
2801#define ASC_MC_INTRB_CODE 0x009B
2802#define ASC_MC_WDTR_ABLE 0x009C
2803#define ASC_MC_SDTR_ABLE 0x009E
2804#define ASC_MC_TAGQNG_ABLE 0x00A0
2805#define ASC_MC_DISC_ENABLE 0x00A2
2806#define ASC_MC_IDLE_CMD_STATUS 0x00A4
2807#define ASC_MC_IDLE_CMD 0x00A6
2808#define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
2809#define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
2810#define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
2811#define ASC_MC_DEFAULT_MEM_CFG 0x00B0
2812#define ASC_MC_DEFAULT_SEL_MASK 0x00B2
2813#define ASC_MC_SDTR_DONE 0x00B6
2814#define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
2815#define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
2816#define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
27c868c2 2817#define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
1da177e4 2818#define ASC_MC_WDTR_DONE 0x0124
27c868c2 2819#define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
1da177e4
LT
2820#define ASC_MC_ICQ 0x0160
2821#define ASC_MC_IRQ 0x0164
2822#define ASC_MC_PPR_ABLE 0x017A
2823
2824/*
2825 * BIOS LRAM variable absolute offsets.
2826 */
2827#define BIOS_CODESEG 0x54
2828#define BIOS_CODELEN 0x56
2829#define BIOS_SIGNATURE 0x58
2830#define BIOS_VERSION 0x5A
2831
2832/*
2833 * Microcode Control Flags
2834 *
2835 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2836 * and handled by the microcode.
2837 */
27c868c2
MW
2838#define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
2839#define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
1da177e4
LT
2840
2841/*
2842 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2843 */
2844#define HSHK_CFG_WIDE_XFR 0x8000
2845#define HSHK_CFG_RATE 0x0F00
2846#define HSHK_CFG_OFFSET 0x001F
2847
27c868c2
MW
2848#define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
2849#define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
2850#define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
2851#define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
2852
2853#define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2854#define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
2855#define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2856#define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
2857#define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2858
2859#define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
2860#define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
2861#define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
2862#define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
2863#define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
1da177e4
LT
2864/*
2865 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
2866 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
2867 */
27c868c2
MW
2868#define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
2869#define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
1da177e4
LT
2870
2871/*
2872 * All fields here are accessed by the board microcode and need to be
2873 * little-endian.
2874 */
27c868c2
MW
2875typedef struct adv_carr_t {
2876 ADV_VADDR carr_va; /* Carrier Virtual Address */
2877 ADV_PADDR carr_pa; /* Carrier Physical Address */
2878 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
2879 /*
2880 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
2881 *
2882 * next_vpa [3:1] Reserved Bits
2883 * next_vpa [0] Done Flag set in Response Queue.
2884 */
2885 ADV_VADDR next_vpa;
1da177e4
LT
2886} ADV_CARR_T;
2887
2888/*
2889 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2890 */
2891#define ASC_NEXT_VPA_MASK 0xFFFFFFF0
2892
2893#define ASC_RQ_DONE 0x00000001
2894#define ASC_RQ_GOOD 0x00000002
2895#define ASC_CQ_STOPPER 0x00000000
2896
2897#define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2898
2899#define ADV_CARRIER_NUM_PAGE_CROSSING \
2900 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2901 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2902
2903#define ADV_CARRIER_BUFSIZE \
2904 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2905
2906/*
2907 * ASC_SCSI_REQ_Q 'a_flag' definitions
2908 *
2909 * The Adv Library should limit use to the lower nibble (4 bits) of
2910 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2911 */
27c868c2
MW
2912#define ADV_POLL_REQUEST 0x01 /* poll for request completion */
2913#define ADV_SCSIQ_DONE 0x02 /* request done */
2914#define ADV_DONT_RETRY 0x08 /* don't do retry */
1da177e4 2915
27c868c2
MW
2916#define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
2917#define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
2918#define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
1da177e4
LT
2919
2920/*
2921 * Adapter temporary configuration structure
2922 *
2923 * This structure can be discarded after initialization. Don't add
2924 * fields here needed after initialization.
2925 *
2926 * Field naming convention:
2927 *
2928 * *_enable indicates the field enables or disables a feature. The
2929 * value of the field is never reset.
2930 */
2931typedef struct adv_dvc_cfg {
27c868c2
MW
2932 ushort disc_enable; /* enable disconnection */
2933 uchar chip_version; /* chip version */
2934 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2935 ushort lib_version; /* Adv Library version number */
2936 ushort control_flag; /* Microcode Control Flag */
2937 ushort mcode_date; /* Microcode date */
2938 ushort mcode_version; /* Microcode version */
2939 ushort pci_slot_info; /* high byte device/function number */
2940 /* bits 7-3 device num., bits 2-0 function num. */
2941 /* low byte bus num. */
2942 ushort serial1; /* EEPROM serial number word 1 */
2943 ushort serial2; /* EEPROM serial number word 2 */
2944 ushort serial3; /* EEPROM serial number word 3 */
2945 struct device *dev; /* pointer to the pci dev structure for this board */
1da177e4
LT
2946} ADV_DVC_CFG;
2947
2948struct adv_dvc_var;
2949struct adv_scsi_req_q;
2950
27c868c2
MW
2951typedef void (*ADV_ISR_CALLBACK)
2952 (struct adv_dvc_var *, struct adv_scsi_req_q *);
1da177e4 2953
27c868c2
MW
2954typedef void (*ADV_ASYNC_CALLBACK)
2955 (struct adv_dvc_var *, uchar);
1da177e4
LT
2956
2957/*
2958 * Adapter operation variable structure.
2959 *
2960 * One structure is required per host adapter.
2961 *
2962 * Field naming convention:
2963 *
2964 * *_able indicates both whether a feature should be enabled or disabled
2965 * and whether a device isi capable of the feature. At initialization
2966 * this field may be set, but later if a device is found to be incapable
2967 * of the feature, the field is cleared.
2968 */
2969typedef struct adv_dvc_var {
27c868c2
MW
2970 AdvPortAddr iop_base; /* I/O port address */
2971 ushort err_code; /* fatal error code */
2972 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
2973 ADV_ISR_CALLBACK isr_callback;
2974 ADV_ASYNC_CALLBACK async_callback;
2975 ushort wdtr_able; /* try WDTR for a device */
2976 ushort sdtr_able; /* try SDTR for a device */
2977 ushort ultra_able; /* try SDTR Ultra speed for a device */
2978 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
2979 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
2980 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
2981 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
2982 ushort tagqng_able; /* try tagged queuing with a device */
2983 ushort ppr_able; /* PPR message capable per TID bitmask. */
2984 uchar max_dvc_qng; /* maximum number of tagged commands per device */
2985 ushort start_motor; /* start motor command allowed */
2986 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
2987 uchar chip_no; /* should be assigned by caller */
2988 uchar max_host_qng; /* maximum number of Q'ed command allowed */
2989 uchar irq_no; /* IRQ number */
2990 ushort no_scam; /* scam_tolerant of EEPROM */
2991 struct asc_board *drv_ptr; /* driver pointer to private structure */
2992 uchar chip_scsi_id; /* chip SCSI target ID */
2993 uchar chip_type;
2994 uchar bist_err_code;
2995 ADV_CARR_T *carrier_buf;
2996 ADV_CARR_T *carr_freelist; /* Carrier free list. */
2997 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
2998 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
2999 ushort carr_pending_cnt; /* Count of pending carriers. */
3000 /*
3001 * Note: The following fields will not be used after initialization. The
3002 * driver may discard the buffer after initialization is done.
3003 */
3004 ADV_DVC_CFG *cfg; /* temporary configuration structure */
1da177e4
LT
3005} ADV_DVC_VAR;
3006
3007#define NO_OF_SG_PER_BLOCK 15
3008
3009typedef struct asc_sg_block {
27c868c2
MW
3010 uchar reserved1;
3011 uchar reserved2;
3012 uchar reserved3;
3013 uchar sg_cnt; /* Valid entries in block. */
3014 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
3015 struct {
3016 ADV_PADDR sg_addr; /* SG element address. */
3017 ADV_DCNT sg_count; /* SG element count. */
3018 } sg_list[NO_OF_SG_PER_BLOCK];
1da177e4
LT
3019} ADV_SG_BLOCK;
3020
3021/*
3022 * ADV_SCSI_REQ_Q - microcode request structure
3023 *
3024 * All fields in this structure up to byte 60 are used by the microcode.
3025 * The microcode makes assumptions about the size and ordering of fields
3026 * in this structure. Do not change the structure definition here without
3027 * coordinating the change with the microcode.
3028 *
3029 * All fields accessed by microcode must be maintained in little_endian
3030 * order.
3031 */
3032typedef struct adv_scsi_req_q {
27c868c2
MW
3033 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
3034 uchar target_cmd;
3035 uchar target_id; /* Device target identifier. */
3036 uchar target_lun; /* Device target logical unit number. */
3037 ADV_PADDR data_addr; /* Data buffer physical address. */
3038 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
3039 ADV_PADDR sense_addr;
3040 ADV_PADDR carr_pa;
3041 uchar mflag;
3042 uchar sense_len;
3043 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
3044 uchar scsi_cntl;
3045 uchar done_status; /* Completion status. */
3046 uchar scsi_status; /* SCSI status byte. */
3047 uchar host_status; /* Ucode host status. */
3048 uchar sg_working_ix;
3049 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
3050 ADV_PADDR sg_real_addr; /* SG list physical address. */
3051 ADV_PADDR scsiq_rptr;
3052 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
3053 ADV_VADDR scsiq_ptr;
3054 ADV_VADDR carr_va;
3055 /*
3056 * End of microcode structure - 60 bytes. The rest of the structure
3057 * is used by the Adv Library and ignored by the microcode.
3058 */
3059 ADV_VADDR srb_ptr;
3060 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
3061 char *vdata_addr; /* Data buffer virtual address. */
3062 uchar a_flag;
3063 uchar pad[2]; /* Pad out to a word boundary. */
1da177e4
LT
3064} ADV_SCSI_REQ_Q;
3065
3066/*
3067 * Microcode idle loop commands
3068 */
3069#define IDLE_CMD_COMPLETED 0
3070#define IDLE_CMD_STOP_CHIP 0x0001
3071#define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
3072#define IDLE_CMD_SEND_INT 0x0004
3073#define IDLE_CMD_ABORT 0x0008
3074#define IDLE_CMD_DEVICE_RESET 0x0010
27c868c2
MW
3075#define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
3076#define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
1da177e4
LT
3077#define IDLE_CMD_SCSIREQ 0x0080
3078
3079#define IDLE_CMD_STATUS_SUCCESS 0x0001
3080#define IDLE_CMD_STATUS_FAILURE 0x0002
3081
3082/*
3083 * AdvSendIdleCmd() flag definitions.
3084 */
3085#define ADV_NOWAIT 0x01
3086
3087/*
3088 * Wait loop time out values.
3089 */
27c868c2
MW
3090#define SCSI_WAIT_10_SEC 10UL /* 10 seconds */
3091#define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
3092#define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
3093#define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */
3094#define SCSI_MAX_RETRY 10 /* retry count */
1da177e4 3095
27c868c2
MW
3096#define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
3097#define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
3098#define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
3099#define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
1da177e4 3100
27c868c2 3101#define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
1da177e4
LT
3102
3103/*
3104 * Device drivers must define the following functions.
3105 */
27c868c2
MW
3106static inline ulong DvcEnterCritical(void);
3107static inline void DvcLeaveCritical(ulong);
3108static void DvcSleepMilliSecond(ADV_DCNT);
3109static uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
3110static void DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
3111static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
3112 uchar *, ASC_SDCNT *, int);
3113static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
1da177e4
LT
3114
3115/*
3116 * Adv Library functions available to drivers.
3117 */
27c868c2
MW
3118static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3119static int AdvISR(ADV_DVC_VAR *);
3120static int AdvInitGetConfig(ADV_DVC_VAR *);
3121static int AdvInitAsc3550Driver(ADV_DVC_VAR *);
3122static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
3123static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
3124static int AdvResetChipAndSB(ADV_DVC_VAR *);
3125static int AdvResetSB(ADV_DVC_VAR *asc_dvc);
1da177e4
LT
3126
3127/*
3128 * Internal Adv Library functions.
3129 */
27c868c2
MW
3130static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
3131static void AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3132static int AdvInitFrom3550EEP(ADV_DVC_VAR *);
3133static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
3134static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
3135static ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3136static void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3137static ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3138static void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3139static ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3140static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3141static void AdvWaitEEPCmd(AdvPortAddr);
3142static ushort AdvReadEEPWord(AdvPortAddr, int);
1da177e4
LT
3143
3144/*
3145 * PCI Bus Definitions
3146 */
3147#define AscPCICmdRegBits_BusMastering 0x0007
3148#define AscPCICmdRegBits_ParErrRespCtrl 0x0040
3149
3150/* Read byte from a register. */
3151#define AdvReadByteRegister(iop_base, reg_off) \
3152 (ADV_MEM_READB((iop_base) + (reg_off)))
3153
3154/* Write byte to a register. */
3155#define AdvWriteByteRegister(iop_base, reg_off, byte) \
3156 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3157
3158/* Read word (2 bytes) from a register. */
3159#define AdvReadWordRegister(iop_base, reg_off) \
3160 (ADV_MEM_READW((iop_base) + (reg_off)))
3161
3162/* Write word (2 bytes) to a register. */
3163#define AdvWriteWordRegister(iop_base, reg_off, word) \
3164 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
3165
3166/* Write dword (4 bytes) to a register. */
3167#define AdvWriteDWordRegister(iop_base, reg_off, dword) \
3168 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
3169
3170/* Read byte from LRAM. */
3171#define AdvReadByteLram(iop_base, addr, byte) \
3172do { \
3173 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3174 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3175} while (0)
3176
3177/* Write byte to LRAM. */
3178#define AdvWriteByteLram(iop_base, addr, byte) \
3179 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3180 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3181
3182/* Read word (2 bytes) from LRAM. */
3183#define AdvReadWordLram(iop_base, addr, word) \
3184do { \
3185 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3186 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3187} while (0)
3188
3189/* Write word (2 bytes) to LRAM. */
3190#define AdvWriteWordLram(iop_base, addr, word) \
3191 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3192 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3193
3194/* Write little-endian double word (4 bytes) to LRAM */
3195/* Because of unspecified C language ordering don't use auto-increment. */
3196#define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
3197 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3198 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3199 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3200 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3201 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3202 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3203
3204/* Read word (2 bytes) from LRAM assuming that the address is already set. */
3205#define AdvReadWordAutoIncLram(iop_base) \
3206 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3207
3208/* Write word (2 bytes) to LRAM assuming that the address is already set. */
3209#define AdvWriteWordAutoIncLram(iop_base, word) \
3210 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3211
1da177e4
LT
3212/*
3213 * Define macro to check for Condor signature.
3214 *
3215 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3216 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3217 */
3218#define AdvFindSignature(iop_base) \
3219 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3220 ADV_CHIP_ID_BYTE) && \
3221 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3222 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
3223
3224/*
3225 * Define macro to Return the version number of the chip at 'iop_base'.
3226 *
3227 * The second parameter 'bus_type' is currently unused.
3228 */
3229#define AdvGetChipVersion(iop_base, bus_type) \
3230 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3231
3232/*
3233 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3234 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3235 *
3236 * If the request has not yet been sent to the device it will simply be
3237 * aborted from RISC memory. If the request is disconnected it will be
3238 * aborted on reselection by sending an Abort Message to the target ID.
3239 *
3240 * Return value:
3241 * ADV_TRUE(1) - Queue was successfully aborted.
3242 * ADV_FALSE(0) - Queue was not found on the active queue list.
3243 */
3244#define AdvAbortQueue(asc_dvc, scsiq) \
3245 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3246 (ADV_DCNT) (scsiq))
3247
3248/*
3249 * Send a Bus Device Reset Message to the specified target ID.
3250 *
3251 * All outstanding commands will be purged if sending the
3252 * Bus Device Reset Message is successful.
3253 *
3254 * Return Value:
3255 * ADV_TRUE(1) - All requests on the target are purged.
3256 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3257 * are not purged.
3258 */
3259#define AdvResetDevice(asc_dvc, target_id) \
3260 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3261 (ADV_DCNT) (target_id))
3262
3263/*
3264 * SCSI Wide Type definition.
3265 */
3266#define ADV_SCSI_BIT_ID_TYPE ushort
3267
3268/*
3269 * AdvInitScsiTarget() 'cntl_flag' options.
3270 */
3271#define ADV_SCAN_LUN 0x01
3272#define ADV_CAPINFO_NOLUN 0x02
3273
3274/*
3275 * Convert target id to target id bit mask.
3276 */
3277#define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
3278
3279/*
3280 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3281 */
3282
27c868c2 3283#define QD_NO_STATUS 0x00 /* Request not completed yet. */
1da177e4
LT
3284#define QD_NO_ERROR 0x01
3285#define QD_ABORTED_BY_HOST 0x02
3286#define QD_WITH_ERROR 0x04
3287
3288#define QHSTA_NO_ERROR 0x00
3289#define QHSTA_M_SEL_TIMEOUT 0x11
3290#define QHSTA_M_DATA_OVER_RUN 0x12
3291#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3292#define QHSTA_M_QUEUE_ABORTED 0x15
27c868c2
MW
3293#define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
3294#define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
3295#define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
3296#define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
3297#define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
3298#define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
3299#define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
1da177e4 3300/* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
27c868c2
MW
3301#define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
3302#define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
3303#define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
3304#define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
3305#define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
3306#define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
3307#define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
3308#define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
1da177e4
LT
3309#define QHSTA_M_WTM_TIMEOUT 0x41
3310#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
3311#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
3312#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
27c868c2
MW
3313#define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
3314#define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
3315#define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
1da177e4
LT
3316
3317/*
3318 * Default EEPROM Configuration structure defined in a_init.c.
3319 */
3320static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
3321static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
3322static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
3323
3324/*
3325 * DvcGetPhyAddr() flag arguments
3326 */
27c868c2
MW
3327#define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
3328#define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
3329#define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
3330#define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
3331#define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
3332#define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
1da177e4
LT
3333
3334/* Return the address that is aligned at the next doubleword >= to 'addr'. */
3335#define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
3336#define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
3337#define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
3338
3339/*
3340 * Total contiguous memory needed for driver SG blocks.
3341 *
3342 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3343 * number of scatter-gather elements the driver supports in a
3344 * single request.
3345 */
3346
3347#define ADV_SG_LIST_MAX_BYTE_SIZE \
3348 (sizeof(ADV_SG_BLOCK) * \
3349 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3350
3351/*
3352 * Inquiry data structure and bitfield macros
3353 *
3354 * Using bitfields to access the subchar data isn't portable across
3355 * endianness, so instead mask and shift. Only quantities of more
3356 * than 1 bit are shifted, since the others are just tested for true
3357 * or false.
3358 */
3359
3360#define ADV_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f)
3361#define ADV_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5)
3362#define ADV_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f)
3363#define ADV_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80)
3364#define ADV_INQ_ANSI_VER(inq) ((inq)->ver & 0x07)
3365#define ADV_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3)
3366#define ADV_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6)
3367#define ADV_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f)
3368#define ADV_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40)
3369#define ADV_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80)
3370#define ADV_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01)
3371#define ADV_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02)
3372#define ADV_INQ_LINK_CMD(inq) ((inq)->flags & 0x08)
3373#define ADV_INQ_SYNC(inq) ((inq)->flags & 0x10)
3374#define ADV_INQ_WIDE16(inq) ((inq)->flags & 0x20)
3375#define ADV_INQ_WIDE32(inq) ((inq)->flags & 0x40)
3376#define ADV_INQ_REL_ADDR(inq) ((inq)->flags & 0x80)
3377#define ADV_INQ_INFO_UNIT(inq) ((inq)->info & 0x01)
3378#define ADV_INQ_QUICK_ARB(inq) ((inq)->info & 0x02)
3379#define ADV_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2)
3380
3381typedef struct {
27c868c2
MW
3382 uchar periph; /* peripheral device type [0:4] */
3383 /* peripheral qualifier [5:7] */
3384 uchar devtype; /* device type modifier (for SCSI I) [0:6] */
3385 /* RMB - removable medium bit [7] */
3386 uchar ver; /* ANSI approved version [0:2] */
3387 /* ECMA version [3:5] */
3388 /* ISO version [6:7] */
3389 uchar byte3; /* response data format [0:3] */
3390 /* 0 SCSI 1 */
3391 /* 1 CCS */
3392 /* 2 SCSI-2 */
3393 /* 3-F reserved */
3394 /* reserved [4:5] */
3395 /* terminate I/O process bit (see 5.6.22) [6] */
3396 /* asynch. event notification (processor) [7] */
3397 uchar add_len; /* additional length */
3398 uchar res1; /* reserved */
3399 uchar res2; /* reserved */
3400 uchar flags; /* soft reset implemented [0] */
3401 /* command queuing [1] */
3402 /* reserved [2] */
3403 /* linked command for this logical unit [3] */
3404 /* synchronous data transfer [4] */
3405 /* wide bus 16 bit data transfer [5] */
3406 /* wide bus 32 bit data transfer [6] */
3407 /* relative addressing mode [7] */
3408 uchar vendor_id[8]; /* vendor identification */
3409 uchar product_id[16]; /* product identification */
3410 uchar product_rev_level[4]; /* product revision level */
3411 uchar vendor_specific[20]; /* vendor specific */
3412 uchar info; /* information unit supported [0] */
3413 /* quick arbitrate supported [1] */
3414 /* clocking field [2:3] */
3415 /* reserved [4:7] */
3416 uchar res3; /* reserved */
3417} ADV_SCSI_INQUIRY; /* 58 bytes */
1da177e4
LT
3418
3419/*
3420 * --- Driver Constants and Macros
3421 */
3422
3423#define ASC_NUM_BOARD_SUPPORTED 16
3424#define ASC_NUM_IOPORT_PROBE 4
3425#define ASC_NUM_BUS 4
3426
3427/* Reference Scsi_Host hostdata */
3428#define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3429
3430/* asc_board_t flags */
3431#define ASC_HOST_IN_RESET 0x01
27c868c2 3432#define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
1da177e4
LT
3433#define ASC_SELECT_QUEUE_DEPTHS 0x08
3434
3435#define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3436#define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD)
3437
27c868c2 3438#define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
1da177e4 3439
27c868c2 3440#define ASC_INFO_SIZE 128 /* advansys_info() line size */
1da177e4
LT
3441
3442#ifdef CONFIG_PROC_FS
3443/* /proc/scsi/advansys/[0...] related definitions */
3444#define ASC_PRTBUF_SIZE 2048
3445#define ASC_PRTLINE_SIZE 160
3446
3447#define ASC_PRT_NEXT() \
3448 if (cp) { \
3449 totlen += len; \
3450 leftlen -= len; \
3451 if (leftlen == 0) { \
3452 return totlen; \
3453 } \
3454 cp += len; \
3455 }
3456#endif /* CONFIG_PROC_FS */
3457
3458/* Asc Library return codes */
3459#define ASC_TRUE 1
3460#define ASC_FALSE 0
3461#define ASC_NOERROR 1
3462#define ASC_BUSY 0
3463#define ASC_ERROR (-1)
3464
3465/* struct scsi_cmnd function return codes */
3466#define STATUS_BYTE(byte) (byte)
3467#define MSG_BYTE(byte) ((byte) << 8)
3468#define HOST_BYTE(byte) ((byte) << 16)
3469#define DRIVER_BYTE(byte) ((byte) << 24)
3470
3471/*
3472 * The following definitions and macros are OS independent interfaces to
3473 * the queue functions:
3474 * REQ - SCSI request structure
3475 * REQP - pointer to SCSI request structure
3476 * REQPTID(reqp) - reqp's target id
3477 * REQPNEXT(reqp) - reqp's next pointer
3478 * REQPNEXTP(reqp) - pointer to reqp's next pointer
3479 * REQPTIME(reqp) - reqp's time stamp value
3480 * REQTIMESTAMP() - system time stamp value
3481 */
27c868c2 3482typedef struct scsi_cmnd REQ, *REQP;
1da177e4
LT
3483#define REQPNEXT(reqp) ((REQP) ((reqp)->host_scribble))
3484#define REQPNEXTP(reqp) ((REQP *) &((reqp)->host_scribble))
3485#define REQPTID(reqp) ((reqp)->device->id)
3486#define REQPTIME(reqp) ((reqp)->SCp.this_residual)
3487#define REQTIMESTAMP() (jiffies)
3488
3489#define REQTIMESTAT(function, ascq, reqp, tid) \
3490{ \
3491 /*
3492 * If the request time stamp is less than the system time stamp, then \
3493 * maybe the system time stamp wrapped. Set the request time to zero.\
3494 */ \
3495 if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3496 REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3497 } else { \
3498 /* Indicate an error occurred with the assertion. */ \
3499 ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3500 REQPTIME(reqp) = 0; \
3501 } \
3502 /* Handle first minimum time case without external initialization. */ \
3503 if (((ascq)->q_tot_cnt[tid] == 1) || \
3504 (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3505 (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3506 ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3507 (function), (tid), (ascq)->q_min_tim[tid]); \
3508 } \
3509 if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3510 (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3511 ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3512 (function), tid, (ascq)->q_max_tim[tid]); \
3513 } \
3514 (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3515 /* Reset the time stamp field. */ \
3516 REQPTIME(reqp) = 0; \
3517}
3518
3519/* asc_enqueue() flags */
3520#define ASC_FRONT 1
3521#define ASC_BACK 2
3522
3523/* asc_dequeue_list() argument */
3524#define ASC_TID_ALL (-1)
3525
3526/* Return non-zero, if the queue is empty. */
3527#define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0)
3528
3529#define PCI_MAX_SLOT 0x1F
3530#define PCI_MAX_BUS 0xFF
3531#define PCI_IOADDRESS_MASK 0xFFFE
27c868c2 3532#define ASC_PCI_DEVICE_ID_CNT 6 /* PCI Device ID count. */
1da177e4
LT
3533
3534#ifndef ADVANSYS_STATS
27c868c2
MW
3535#define ASC_STATS(shost, counter)
3536#define ASC_STATS_ADD(shost, counter, count)
1da177e4 3537#else /* ADVANSYS_STATS */
27c868c2
MW
3538#define ASC_STATS(shost, counter) \
3539 (ASC_BOARDP(shost)->asc_stats.counter++)
1da177e4 3540
27c868c2
MW
3541#define ASC_STATS_ADD(shost, counter, count) \
3542 (ASC_BOARDP(shost)->asc_stats.counter += (count))
1da177e4
LT
3543#endif /* ADVANSYS_STATS */
3544
3545#define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3546
3547/* If the result wraps when calculating tenths, return 0. */
3548#define ASC_TENTHS(num, den) \
3549 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3550 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3551
3552/*
3553 * Display a message to the console.
3554 */
3555#define ASC_PRINT(s) \
3556 { \
3557 printk("advansys: "); \
3558 printk(s); \
3559 }
3560
3561#define ASC_PRINT1(s, a1) \
3562 { \
3563 printk("advansys: "); \
3564 printk((s), (a1)); \
3565 }
3566
3567#define ASC_PRINT2(s, a1, a2) \
3568 { \
3569 printk("advansys: "); \
3570 printk((s), (a1), (a2)); \
3571 }
3572
3573#define ASC_PRINT3(s, a1, a2, a3) \
3574 { \
3575 printk("advansys: "); \
3576 printk((s), (a1), (a2), (a3)); \
3577 }
3578
3579#define ASC_PRINT4(s, a1, a2, a3, a4) \
3580 { \
3581 printk("advansys: "); \
3582 printk((s), (a1), (a2), (a3), (a4)); \
3583 }
3584
1da177e4
LT
3585#ifndef ADVANSYS_DEBUG
3586
3587#define ASC_DBG(lvl, s)
3588#define ASC_DBG1(lvl, s, a1)
3589#define ASC_DBG2(lvl, s, a1, a2)
3590#define ASC_DBG3(lvl, s, a1, a2, a3)
3591#define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3592#define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3593#define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3594#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3595#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3596#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3597#define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3598#define ASC_DBG_PRT_HEX(lvl, name, start, length)
3599#define ASC_DBG_PRT_CDB(lvl, cdb, len)
3600#define ASC_DBG_PRT_SENSE(lvl, sense, len)
3601#define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3602
3603#else /* ADVANSYS_DEBUG */
3604
3605/*
3606 * Debugging Message Levels:
3607 * 0: Errors Only
3608 * 1: High-Level Tracing
3609 * 2-N: Verbose Tracing
3610 */
3611
3612#define ASC_DBG(lvl, s) \
3613 { \
3614 if (asc_dbglvl >= (lvl)) { \
3615 printk(s); \
3616 } \
3617 }
3618
3619#define ASC_DBG1(lvl, s, a1) \
3620 { \
3621 if (asc_dbglvl >= (lvl)) { \
3622 printk((s), (a1)); \
3623 } \
3624 }
3625
3626#define ASC_DBG2(lvl, s, a1, a2) \
3627 { \
3628 if (asc_dbglvl >= (lvl)) { \
3629 printk((s), (a1), (a2)); \
3630 } \
3631 }
3632
3633#define ASC_DBG3(lvl, s, a1, a2, a3) \
3634 { \
3635 if (asc_dbglvl >= (lvl)) { \
3636 printk((s), (a1), (a2), (a3)); \
3637 } \
3638 }
3639
3640#define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3641 { \
3642 if (asc_dbglvl >= (lvl)) { \
3643 printk((s), (a1), (a2), (a3), (a4)); \
3644 } \
3645 }
3646
3647#define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3648 { \
3649 if (asc_dbglvl >= (lvl)) { \
3650 asc_prt_scsi_host(s); \
3651 } \
3652 }
3653
3654#define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3655 { \
3656 if (asc_dbglvl >= (lvl)) { \
3657 asc_prt_scsi_cmnd(s); \
3658 } \
3659 }
3660
3661#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3662 { \
3663 if (asc_dbglvl >= (lvl)) { \
3664 asc_prt_asc_scsi_q(scsiqp); \
3665 } \
3666 }
3667
3668#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3669 { \
3670 if (asc_dbglvl >= (lvl)) { \
3671 asc_prt_asc_qdone_info(qdone); \
3672 } \
3673 }
3674
3675#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3676 { \
3677 if (asc_dbglvl >= (lvl)) { \
3678 asc_prt_adv_scsi_req_q(scsiqp); \
3679 } \
3680 }
3681
3682#define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3683 { \
3684 if (asc_dbglvl >= (lvl)) { \
3685 asc_prt_hex((name), (start), (length)); \
3686 } \
3687 }
3688
3689#define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3690 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3691
3692#define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3693 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3694
3695#define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3696 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3697#endif /* ADVANSYS_DEBUG */
3698
3699#ifndef ADVANSYS_ASSERT
3700#define ASC_ASSERT(a)
3701#else /* ADVANSYS_ASSERT */
3702
3703#define ASC_ASSERT(a) \
3704 { \
3705 if (!(a)) { \
3706 printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3707 __FILE__, __LINE__); \
3708 } \
3709 }
3710
3711#endif /* ADVANSYS_ASSERT */
3712
1da177e4
LT
3713/*
3714 * --- Driver Structures
3715 */
3716
3717#ifdef ADVANSYS_STATS
3718
3719/* Per board statistics structure */
3720struct asc_stats {
27c868c2
MW
3721 /* Driver Entrypoint Statistics */
3722 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
3723 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
3724 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
3725 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
3726 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
3727 ADV_DCNT done; /* # calls to request's scsi_done function */
3728 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
3729 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
3730 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
3731 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3732 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
3733 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
3734 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
3735 ADV_DCNT exe_unknown; /* # unknown returns. */
3736 /* Data Transfer Statistics */
3737 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
3738 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
3739 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
3740 ADV_DCNT sg_elem; /* # scatter-gather elements */
3741 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
1da177e4
LT
3742};
3743#endif /* ADVANSYS_STATS */
3744
3745/*
3746 * Request queuing structure
3747 */
3748typedef struct asc_queue {
27c868c2
MW
3749 ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */
3750 REQP q_first[ADV_MAX_TID + 1]; /* first queued request */
3751 REQP q_last[ADV_MAX_TID + 1]; /* last queued request */
1da177e4 3752#ifdef ADVANSYS_STATS
27c868c2
MW
3753 short q_cur_cnt[ADV_MAX_TID + 1]; /* current queue count */
3754 short q_max_cnt[ADV_MAX_TID + 1]; /* maximum queue count */
3755 ADV_DCNT q_tot_cnt[ADV_MAX_TID + 1]; /* total enqueue count */
3756 ADV_DCNT q_tot_tim[ADV_MAX_TID + 1]; /* total time queued */
3757 ushort q_max_tim[ADV_MAX_TID + 1]; /* maximum time queued */
3758 ushort q_min_tim[ADV_MAX_TID + 1]; /* minimum time queued */
3759#endif /* ADVANSYS_STATS */
1da177e4
LT
3760} asc_queue_t;
3761
3762/*
3763 * Adv Library Request Structures
3764 *
3765 * The following two structures are used to process Wide Board requests.
3766 *
3767 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
3768 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
3769 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
3770 * Mid-Level SCSI request structure.
3771 *
3772 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
3773 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
3774 * up to 255 scatter-gather elements may be used per request or
3775 * ADV_SCSI_REQ_Q.
3776 *
3777 * Both structures must be 32 byte aligned.
3778 */
3779typedef struct adv_sgblk {
27c868c2
MW
3780 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
3781 uchar align[32]; /* Sgblock structure padding. */
3782 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
1da177e4
LT
3783} adv_sgblk_t;
3784
3785typedef struct adv_req {
27c868c2
MW
3786 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
3787 uchar align[32]; /* Request structure padding. */
3788 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
3789 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
3790 struct adv_req *next_reqp; /* Next Request Structure. */
1da177e4
LT
3791} adv_req_t;
3792
3793/*
3794 * Structure allocated for each board.
3795 *
8dfb5379 3796 * This structure is allocated by scsi_host_alloc() at the end
1da177e4
LT
3797 * of the 'Scsi_Host' structure starting at the 'hostdata'
3798 * field. It is guaranteed to be allocated from DMA-able memory.
3799 */
3800typedef struct asc_board {
27c868c2
MW
3801 int id; /* Board Id */
3802 uint flags; /* Board flags */
3803 union {
3804 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
3805 ADV_DVC_VAR adv_dvc_var; /* Wide board */
3806 } dvc_var;
3807 union {
3808 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
3809 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
3810 } dvc_cfg;
3811 ushort asc_n_io_port; /* Number I/O ports. */
3812 asc_queue_t active; /* Active command queue */
3813 asc_queue_t waiting; /* Waiting command queue */
3814 asc_queue_t done; /* Done command queue */
3815 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
3816 struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */
3817 ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
3818 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
3819 ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
3820 union {
3821 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
3822 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
3823 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
3824 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
3825 } eep_config;
3826 ulong last_reset; /* Saved last reset time */
3827 spinlock_t lock; /* Board spinlock */
27c868c2
MW
3828 /* /proc/scsi/advansys/[0...] */
3829 char *prtbuf; /* /proc print buffer */
1da177e4 3830#ifdef ADVANSYS_STATS
27c868c2
MW
3831 struct asc_stats asc_stats; /* Board statistics */
3832#endif /* ADVANSYS_STATS */
3833 /*
3834 * The following fields are used only for Narrow Boards.
3835 */
3836 /* The following three structures must be in DMA-able memory. */
3837 ASC_SCSI_REQ_Q scsireqq;
3838 ASC_CAP_INFO cap_info;
3839 ASC_SCSI_INQUIRY inquiry;
3840 uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */
3841 /*
3842 * The following fields are used only for Wide Boards.
3843 */
3844 void __iomem *ioremap_addr; /* I/O Memory remap address. */
3845 ushort ioport; /* I/O Port address. */
b2c16f58 3846 ADV_CARR_T *carrp; /* ADV_CARR_T memory block. */
27c868c2
MW
3847 adv_req_t *orig_reqp; /* adv_req_t memory block. */
3848 adv_req_t *adv_reqp; /* Request structures. */
3849 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
3850 ushort bios_signature; /* BIOS Signature. */
3851 ushort bios_version; /* BIOS Version. */
3852 ushort bios_codeseg; /* BIOS Code Segment. */
3853 ushort bios_codelen; /* BIOS Code Segment Length. */
1da177e4
LT
3854} asc_board_t;
3855
3856/*
3857 * PCI configuration structures
3858 */
27c868c2
MW
3859typedef struct _PCI_DATA_ {
3860 uchar type;
3861 uchar bus;
3862 uchar slot;
3863 uchar func;
3864 uchar offset;
1da177e4
LT
3865} PCI_DATA;
3866
27c868c2
MW
3867typedef struct _PCI_DEVICE_ {
3868 ushort vendorID;
3869 ushort deviceID;
3870 ushort slotNumber;
3871 ushort slotFound;
3872 uchar busNumber;
3873 uchar maxBusNumber;
3874 uchar devFunc;
3875 ushort startSlot;
3876 ushort endSlot;
3877 uchar bridge;
3878 uchar type;
1da177e4
LT
3879} PCI_DEVICE;
3880
27c868c2
MW
3881typedef struct _PCI_CONFIG_SPACE_ {
3882 ushort vendorID;
3883 ushort deviceID;
3884 ushort command;
3885 ushort status;
3886 uchar revision;
3887 uchar classCode[3];
3888 uchar cacheSize;
3889 uchar latencyTimer;
3890 uchar headerType;
3891 uchar bist;
3892 ADV_PADDR baseAddress[6];
3893 ushort reserved[4];
3894 ADV_PADDR optionRomAddr;
3895 ushort reserved2[4];
3896 uchar irqLine;
3897 uchar irqPin;
3898 uchar minGnt;
3899 uchar maxLatency;
1da177e4
LT
3900} PCI_CONFIG_SPACE;
3901
1da177e4
LT
3902/*
3903 * --- Driver Data
3904 */
3905
3906/* Note: All driver global data should be initialized. */
3907
3908/* Number of boards detected in system. */
27c868c2
MW
3909static int asc_board_count = 0;
3910static struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { NULL };
1da177e4
LT
3911
3912/* Overrun buffer used by all narrow boards. */
27c868c2 3913static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
1da177e4
LT
3914
3915/*
3916 * Global structures required to issue a command.
3917 */
27c868c2
MW
3918static ASC_SCSI_Q asc_scsi_q = { {0} };
3919static ASC_SG_HEAD asc_sg_head = { 0 };
1da177e4
LT
3920
3921/* List of supported bus types. */
27c868c2
MW
3922static ushort asc_bus[ASC_NUM_BUS] __initdata = {
3923 ASC_IS_ISA,
3924 ASC_IS_VL,
3925 ASC_IS_EISA,
3926 ASC_IS_PCI,
1da177e4
LT
3927};
3928
27c868c2
MW
3929static int asc_iopflag = ASC_FALSE;
3930static int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
1da177e4
LT
3931
3932#ifdef ADVANSYS_DEBUG
27c868c2
MW
3933static char *asc_bus_name[ASC_NUM_BUS] = {
3934 "ASC_IS_ISA",
3935 "ASC_IS_VL",
3936 "ASC_IS_EISA",
3937 "ASC_IS_PCI",
1da177e4
LT
3938};
3939
27c868c2 3940static int asc_dbglvl = 3;
1da177e4
LT
3941#endif /* ADVANSYS_DEBUG */
3942
3943/* Declaration for Asc Library internal data referenced by driver. */
27c868c2 3944static PortAddr _asc_def_iop_base[];
1da177e4
LT
3945
3946/*
3947 * --- Driver Function Prototypes
3948 *
3949 * advansys.h contains function prototypes for functions global to Linux.
3950 */
3951
27c868c2
MW
3952static int advansys_slave_configure(struct scsi_device *);
3953static void asc_scsi_done_list(struct scsi_cmnd *);
3954static int asc_execute_scsi_cmnd(struct scsi_cmnd *);
3955static int asc_build_req(asc_board_t *, struct scsi_cmnd *);
3956static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
3957static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
3958static void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
3959static void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3960static void adv_async_callback(ADV_DVC_VAR *, uchar);
3961static void asc_enqueue(asc_queue_t *, REQP, int);
3962static REQP asc_dequeue(asc_queue_t *, int);
3963static REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
3964static int asc_rmqueue(asc_queue_t *, REQP);
3965static void asc_execute_queue(asc_queue_t *);
1da177e4 3966#ifdef CONFIG_PROC_FS
27c868c2
MW
3967static int asc_proc_copy(off_t, off_t, char *, int, char *, int);
3968static int asc_prt_board_devices(struct Scsi_Host *, char *, int);
3969static int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
3970static int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
3971static int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
3972static int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
3973static int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
3974static int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
3975static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
3976static int asc_prt_line(char *, int, char *fmt, ...);
1da177e4
LT
3977#endif /* CONFIG_PROC_FS */
3978
3979/* Declaration for Asc Library internal functions referenced by driver. */
27c868c2
MW
3980static int AscFindSignature(PortAddr);
3981static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1da177e4
LT
3982
3983/* Statistics function prototypes. */
3984#ifdef ADVANSYS_STATS
3985#ifdef CONFIG_PROC_FS
27c868c2
MW
3986static int asc_prt_board_stats(struct Scsi_Host *, char *, int);
3987static int asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
1da177e4
LT
3988#endif /* CONFIG_PROC_FS */
3989#endif /* ADVANSYS_STATS */
3990
3991/* Debug function prototypes. */
3992#ifdef ADVANSYS_DEBUG
27c868c2
MW
3993static void asc_prt_scsi_host(struct Scsi_Host *);
3994static void asc_prt_scsi_cmnd(struct scsi_cmnd *);
3995static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
3996static void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
3997static void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
3998static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
3999static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
4000static void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
4001static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
4002static void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
4003static void asc_prt_hex(char *f, uchar *, int);
1da177e4
LT
4004#endif /* ADVANSYS_DEBUG */
4005
1da177e4
LT
4006#ifdef CONFIG_PROC_FS
4007/*
4008 * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
4009 *
4010 * *buffer: I/O buffer
4011 * **start: if inout == FALSE pointer into buffer where user read should start
4012 * offset: current offset into a /proc/scsi/advansys/[0...] file
4013 * length: length of buffer
4014 * hostno: Scsi_Host host_no
4015 * inout: TRUE - user is writing; FALSE - user is reading
4016 *
4017 * Return the number of bytes read from or written to a
4018 * /proc/scsi/advansys/[0...] file.
4019 *
4020 * Note: This function uses the per board buffer 'prtbuf' which is
4021 * allocated when the board is initialized in advansys_detect(). The
4022 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
4023 * used to write to the buffer. The way asc_proc_copy() is written
4024 * if 'prtbuf' is too small it will not be overwritten. Instead the
4025 * user just won't get all the available statistics.
4026 */
70c8d897 4027static int
1da177e4 4028advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
27c868c2 4029 off_t offset, int length, int inout)
1da177e4 4030{
27c868c2 4031 asc_board_t *boardp;
27c868c2
MW
4032 char *cp;
4033 int cplen;
4034 int cnt;
4035 int totcnt;
4036 int leftlen;
4037 char *curbuf;
4038 off_t advoffset;
1da177e4 4039#ifdef ADVANSYS_STATS
27c868c2 4040 int tgt_id;
1da177e4
LT
4041#endif /* ADVANSYS_STATS */
4042
27c868c2 4043 ASC_DBG(1, "advansys_proc_info: begin\n");
1da177e4 4044
27c868c2
MW
4045 /*
4046 * User write not supported.
4047 */
4048 if (inout == TRUE) {
4049 return (-ENOSYS);
4050 }
1da177e4 4051
27c868c2
MW
4052 /*
4053 * User read of /proc/scsi/advansys/[0...] file.
4054 */
1da177e4 4055
2a437959 4056 boardp = ASC_BOARDP(shost);
27c868c2
MW
4057
4058 /* Copy read data starting at the beginning of the buffer. */
4059 *start = buffer;
4060 curbuf = buffer;
4061 advoffset = 0;
4062 totcnt = 0;
4063 leftlen = length;
4064
4065 /*
4066 * Get board configuration information.
4067 *
4068 * advansys_info() returns the board string from its own static buffer.
4069 */
2a437959 4070 cp = (char *)advansys_info(shost);
27c868c2
MW
4071 strcat(cp, "\n");
4072 cplen = strlen(cp);
4073 /* Copy board information. */
4074 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4075 totcnt += cnt;
4076 leftlen -= cnt;
4077 if (leftlen == 0) {
4078 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4079 return totcnt;
4080 }
4081 advoffset += cplen;
4082 curbuf += cnt;
4083
4084 /*
4085 * Display Wide Board BIOS Information.
4086 */
4087 if (ASC_WIDE_BOARD(boardp)) {
4088 cp = boardp->prtbuf;
2a437959 4089 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
4090 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4091 cnt =
4092 asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
4093 cplen);
4094 totcnt += cnt;
4095 leftlen -= cnt;
4096 if (leftlen == 0) {
4097 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4098 return totcnt;
4099 }
4100 advoffset += cplen;
4101 curbuf += cnt;
4102 }
1da177e4 4103
27c868c2
MW
4104 /*
4105 * Display driver information for each device attached to the board.
4106 */
4107 cp = boardp->prtbuf;
2a437959 4108 cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
4109 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4110 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4111 totcnt += cnt;
4112 leftlen -= cnt;
4113 if (leftlen == 0) {
4114 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4115 return totcnt;
4116 }
4117 advoffset += cplen;
4118 curbuf += cnt;
4119
4120 /*
4121 * Display EEPROM configuration for the board.
4122 */
4123 cp = boardp->prtbuf;
4124 if (ASC_NARROW_BOARD(boardp)) {
2a437959 4125 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 4126 } else {
2a437959 4127 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
4128 }
4129 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4130 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4131 totcnt += cnt;
4132 leftlen -= cnt;
4133 if (leftlen == 0) {
4134 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4135 return totcnt;
4136 }
4137 advoffset += cplen;
4138 curbuf += cnt;
4139
4140 /*
4141 * Display driver configuration and information for the board.
4142 */
4143 cp = boardp->prtbuf;
2a437959 4144 cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
4145 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4146 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4147 totcnt += cnt;
4148 leftlen -= cnt;
4149 if (leftlen == 0) {
4150 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4151 return totcnt;
4152 }
4153 advoffset += cplen;
4154 curbuf += cnt;
1da177e4
LT
4155
4156#ifdef ADVANSYS_STATS
27c868c2
MW
4157 /*
4158 * Display driver statistics for the board.
4159 */
4160 cp = boardp->prtbuf;
2a437959 4161 cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
4162 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4163 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4164 totcnt += cnt;
4165 leftlen -= cnt;
4166 if (leftlen == 0) {
4167 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4168 return totcnt;
4169 }
4170 advoffset += cplen;
4171 curbuf += cnt;
4172
4173 /*
4174 * Display driver statistics for each target.
4175 */
4176 for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
4177 cp = boardp->prtbuf;
2a437959
MW
4178 cplen = asc_prt_target_stats(shost, tgt_id, cp,
4179 ASC_PRTBUF_SIZE);
27c868c2
MW
4180 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4181 cnt =
4182 asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
4183 cplen);
4184 totcnt += cnt;
4185 leftlen -= cnt;
4186 if (leftlen == 0) {
4187 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4188 return totcnt;
4189 }
4190 advoffset += cplen;
4191 curbuf += cnt;
4192 }
1da177e4
LT
4193#endif /* ADVANSYS_STATS */
4194
27c868c2
MW
4195 /*
4196 * Display Asc Library dynamic configuration information
4197 * for the board.
4198 */
4199 cp = boardp->prtbuf;
4200 if (ASC_NARROW_BOARD(boardp)) {
2a437959 4201 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 4202 } else {
2a437959 4203 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
4204 }
4205 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4206 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4207 totcnt += cnt;
4208 leftlen -= cnt;
4209 if (leftlen == 0) {
4210 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4211 return totcnt;
4212 }
4213 advoffset += cplen;
4214 curbuf += cnt;
1da177e4 4215
27c868c2 4216 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
1da177e4 4217
27c868c2 4218 return totcnt;
1da177e4 4219}
1da177e4 4220#endif /* CONFIG_PROC_FS */
1da177e4
LT
4221
4222/*
4223 * advansys_info()
4224 *
4225 * Return suitable for printing on the console with the argument
4226 * adapter's configuration information.
4227 *
4228 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
4229 * otherwise the static 'info' array will be overrun.
4230 */
27c868c2 4231static const char *advansys_info(struct Scsi_Host *shost)
1da177e4 4232{
27c868c2
MW
4233 static char info[ASC_INFO_SIZE];
4234 asc_board_t *boardp;
4235 ASC_DVC_VAR *asc_dvc_varp;
4236 ADV_DVC_VAR *adv_dvc_varp;
4237 char *busname;
4238 int iolen;
4239 char *widename = NULL;
4240
4241 boardp = ASC_BOARDP(shost);
4242 if (ASC_NARROW_BOARD(boardp)) {
4243 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4244 ASC_DBG(1, "advansys_info: begin\n");
4245 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
4246 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
4247 ASC_IS_ISAPNP) {
4248 busname = "ISA PnP";
4249 } else {
4250 busname = "ISA";
4251 }
4252 /* Don't reference 'shost->n_io_port'; It may be truncated. */
4253 sprintf(info,
4254 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
4255 ASC_VERSION, busname,
4256 (ulong)shost->io_port,
4257 (ulong)shost->io_port + boardp->asc_n_io_port -
4258 1, shost->irq, shost->dma_channel);
4259 } else {
4260 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
4261 busname = "VL";
4262 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
4263 busname = "EISA";
4264 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
4265 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
4266 == ASC_IS_PCI_ULTRA) {
4267 busname = "PCI Ultra";
4268 } else {
4269 busname = "PCI";
4270 }
4271 } else {
4272 busname = "?";
4273 ASC_PRINT2
4274 ("advansys_info: board %d: unknown bus type %d\n",
4275 boardp->id, asc_dvc_varp->bus_type);
4276 }
4277 /* Don't reference 'shost->n_io_port'; It may be truncated. */
4278 sprintf(info,
4279 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
4280 ASC_VERSION, busname,
4281 (ulong)shost->io_port,
4282 (ulong)shost->io_port + boardp->asc_n_io_port -
4283 1, shost->irq);
4284 }
4285 } else {
4286 /*
4287 * Wide Adapter Information
4288 *
4289 * Memory-mapped I/O is used instead of I/O space to access
4290 * the adapter, but display the I/O Port range. The Memory
4291 * I/O address is displayed through the driver /proc file.
4292 */
4293 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4294 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4295 iolen = ADV_3550_IOLEN;
4296 widename = "Ultra-Wide";
4297 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4298 iolen = ADV_38C0800_IOLEN;
4299 widename = "Ultra2-Wide";
4300 } else {
4301 iolen = ADV_38C1600_IOLEN;
4302 widename = "Ultra3-Wide";
4303 }
4304 sprintf(info,
4305 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
4306 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
4307 (ulong)adv_dvc_varp->iop_base + iolen - 1, shost->irq);
4308 }
4309 ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
4310 ASC_DBG(1, "advansys_info: end\n");
4311 return info;
1da177e4
LT
4312}
4313
4314/*
4315 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
4316 *
4317 * This function always returns 0. Command return status is saved
4318 * in the 'scp' result field.
4319 */
70c8d897 4320static int
27c868c2 4321advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *))
1da177e4 4322{
27c868c2
MW
4323 struct Scsi_Host *shost;
4324 asc_board_t *boardp;
4325 ulong flags;
4326 struct scsi_cmnd *done_scp;
1da177e4 4327
27c868c2
MW
4328 shost = scp->device->host;
4329 boardp = ASC_BOARDP(shost);
4330 ASC_STATS(shost, queuecommand);
1da177e4 4331
27c868c2
MW
4332 /* host_lock taken by mid-level prior to call but need to protect */
4333 /* against own ISR */
4334 spin_lock_irqsave(&boardp->lock, flags);
1da177e4 4335
27c868c2
MW
4336 /*
4337 * Block new commands while handling a reset or abort request.
4338 */
4339 if (boardp->flags & ASC_HOST_IN_RESET) {
4340 ASC_DBG1(1,
4341 "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
4342 (ulong)scp);
4343 scp->result = HOST_BYTE(DID_RESET);
1da177e4 4344
27c868c2
MW
4345 /*
4346 * Add blocked requests to the board's 'done' queue. The queued
4347 * requests will be completed at the end of the abort or reset
4348 * handling.
4349 */
4350 asc_enqueue(&boardp->done, scp, ASC_BACK);
4351 spin_unlock_irqrestore(&boardp->lock, flags);
4352 return 0;
4353 }
1da177e4 4354
27c868c2
MW
4355 /*
4356 * Attempt to execute any waiting commands for the board.
4357 */
4358 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4359 ASC_DBG(1,
4360 "advansys_queuecommand: before asc_execute_queue() waiting\n");
4361 asc_execute_queue(&boardp->waiting);
4362 }
4363
4364 /*
4365 * Save the function pointer to Linux mid-level 'done' function
4366 * and attempt to execute the command.
4367 *
4368 * If ASC_NOERROR is returned the request has been added to the
4369 * board's 'active' queue and will be completed by the interrupt
4370 * handler.
4371 *
4372 * If ASC_BUSY is returned add the request to the board's per
4373 * target waiting list. This is the first time the request has
4374 * been tried. Add it to the back of the waiting list. It will be
4375 * retried later.
4376 *
4377 * If an error occurred, the request will have been placed on the
4378 * board's 'done' queue and must be completed before returning.
4379 */
4380 scp->scsi_done = done;
4381 switch (asc_execute_scsi_cmnd(scp)) {
4382 case ASC_NOERROR:
4383 break;
4384 case ASC_BUSY:
4385 asc_enqueue(&boardp->waiting, scp, ASC_BACK);
4386 break;
4387 case ASC_ERROR:
4388 default:
4389 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
4390 /* Interrupts could be enabled here. */
4391 asc_scsi_done_list(done_scp);
4392 break;
4393 }
4394 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 4395
27c868c2 4396 return 0;
1da177e4
LT
4397}
4398
4399/*
4400 * advansys_reset()
4401 *
4402 * Reset the bus associated with the command 'scp'.
4403 *
4404 * This function runs its own thread. Interrupts must be blocked but
4405 * sleeping is allowed and no locking other than for host structures is
4406 * required. Returns SUCCESS or FAILED.
4407 */
27c868c2 4408static int advansys_reset(struct scsi_cmnd *scp)
1da177e4 4409{
27c868c2
MW
4410 struct Scsi_Host *shost;
4411 asc_board_t *boardp;
4412 ASC_DVC_VAR *asc_dvc_varp;
4413 ADV_DVC_VAR *adv_dvc_varp;
4414 ulong flags;
4415 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4416 struct scsi_cmnd *tscp, *new_last_scp;
4417 int status;
4418 int ret = SUCCESS;
4419
4420 ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp);
1da177e4
LT
4421
4422#ifdef ADVANSYS_STATS
27c868c2
MW
4423 if (scp->device->host != NULL) {
4424 ASC_STATS(scp->device->host, reset);
4425 }
1da177e4
LT
4426#endif /* ADVANSYS_STATS */
4427
27c868c2
MW
4428 if ((shost = scp->device->host) == NULL) {
4429 scp->result = HOST_BYTE(DID_ERROR);
4430 return FAILED;
4431 }
1da177e4 4432
27c868c2 4433 boardp = ASC_BOARDP(shost);
1da177e4 4434
27c868c2
MW
4435 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
4436 boardp->id);
4437 /*
4438 * Check for re-entrancy.
4439 */
1da177e4 4440 spin_lock_irqsave(&boardp->lock, flags);
27c868c2
MW
4441 if (boardp->flags & ASC_HOST_IN_RESET) {
4442 spin_unlock_irqrestore(&boardp->lock, flags);
4443 return FAILED;
4444 }
4445 boardp->flags |= ASC_HOST_IN_RESET;
4446 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 4447
27c868c2
MW
4448 if (ASC_NARROW_BOARD(boardp)) {
4449 /*
4450 * Narrow Board
4451 */
4452 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
1da177e4 4453
27c868c2
MW
4454 /*
4455 * Reset the chip and SCSI bus.
4456 */
4457 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
4458 status = AscInitAsc1000Driver(asc_dvc_varp);
4459
4460 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
4461 if (asc_dvc_varp->err_code) {
4462 ASC_PRINT2
4463 ("advansys_reset: board %d: SCSI bus reset error: 0x%x\n",
4464 boardp->id, asc_dvc_varp->err_code);
4465 ret = FAILED;
4466 } else if (status) {
4467 ASC_PRINT2
4468 ("advansys_reset: board %d: SCSI bus reset warning: 0x%x\n",
4469 boardp->id, status);
4470 } else {
4471 ASC_PRINT1
4472 ("advansys_reset: board %d: SCSI bus reset successful.\n",
4473 boardp->id);
4474 }
4475
4476 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
4477 spin_lock_irqsave(&boardp->lock, flags);
1da177e4 4478
27c868c2
MW
4479 } else {
4480 /*
4481 * Wide Board
4482 *
4483 * If the suggest reset bus flags are set, then reset the bus.
4484 * Otherwise only reset the device.
4485 */
4486 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
1da177e4 4487
27c868c2
MW
4488 /*
4489 * Reset the target's SCSI bus.
4490 */
4491 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
4492 switch (AdvResetChipAndSB(adv_dvc_varp)) {
4493 case ASC_TRUE:
4494 ASC_PRINT1
4495 ("advansys_reset: board %d: SCSI bus reset successful.\n",
4496 boardp->id);
4497 break;
4498 case ASC_FALSE:
4499 default:
4500 ASC_PRINT1
4501 ("advansys_reset: board %d: SCSI bus reset error.\n",
4502 boardp->id);
4503 ret = FAILED;
4504 break;
4505 }
4506 spin_lock_irqsave(&boardp->lock, flags);
4507 (void)AdvISR(adv_dvc_varp);
4508 }
4509 /* Board lock is held. */
4510
4511 /*
4512 * Dequeue all board 'done' requests. A pointer to the last request
4513 * is returned in 'last_scp'.
4514 */
4515 done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
4516
4517 /*
4518 * Dequeue all board 'active' requests for all devices and set
4519 * the request status to DID_RESET. A pointer to the last request
4520 * is returned in 'last_scp'.
4521 */
4522 if (done_scp == NULL) {
4523 done_scp =
4524 asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL);
4525 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4526 tscp->result = HOST_BYTE(DID_RESET);
4527 }
4528 } else {
4529 /* Append to 'done_scp' at the end with 'last_scp'. */
4530 ASC_ASSERT(last_scp != NULL);
4531 last_scp->host_scribble =
4532 (unsigned char *)asc_dequeue_list(&boardp->active,
4533 &new_last_scp,
4534 ASC_TID_ALL);
4535 if (new_last_scp != NULL) {
4536 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4537 for (tscp = REQPNEXT(last_scp); tscp;
4538 tscp = REQPNEXT(tscp)) {
4539 tscp->result = HOST_BYTE(DID_RESET);
4540 }
4541 last_scp = new_last_scp;
4542 }
4543 }
1da177e4 4544
27c868c2
MW
4545 /*
4546 * Dequeue all 'waiting' requests and set the request status
4547 * to DID_RESET.
4548 */
4549 if (done_scp == NULL) {
4550 done_scp =
4551 asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL);
4552 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4553 tscp->result = HOST_BYTE(DID_RESET);
4554 }
4555 } else {
4556 /* Append to 'done_scp' at the end with 'last_scp'. */
4557 ASC_ASSERT(last_scp != NULL);
4558 last_scp->host_scribble =
4559 (unsigned char *)asc_dequeue_list(&boardp->waiting,
4560 &new_last_scp,
4561 ASC_TID_ALL);
4562 if (new_last_scp != NULL) {
4563 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4564 for (tscp = REQPNEXT(last_scp); tscp;
4565 tscp = REQPNEXT(tscp)) {
4566 tscp->result = HOST_BYTE(DID_RESET);
4567 }
4568 last_scp = new_last_scp;
4569 }
4570 }
1da177e4 4571
27c868c2
MW
4572 /* Save the time of the most recently completed reset. */
4573 boardp->last_reset = jiffies;
1da177e4 4574
27c868c2
MW
4575 /* Clear reset flag. */
4576 boardp->flags &= ~ASC_HOST_IN_RESET;
4577 spin_unlock_irqrestore(&boardp->lock, flags);
4578
4579 /*
4580 * Complete all the 'done_scp' requests.
4581 */
4582 if (done_scp != NULL) {
4583 asc_scsi_done_list(done_scp);
4584 }
1da177e4 4585
27c868c2 4586 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
1da177e4 4587
27c868c2 4588 return ret;
1da177e4
LT
4589}
4590
4591/*
4592 * advansys_biosparam()
4593 *
4594 * Translate disk drive geometry if the "BIOS greater than 1 GB"
4595 * support is enabled for a drive.
4596 *
4597 * ip (information pointer) is an int array with the following definition:
4598 * ip[0]: heads
4599 * ip[1]: sectors
4600 * ip[2]: cylinders
4601 */
70c8d897 4602static int
1da177e4 4603advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
27c868c2 4604 sector_t capacity, int ip[])
1da177e4 4605{
27c868c2
MW
4606 asc_board_t *boardp;
4607
4608 ASC_DBG(1, "advansys_biosparam: begin\n");
4609 ASC_STATS(sdev->host, biosparam);
4610 boardp = ASC_BOARDP(sdev->host);
4611 if (ASC_NARROW_BOARD(boardp)) {
4612 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
4613 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
4614 ip[0] = 255;
4615 ip[1] = 63;
4616 } else {
4617 ip[0] = 64;
4618 ip[1] = 32;
4619 }
4620 } else {
4621 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
4622 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
4623 ip[0] = 255;
4624 ip[1] = 63;
4625 } else {
4626 ip[0] = 64;
4627 ip[1] = 32;
4628 }
4629 }
4630 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
4631 ASC_DBG(1, "advansys_biosparam: end\n");
4632 return 0;
1da177e4
LT
4633}
4634
8dfb5379 4635static struct scsi_host_template advansys_template = {
27c868c2 4636 .proc_name = "advansys",
1da177e4 4637#ifdef CONFIG_PROC_FS
27c868c2 4638 .proc_info = advansys_proc_info,
1da177e4 4639#endif
27c868c2 4640 .name = "advansys",
27c868c2
MW
4641 .info = advansys_info,
4642 .queuecommand = advansys_queuecommand,
4643 .eh_bus_reset_handler = advansys_reset,
4644 .bios_param = advansys_biosparam,
4645 .slave_configure = advansys_slave_configure,
4646 /*
4647 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
8dfb5379
MW
4648 * must be set. The flag will be cleared in advansys_board_found
4649 * for non-ISA adapters.
27c868c2
MW
4650 */
4651 .unchecked_isa_dma = 1,
4652 /*
4653 * All adapters controlled by this driver are capable of large
4654 * scatter-gather lists. According to the mid-level SCSI documentation
4655 * this obviates any performance gain provided by setting
4656 * 'use_clustering'. But empirically while CPU utilization is increased
4657 * by enabling clustering, I/O throughput increases as well.
4658 */
4659 .use_clustering = ENABLE_CLUSTERING,
1da177e4 4660};
1da177e4 4661
1da177e4
LT
4662/*
4663 * --- Miscellaneous Driver Functions
4664 */
4665
4666/*
4667 * First-level interrupt handler.
4668 *
4669 * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
4670 * all boards are currently checked for interrupts on each interrupt, 'dev_id'
4671 * is not referenced. 'dev_id' could be used to identify an interrupt passed
4672 * to the AdvanSys driver which is for a device sharing an interrupt with
4673 * an AdvanSys adapter.
4674 */
27c868c2 4675static irqreturn_t advansys_interrupt(int irq, void *dev_id)
1da177e4 4676{
074c8fe4 4677 unsigned long flags;
27c868c2
MW
4678 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4679 struct scsi_cmnd *new_last_scp;
074c8fe4
MW
4680 struct Scsi_Host *shost = dev_id;
4681 asc_board_t *boardp = ASC_BOARDP(shost);
4682 irqreturn_t result = IRQ_NONE;
27c868c2 4683
074c8fe4
MW
4684 ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp);
4685 spin_lock_irqsave(&boardp->lock, flags);
4686 if (ASC_NARROW_BOARD(boardp)) {
4687 /*
4688 * Narrow Board
4689 */
4690 if (AscIsIntPending(shost->io_port)) {
4691 result = IRQ_HANDLED;
4692 ASC_STATS(shost, interrupt);
4693 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
4694 AscISR(&boardp->dvc_var.asc_dvc_var);
4695 }
4696 } else {
4697 /*
4698 * Wide Board
4699 */
4700 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
4701 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
4702 result = IRQ_HANDLED;
4703 ASC_STATS(shost, interrupt);
4704 }
4705 }
27c868c2
MW
4706
4707 /*
074c8fe4
MW
4708 * Start waiting requests and create a list of completed requests.
4709 *
4710 * If a reset request is being performed for the board, the reset
4711 * handler will complete pending requests after it has completed.
4712 */
4713 if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
4714 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%p, "
4715 "last_scp 0x%p\n", done_scp, last_scp);
4716
4717 /* Start any waiting commands for the board. */
4718 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4719 ASC_DBG(1, "advansys_interrupt: before "
4720 "asc_execute_queue()\n");
4721 asc_execute_queue(&boardp->waiting);
27c868c2 4722 }
1da177e4 4723
27c868c2 4724 /*
074c8fe4 4725 * Add to the list of requests that must be completed.
27c868c2 4726 *
074c8fe4
MW
4727 * 'done_scp' will always be NULL on the first iteration of
4728 * this loop. 'last_scp' is set at the same time as 'done_scp'.
27c868c2 4729 */
074c8fe4
MW
4730 if (done_scp == NULL) {
4731 done_scp = asc_dequeue_list(&boardp->done,
4732 &last_scp, ASC_TID_ALL);
4733 } else {
4734 ASC_ASSERT(last_scp != NULL);
4735 last_scp->host_scribble =
4736 (unsigned char *)asc_dequeue_list(&boardp->
4737 done,
4738 &new_last_scp,
4739 ASC_TID_ALL);
4740 if (new_last_scp != NULL) {
4741 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4742 last_scp = new_last_scp;
27c868c2
MW
4743 }
4744 }
27c868c2 4745 }
074c8fe4 4746 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 4747
27c868c2
MW
4748 /*
4749 * If interrupts were enabled on entry, then they
4750 * are now enabled here.
4751 *
4752 * Complete all requests on the done list.
4753 */
1da177e4 4754
27c868c2 4755 asc_scsi_done_list(done_scp);
1da177e4 4756
27c868c2 4757 ASC_DBG(1, "advansys_interrupt: end\n");
074c8fe4 4758 return result;
1da177e4
LT
4759}
4760
4761/*
4762 * Set the number of commands to queue per device for the
4763 * specified host adapter.
4764 */
27c868c2 4765static int advansys_slave_configure(struct scsi_device *device)
1da177e4 4766{
27c868c2 4767 asc_board_t *boardp;
1da177e4 4768
27c868c2
MW
4769 boardp = ASC_BOARDP(device->host);
4770 boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
4771 /*
4772 * Save a pointer to the device and set its initial/maximum
4773 * queue depth. Only save the pointer for a lun0 dev though.
4774 */
4775 if (device->lun == 0)
4776 boardp->device[device->id] = device;
4777 if (device->tagged_supported) {
4778 if (ASC_NARROW_BOARD(boardp)) {
4779 scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
4780 boardp->dvc_var.asc_dvc_var.
4781 max_dvc_qng[device->id]);
4782 } else {
4783 scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
4784 boardp->dvc_var.adv_dvc_var.
4785 max_dvc_qng);
4786 }
4787 } else {
4788 scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun);
4789 }
4790 ASC_DBG4(1,
4791 "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n",
4792 (ulong)device, (ulong)boardp, device->id, device->queue_depth);
4793 return 0;
1da177e4
LT
4794}
4795
4796/*
4797 * Complete all requests on the singly linked list pointed
4798 * to by 'scp'.
4799 *
4800 * Interrupts can be enabled on entry.
4801 */
27c868c2 4802static void asc_scsi_done_list(struct scsi_cmnd *scp)
1da177e4 4803{
27c868c2 4804 struct scsi_cmnd *tscp;
1da177e4 4805
27c868c2
MW
4806 ASC_DBG(2, "asc_scsi_done_list: begin\n");
4807 while (scp != NULL) {
4808 asc_board_t *boardp;
4809 struct device *dev;
1da177e4 4810
27c868c2
MW
4811 ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp);
4812 tscp = REQPNEXT(scp);
4813 scp->host_scribble = NULL;
1da177e4 4814
27c868c2 4815 boardp = ASC_BOARDP(scp->device->host);
1da177e4 4816
27c868c2
MW
4817 if (ASC_NARROW_BOARD(boardp))
4818 dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
4819 else
4820 dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
1da177e4 4821
27c868c2
MW
4822 if (scp->use_sg)
4823 dma_unmap_sg(dev,
4824 (struct scatterlist *)scp->request_buffer,
4825 scp->use_sg, scp->sc_data_direction);
4826 else if (scp->request_bufflen)
4827 dma_unmap_single(dev, scp->SCp.dma_handle,
4828 scp->request_bufflen,
4829 scp->sc_data_direction);
1da177e4 4830
27c868c2
MW
4831 ASC_STATS(scp->device->host, done);
4832 ASC_ASSERT(scp->scsi_done != NULL);
1da177e4 4833
27c868c2 4834 scp->scsi_done(scp);
1da177e4 4835
27c868c2
MW
4836 scp = tscp;
4837 }
4838 ASC_DBG(2, "asc_scsi_done_list: done\n");
4839 return;
1da177e4
LT
4840}
4841
4842/*
4843 * Execute a single 'Scsi_Cmnd'.
4844 *
4845 * The function 'done' is called when the request has been completed.
4846 *
4847 * Scsi_Cmnd:
4848 *
4849 * host - board controlling device
4850 * device - device to send command
4851 * target - target of device
4852 * lun - lun of device
4853 * cmd_len - length of SCSI CDB
4854 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
4855 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
4856 *
4857 * if (use_sg == 0) {
4858 * request_buffer - buffer address for request
4859 * request_bufflen - length of request buffer
4860 * } else {
4861 * request_buffer - pointer to scatterlist structure
4862 * }
4863 *
4864 * sense_buffer - sense command buffer
4865 *
4866 * result (4 bytes of an int):
4867 * Byte Meaning
4868 * 0 SCSI Status Byte Code
4869 * 1 SCSI One Byte Message Code
4870 * 2 Host Error Code
4871 * 3 Mid-Level Error Code
4872 *
4873 * host driver fields:
4874 * SCp - Scsi_Pointer used for command processing status
4875 * scsi_done - used to save caller's done function
4876 * host_scribble - used for pointer to another struct scsi_cmnd
4877 *
4878 * If this function returns ASC_NOERROR the request has been enqueued
4879 * on the board's 'active' queue and will be completed from the
4880 * interrupt handler.
4881 *
4882 * If this function returns ASC_NOERROR the request has been enqueued
4883 * on the board's 'done' queue and must be completed by the caller.
4884 *
4885 * If ASC_BUSY is returned the request will be enqueued by the
4886 * caller on the target's waiting queue and re-tried later.
4887 */
27c868c2 4888static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
1da177e4 4889{
27c868c2
MW
4890 asc_board_t *boardp;
4891 ASC_DVC_VAR *asc_dvc_varp;
4892 ADV_DVC_VAR *adv_dvc_varp;
4893 ADV_SCSI_REQ_Q *adv_scsiqp;
4894 struct scsi_device *device;
4895 int ret;
4896
4897 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
4898 (ulong)scp, (ulong)scp->scsi_done);
4899
4900 boardp = ASC_BOARDP(scp->device->host);
4901 device = boardp->device[scp->device->id];
4902
4903 if (ASC_NARROW_BOARD(boardp)) {
4904 /*
4905 * Build and execute Narrow Board request.
4906 */
4907
4908 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4909
4910 /*
4911 * Build Asc Library request structure using the
4912 * global structures 'asc_scsi_req' and 'asc_sg_head'.
4913 *
4914 * If an error is returned, then the request has been
4915 * queued on the board done queue. It will be completed
4916 * by the caller.
4917 *
4918 * asc_build_req() can not return ASC_BUSY.
4919 */
4920 if (asc_build_req(boardp, scp) == ASC_ERROR) {
4921 ASC_STATS(scp->device->host, build_error);
4922 return ASC_ERROR;
4923 }
4924
4925 /*
4926 * Execute the command. If there is no error, add the command
4927 * to the active queue.
4928 */
4929 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
4930 case ASC_NOERROR:
4931 ASC_STATS(scp->device->host, exe_noerror);
4932 /*
4933 * Increment monotonically increasing per device successful
4934 * request counter. Wrapping doesn't matter.
4935 */
4936 boardp->reqcnt[scp->device->id]++;
4937 asc_enqueue(&boardp->active, scp, ASC_BACK);
4938 ASC_DBG(1,
4939 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
4940 break;
4941 case ASC_BUSY:
4942 /*
4943 * Caller will enqueue request on the target's waiting queue
4944 * and retry later.
4945 */
4946 ASC_STATS(scp->device->host, exe_busy);
4947 break;
4948 case ASC_ERROR:
4949 ASC_PRINT2
4950 ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4951 boardp->id, asc_dvc_varp->err_code);
4952 ASC_STATS(scp->device->host, exe_error);
4953 scp->result = HOST_BYTE(DID_ERROR);
4954 asc_enqueue(&boardp->done, scp, ASC_BACK);
4955 break;
4956 default:
4957 ASC_PRINT2
4958 ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
4959 boardp->id, asc_dvc_varp->err_code);
4960 ASC_STATS(scp->device->host, exe_unknown);
4961 scp->result = HOST_BYTE(DID_ERROR);
4962 asc_enqueue(&boardp->done, scp, ASC_BACK);
4963 break;
4964 }
4965 } else {
4966 /*
4967 * Build and execute Wide Board request.
4968 */
4969 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4970
4971 /*
4972 * Build and get a pointer to an Adv Library request structure.
4973 *
4974 * If the request is successfully built then send it below,
4975 * otherwise return with an error.
4976 */
4977 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
4978 case ASC_NOERROR:
4979 ASC_DBG(3,
4980 "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
4981 break;
4982 case ASC_BUSY:
4983 ASC_DBG(1,
4984 "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
4985 /*
4986 * If busy is returned the request has not been enqueued.
4987 * It will be enqueued by the caller on the target's waiting
4988 * queue and retried later.
4989 *
4990 * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg'
4991 * count wide board busy conditions. They are updated in
4992 * adv_build_req and adv_get_sglist, respectively.
4993 */
4994 return ASC_BUSY;
4995 case ASC_ERROR:
4996 /*
4997 * If an error is returned, then the request has been
4998 * queued on the board done queue. It will be completed
4999 * by the caller.
5000 */
5001 default:
5002 ASC_DBG(1,
5003 "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
5004 ASC_STATS(scp->device->host, build_error);
5005 return ASC_ERROR;
5006 }
1da177e4 5007
27c868c2
MW
5008 /*
5009 * Execute the command. If there is no error, add the command
5010 * to the active queue.
5011 */
5012 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
5013 case ASC_NOERROR:
5014 ASC_STATS(scp->device->host, exe_noerror);
5015 /*
5016 * Increment monotonically increasing per device successful
5017 * request counter. Wrapping doesn't matter.
5018 */
5019 boardp->reqcnt[scp->device->id]++;
5020 asc_enqueue(&boardp->active, scp, ASC_BACK);
5021 ASC_DBG(1,
5022 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
5023 break;
5024 case ASC_BUSY:
5025 /*
5026 * Caller will enqueue request on the target's waiting queue
5027 * and retry later.
5028 */
5029 ASC_STATS(scp->device->host, exe_busy);
5030 break;
5031 case ASC_ERROR:
5032 ASC_PRINT2
5033 ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
5034 boardp->id, adv_dvc_varp->err_code);
5035 ASC_STATS(scp->device->host, exe_error);
5036 scp->result = HOST_BYTE(DID_ERROR);
5037 asc_enqueue(&boardp->done, scp, ASC_BACK);
5038 break;
5039 default:
5040 ASC_PRINT2
5041 ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
5042 boardp->id, adv_dvc_varp->err_code);
5043 ASC_STATS(scp->device->host, exe_unknown);
5044 scp->result = HOST_BYTE(DID_ERROR);
5045 asc_enqueue(&boardp->done, scp, ASC_BACK);
5046 break;
5047 }
5048 }
5049
5050 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
5051 return ret;
1da177e4
LT
5052}
5053
5054/*
5055 * Build a request structure for the Asc Library (Narrow Board).
5056 *
5057 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
5058 * used to build the request.
5059 *
5060 * If an error occurs, then queue the request on the board done
5061 * queue and return ASC_ERROR.
5062 */
27c868c2 5063static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
1da177e4 5064{
27c868c2
MW
5065 struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
5066
5067 /*
5068 * Mutually exclusive access is required to 'asc_scsi_q' and
5069 * 'asc_sg_head' until after the request is started.
5070 */
5071 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
5072
5073 /*
5074 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
5075 */
5076 asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
5077
5078 /*
5079 * Build the ASC_SCSI_Q request.
5080 *
5081 * For narrow boards a CDB length maximum of 12 bytes
5082 * is supported.
5083 */
5084 if (scp->cmd_len > ASC_MAX_CDB_LEN) {
5085 ASC_PRINT3
5086 ("asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN %d\n",
5087 boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN);
5088 scp->result = HOST_BYTE(DID_ERROR);
5089 asc_enqueue(&boardp->done, scp, ASC_BACK);
5090 return ASC_ERROR;
5091 }
5092 asc_scsi_q.cdbptr = &scp->cmnd[0];
5093 asc_scsi_q.q2.cdb_len = scp->cmd_len;
5094 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
5095 asc_scsi_q.q1.target_lun = scp->device->lun;
5096 asc_scsi_q.q2.target_ix =
5097 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
5098 asc_scsi_q.q1.sense_addr =
5099 cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
5100 asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
5101
5102 /*
5103 * If there are any outstanding requests for the current target,
5104 * then every 255th request send an ORDERED request. This heuristic
5105 * tries to retain the benefit of request sorting while preventing
5106 * request starvation. 255 is the max number of tags or pending commands
5107 * a device may have outstanding.
5108 *
5109 * The request count is incremented below for every successfully
5110 * started request.
5111 *
5112 */
5113 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
5114 (boardp->reqcnt[scp->device->id] % 255) == 0) {
5115 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
5116 } else {
5117 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
5118 }
1da177e4 5119
27c868c2
MW
5120 /*
5121 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
5122 * buffer command.
5123 */
5124 if (scp->use_sg == 0) {
5125 /*
5126 * CDB request of single contiguous buffer.
5127 */
5128 ASC_STATS(scp->device->host, cont_cnt);
5129 scp->SCp.dma_handle = scp->request_bufflen ?
5130 dma_map_single(dev, scp->request_buffer,
5131 scp->request_bufflen,
5132 scp->sc_data_direction) : 0;
5133 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
5134 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
5135 ASC_STATS_ADD(scp->device->host, cont_xfer,
5136 ASC_CEILING(scp->request_bufflen, 512));
5137 asc_scsi_q.q1.sg_queue_cnt = 0;
5138 asc_scsi_q.sg_head = NULL;
5139 } else {
5140 /*
5141 * CDB scatter-gather request list.
5142 */
5143 int sgcnt;
5144 int use_sg;
5145 struct scatterlist *slp;
5146
5147 slp = (struct scatterlist *)scp->request_buffer;
5148 use_sg =
5149 dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
5150
5151 if (use_sg > scp->device->host->sg_tablesize) {
5152 ASC_PRINT3
5153 ("asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
5154 boardp->id, use_sg,
5155 scp->device->host->sg_tablesize);
5156 dma_unmap_sg(dev, slp, scp->use_sg,
5157 scp->sc_data_direction);
5158 scp->result = HOST_BYTE(DID_ERROR);
5159 asc_enqueue(&boardp->done, scp, ASC_BACK);
5160 return ASC_ERROR;
5161 }
5162
5163 ASC_STATS(scp->device->host, sg_cnt);
1da177e4 5164
27c868c2
MW
5165 /*
5166 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
5167 * structure to point to it.
5168 */
5169 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
5170
5171 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
5172 asc_scsi_q.sg_head = &asc_sg_head;
5173 asc_scsi_q.q1.data_cnt = 0;
5174 asc_scsi_q.q1.data_addr = 0;
5175 /* This is a byte value, otherwise it would need to be swapped. */
5176 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
5177 ASC_STATS_ADD(scp->device->host, sg_elem,
5178 asc_sg_head.entry_cnt);
1da177e4 5179
27c868c2
MW
5180 /*
5181 * Convert scatter-gather list into ASC_SG_HEAD list.
5182 */
5183 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
5184 asc_sg_head.sg_list[sgcnt].addr =
5185 cpu_to_le32(sg_dma_address(slp));
5186 asc_sg_head.sg_list[sgcnt].bytes =
5187 cpu_to_le32(sg_dma_len(slp));
5188 ASC_STATS_ADD(scp->device->host, sg_xfer,
5189 ASC_CEILING(sg_dma_len(slp), 512));
5190 }
5191 }
1da177e4 5192
27c868c2
MW
5193 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
5194 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
1da177e4 5195
27c868c2 5196 return ASC_NOERROR;
1da177e4
LT
5197}
5198
5199/*
5200 * Build a request structure for the Adv Library (Wide Board).
5201 *
5202 * If an adv_req_t can not be allocated to issue the request,
5203 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
5204 *
5205 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
5206 * microcode for DMA addresses or math operations are byte swapped
5207 * to little-endian order.
5208 */
27c868c2 5209static int
1da177e4 5210adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
27c868c2 5211 ADV_SCSI_REQ_Q **adv_scsiqpp)
1da177e4 5212{
27c868c2
MW
5213 adv_req_t *reqp;
5214 ADV_SCSI_REQ_Q *scsiqp;
5215 int i;
5216 int ret;
5217 struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
5218
5219 /*
5220 * Allocate an adv_req_t structure from the board to execute
5221 * the command.
5222 */
5223 if (boardp->adv_reqp == NULL) {
5224 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
5225 ASC_STATS(scp->device->host, adv_build_noreq);
5226 return ASC_BUSY;
5227 } else {
5228 reqp = boardp->adv_reqp;
5229 boardp->adv_reqp = reqp->next_reqp;
5230 reqp->next_reqp = NULL;
5231 }
1da177e4 5232
27c868c2
MW
5233 /*
5234 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
5235 */
5236 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5237
5238 /*
5239 * Initialize the structure.
5240 */
5241 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
5242
5243 /*
5244 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
5245 */
5246 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
5247
5248 /*
5249 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
5250 */
5251 reqp->cmndp = scp;
5252
5253 /*
5254 * Build the ADV_SCSI_REQ_Q request.
5255 */
5256
5257 /*
5258 * Set CDB length and copy it to the request structure.
5259 * For wide boards a CDB length maximum of 16 bytes
5260 * is supported.
5261 */
5262 if (scp->cmd_len > ADV_MAX_CDB_LEN) {
5263 ASC_PRINT3
5264 ("adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n",
5265 boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
5266 scp->result = HOST_BYTE(DID_ERROR);
5267 asc_enqueue(&boardp->done, scp, ASC_BACK);
5268 return ASC_ERROR;
5269 }
5270 scsiqp->cdb_len = scp->cmd_len;
5271 /* Copy first 12 CDB bytes to cdb[]. */
5272 for (i = 0; i < scp->cmd_len && i < 12; i++) {
5273 scsiqp->cdb[i] = scp->cmnd[i];
5274 }
5275 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
5276 for (; i < scp->cmd_len; i++) {
5277 scsiqp->cdb16[i - 12] = scp->cmnd[i];
5278 }
1da177e4 5279
27c868c2
MW
5280 scsiqp->target_id = scp->device->id;
5281 scsiqp->target_lun = scp->device->lun;
1da177e4 5282
27c868c2
MW
5283 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
5284 scsiqp->sense_len = sizeof(scp->sense_buffer);
1da177e4 5285
27c868c2
MW
5286 /*
5287 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
5288 * buffer command.
5289 */
1da177e4 5290
1da177e4 5291 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
27c868c2
MW
5292 scsiqp->vdata_addr = scp->request_buffer;
5293 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
1da177e4 5294
27c868c2
MW
5295 if (scp->use_sg == 0) {
5296 /*
5297 * CDB request of single contiguous buffer.
5298 */
5299 reqp->sgblkp = NULL;
5300 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
5301 if (scp->request_bufflen) {
5302 scsiqp->vdata_addr = scp->request_buffer;
5303 scp->SCp.dma_handle =
5304 dma_map_single(dev, scp->request_buffer,
5305 scp->request_bufflen,
5306 scp->sc_data_direction);
5307 } else {
5308 scsiqp->vdata_addr = NULL;
5309 scp->SCp.dma_handle = 0;
5310 }
5311 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
5312 scsiqp->sg_list_ptr = NULL;
5313 scsiqp->sg_real_addr = 0;
5314 ASC_STATS(scp->device->host, cont_cnt);
5315 ASC_STATS_ADD(scp->device->host, cont_xfer,
5316 ASC_CEILING(scp->request_bufflen, 512));
5317 } else {
5318 /*
5319 * CDB scatter-gather request list.
5320 */
5321 struct scatterlist *slp;
5322 int use_sg;
5323
5324 slp = (struct scatterlist *)scp->request_buffer;
5325 use_sg =
5326 dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
5327
5328 if (use_sg > ADV_MAX_SG_LIST) {
5329 ASC_PRINT3
5330 ("adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
5331 boardp->id, use_sg,
5332 scp->device->host->sg_tablesize);
5333 dma_unmap_sg(dev, slp, scp->use_sg,
5334 scp->sc_data_direction);
5335 scp->result = HOST_BYTE(DID_ERROR);
5336 asc_enqueue(&boardp->done, scp, ASC_BACK);
5337
5338 /*
5339 * Free the 'adv_req_t' structure by adding it back to the
5340 * board free list.
5341 */
5342 reqp->next_reqp = boardp->adv_reqp;
5343 boardp->adv_reqp = reqp;
5344
5345 return ASC_ERROR;
5346 }
5347
5348 if ((ret =
5349 adv_get_sglist(boardp, reqp, scp,
5350 use_sg)) != ADV_SUCCESS) {
5351 /*
5352 * Free the adv_req_t structure by adding it back to the
5353 * board free list.
5354 */
5355 reqp->next_reqp = boardp->adv_reqp;
5356 boardp->adv_reqp = reqp;
5357
5358 return ret;
5359 }
5360
5361 ASC_STATS(scp->device->host, sg_cnt);
5362 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
5363 }
1da177e4 5364
27c868c2
MW
5365 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5366 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
1da177e4 5367
27c868c2 5368 *adv_scsiqpp = scsiqp;
1da177e4 5369
27c868c2 5370 return ASC_NOERROR;
1da177e4
LT
5371}
5372
5373/*
5374 * Build scatter-gather list for Adv Library (Wide Board).
5375 *
5376 * Additional ADV_SG_BLOCK structures will need to be allocated
5377 * if the total number of scatter-gather elements exceeds
5378 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
5379 * assumed to be physically contiguous.
5380 *
5381 * Return:
5382 * ADV_SUCCESS(1) - SG List successfully created
5383 * ADV_ERROR(-1) - SG List creation failed
5384 */
27c868c2
MW
5385static int
5386adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
5387 int use_sg)
1da177e4 5388{
27c868c2
MW
5389 adv_sgblk_t *sgblkp;
5390 ADV_SCSI_REQ_Q *scsiqp;
5391 struct scatterlist *slp;
5392 int sg_elem_cnt;
5393 ADV_SG_BLOCK *sg_block, *prev_sg_block;
5394 ADV_PADDR sg_block_paddr;
5395 int i;
5396
5397 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5398 slp = (struct scatterlist *)scp->request_buffer;
5399 sg_elem_cnt = use_sg;
5400 prev_sg_block = NULL;
5401 reqp->sgblkp = NULL;
5402
5403 do {
5404 /*
5405 * Allocate a 'adv_sgblk_t' structure from the board free
5406 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
5407 * (15) scatter-gather elements.
5408 */
5409 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
5410 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
5411 ASC_STATS(scp->device->host, adv_build_nosg);
5412
5413 /*
5414 * Allocation failed. Free 'adv_sgblk_t' structures already
5415 * allocated for the request.
5416 */
5417 while ((sgblkp = reqp->sgblkp) != NULL) {
5418 /* Remove 'sgblkp' from the request list. */
5419 reqp->sgblkp = sgblkp->next_sgblkp;
5420
5421 /* Add 'sgblkp' to the board free list. */
5422 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5423 boardp->adv_sgblkp = sgblkp;
5424 }
5425 return ASC_BUSY;
5426 } else {
5427 /* Complete 'adv_sgblk_t' board allocation. */
5428 boardp->adv_sgblkp = sgblkp->next_sgblkp;
5429 sgblkp->next_sgblkp = NULL;
5430
5431 /*
5432 * Get 8 byte aligned virtual and physical addresses for
5433 * the allocated ADV_SG_BLOCK structure.
5434 */
5435 sg_block =
5436 (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
5437 sg_block_paddr = virt_to_bus(sg_block);
5438
5439 /*
5440 * Check if this is the first 'adv_sgblk_t' for the request.
5441 */
5442 if (reqp->sgblkp == NULL) {
5443 /* Request's first scatter-gather block. */
5444 reqp->sgblkp = sgblkp;
5445
5446 /*
5447 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
5448 * address pointers.
5449 */
5450 scsiqp->sg_list_ptr = sg_block;
5451 scsiqp->sg_real_addr =
5452 cpu_to_le32(sg_block_paddr);
5453 } else {
5454 /* Request's second or later scatter-gather block. */
5455 sgblkp->next_sgblkp = reqp->sgblkp;
5456 reqp->sgblkp = sgblkp;
5457
5458 /*
5459 * Point the previous ADV_SG_BLOCK structure to
5460 * the newly allocated ADV_SG_BLOCK structure.
5461 */
5462 ASC_ASSERT(prev_sg_block != NULL);
5463 prev_sg_block->sg_ptr =
5464 cpu_to_le32(sg_block_paddr);
5465 }
5466 }
5467
5468 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
5469 sg_block->sg_list[i].sg_addr =
5470 cpu_to_le32(sg_dma_address(slp));
5471 sg_block->sg_list[i].sg_count =
5472 cpu_to_le32(sg_dma_len(slp));
5473 ASC_STATS_ADD(scp->device->host, sg_xfer,
5474 ASC_CEILING(sg_dma_len(slp), 512));
5475
5476 if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */
5477 sg_block->sg_cnt = i + 1;
5478 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
5479 return ADV_SUCCESS;
5480 }
5481 slp++;
5482 }
5483 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
5484 prev_sg_block = sg_block;
5485 }
5486 while (1);
5487 /* NOTREACHED */
1da177e4
LT
5488}
5489
5490/*
5491 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
5492 *
5493 * Interrupt callback function for the Narrow SCSI Asc Library.
5494 */
27c868c2 5495static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
1da177e4 5496{
27c868c2
MW
5497 asc_board_t *boardp;
5498 struct scsi_cmnd *scp;
5499 struct Scsi_Host *shost;
27c868c2
MW
5500
5501 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
5502 (ulong)asc_dvc_varp, (ulong)qdonep);
5503 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
5504
5505 /*
5506 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5507 * command that has been completed.
5508 */
5509 scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
5510 ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp);
5511
5512 if (scp == NULL) {
5513 ASC_PRINT("asc_isr_callback: scp is NULL\n");
5514 return;
5515 }
5516 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5517
27c868c2 5518 shost = scp->device->host;
27c868c2
MW
5519 ASC_STATS(shost, callback);
5520 ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
5521
5522 /*
5523 * If the request isn't found on the active queue, it may
5524 * have been removed to handle a reset request.
5525 * Display a message and return.
5526 */
5527 boardp = ASC_BOARDP(shost);
5528 ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
5529 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5530 ASC_PRINT2
5531 ("asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
5532 boardp->id, (ulong)scp);
5533 return;
5534 }
1da177e4 5535
27c868c2
MW
5536 /*
5537 * 'qdonep' contains the command's ending status.
5538 */
5539 switch (qdonep->d3.done_stat) {
5540 case QD_NO_ERROR:
5541 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
5542 scp->result = 0;
1da177e4 5543
27c868c2
MW
5544 /*
5545 * If an INQUIRY command completed successfully, then call
5546 * the AscInquiryHandling() function to set-up the device.
5547 */
5548 if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 &&
5549 (scp->request_bufflen - qdonep->remain_bytes) >= 8) {
5550 AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7,
5551 (ASC_SCSI_INQUIRY *)scp->
5552 request_buffer);
5553 }
1da177e4 5554
27c868c2
MW
5555 /*
5556 * Check for an underrun condition.
5557 *
5558 * If there was no error and an underrun condition, then
5559 * then return the number of underrun bytes.
5560 */
5561 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
5562 qdonep->remain_bytes <= scp->request_bufflen) {
5563 ASC_DBG1(1,
5564 "asc_isr_callback: underrun condition %u bytes\n",
5565 (unsigned)qdonep->remain_bytes);
5566 scp->resid = qdonep->remain_bytes;
5567 }
5568 break;
5569
5570 case QD_WITH_ERROR:
5571 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
5572 switch (qdonep->d3.host_stat) {
5573 case QHSTA_NO_ERROR:
5574 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
5575 ASC_DBG(2,
5576 "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5577 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5578 sizeof(scp->sense_buffer));
5579 /*
5580 * Note: The 'status_byte()' macro used by target drivers
5581 * defined in scsi.h shifts the status byte returned by
5582 * host drivers right by 1 bit. This is why target drivers
5583 * also use right shifted status byte definitions. For
5584 * instance target drivers use CHECK_CONDITION, defined to
5585 * 0x1, instead of the SCSI defined check condition value
5586 * of 0x2. Host drivers are supposed to return the status
5587 * byte as it is defined by SCSI.
5588 */
5589 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5590 STATUS_BYTE(qdonep->d3.scsi_stat);
5591 } else {
5592 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
5593 }
5594 break;
5595
5596 default:
5597 /* QHSTA error occurred */
5598 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
5599 qdonep->d3.host_stat);
5600 scp->result = HOST_BYTE(DID_BAD_TARGET);
5601 break;
5602 }
5603 break;
5604
5605 case QD_ABORTED_BY_HOST:
5606 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
5607 scp->result =
5608 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
5609 scsi_msg) |
5610 STATUS_BYTE(qdonep->d3.scsi_stat);
5611 break;
5612
5613 default:
5614 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n",
5615 qdonep->d3.done_stat);
5616 scp->result =
5617 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
5618 scsi_msg) |
5619 STATUS_BYTE(qdonep->d3.scsi_stat);
5620 break;
5621 }
1da177e4 5622
27c868c2
MW
5623 /*
5624 * If the 'init_tidmask' bit isn't already set for the target and the
5625 * current request finished normally, then set the bit for the target
5626 * to indicate that a device is present.
5627 */
5628 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5629 qdonep->d3.done_stat == QD_NO_ERROR &&
5630 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
5631 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5632 }
1da177e4 5633
27c868c2
MW
5634 /*
5635 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5636 * function, add the command to the end of the board's done queue.
5637 * The done function for the command will be called from
5638 * advansys_interrupt().
5639 */
5640 asc_enqueue(&boardp->done, scp, ASC_BACK);
1da177e4 5641
27c868c2 5642 return;
1da177e4
LT
5643}
5644
5645/*
5646 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
5647 *
5648 * Callback function for the Wide SCSI Adv Library.
5649 */
27c868c2 5650static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
1da177e4 5651{
27c868c2
MW
5652 asc_board_t *boardp;
5653 adv_req_t *reqp;
5654 adv_sgblk_t *sgblkp;
5655 struct scsi_cmnd *scp;
5656 struct Scsi_Host *shost;
27c868c2
MW
5657 ADV_DCNT resid_cnt;
5658
5659 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
5660 (ulong)adv_dvc_varp, (ulong)scsiqp);
5661 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5662
5663 /*
5664 * Get the adv_req_t structure for the command that has been
5665 * completed. The adv_req_t structure actually contains the
5666 * completed ADV_SCSI_REQ_Q structure.
5667 */
5668 reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
5669 ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp);
5670 if (reqp == NULL) {
5671 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
5672 return;
5673 }
1da177e4 5674
27c868c2
MW
5675 /*
5676 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5677 * command that has been completed.
5678 *
5679 * Note: The adv_req_t request structure and adv_sgblk_t structure,
5680 * if any, are dropped, because a board structure pointer can not be
5681 * determined.
5682 */
5683 scp = reqp->cmndp;
5684 ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp);
5685 if (scp == NULL) {
5686 ASC_PRINT
5687 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
5688 return;
5689 }
5690 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5691
27c868c2 5692 shost = scp->device->host;
27c868c2
MW
5693 ASC_STATS(shost, callback);
5694 ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
5695
5696 /*
5697 * If the request isn't found on the active queue, it may have been
5698 * removed to handle a reset request. Display a message and return.
5699 *
5700 * Note: Because the structure may still be in use don't attempt
5701 * to free the adv_req_t and adv_sgblk_t, if any, structures.
5702 */
5703 boardp = ASC_BOARDP(shost);
5704 ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
5705 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5706 ASC_PRINT2
5707 ("adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
5708 boardp->id, (ulong)scp);
5709 return;
5710 }
1da177e4 5711
27c868c2
MW
5712 /*
5713 * 'done_status' contains the command's ending status.
5714 */
5715 switch (scsiqp->done_status) {
5716 case QD_NO_ERROR:
5717 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
5718 scp->result = 0;
1da177e4 5719
27c868c2
MW
5720 /*
5721 * Check for an underrun condition.
5722 *
5723 * If there was no error and an underrun condition, then
5724 * then return the number of underrun bytes.
5725 */
5726 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
5727 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
5728 resid_cnt <= scp->request_bufflen) {
5729 ASC_DBG1(1,
5730 "adv_isr_callback: underrun condition %lu bytes\n",
5731 (ulong)resid_cnt);
5732 scp->resid = resid_cnt;
5733 }
5734 break;
5735
5736 case QD_WITH_ERROR:
5737 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
5738 switch (scsiqp->host_status) {
5739 case QHSTA_NO_ERROR:
5740 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
5741 ASC_DBG(2,
5742 "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5743 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5744 sizeof(scp->sense_buffer));
5745 /*
5746 * Note: The 'status_byte()' macro used by target drivers
5747 * defined in scsi.h shifts the status byte returned by
5748 * host drivers right by 1 bit. This is why target drivers
5749 * also use right shifted status byte definitions. For
5750 * instance target drivers use CHECK_CONDITION, defined to
5751 * 0x1, instead of the SCSI defined check condition value
5752 * of 0x2. Host drivers are supposed to return the status
5753 * byte as it is defined by SCSI.
5754 */
5755 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5756 STATUS_BYTE(scsiqp->scsi_status);
5757 } else {
5758 scp->result = STATUS_BYTE(scsiqp->scsi_status);
5759 }
5760 break;
5761
5762 default:
5763 /* Some other QHSTA error occurred. */
5764 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
5765 scsiqp->host_status);
5766 scp->result = HOST_BYTE(DID_BAD_TARGET);
5767 break;
5768 }
5769 break;
5770
5771 case QD_ABORTED_BY_HOST:
5772 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
5773 scp->result =
5774 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
5775 break;
5776
5777 default:
5778 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n",
5779 scsiqp->done_status);
5780 scp->result =
5781 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
5782 break;
5783 }
1da177e4 5784
27c868c2
MW
5785 /*
5786 * If the 'init_tidmask' bit isn't already set for the target and the
5787 * current request finished normally, then set the bit for the target
5788 * to indicate that a device is present.
5789 */
5790 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5791 scsiqp->done_status == QD_NO_ERROR &&
5792 scsiqp->host_status == QHSTA_NO_ERROR) {
5793 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5794 }
1da177e4 5795
27c868c2
MW
5796 /*
5797 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5798 * function, add the command to the end of the board's done queue.
5799 * The done function for the command will be called from
5800 * advansys_interrupt().
5801 */
5802 asc_enqueue(&boardp->done, scp, ASC_BACK);
5803
5804 /*
5805 * Free all 'adv_sgblk_t' structures allocated for the request.
5806 */
5807 while ((sgblkp = reqp->sgblkp) != NULL) {
5808 /* Remove 'sgblkp' from the request list. */
5809 reqp->sgblkp = sgblkp->next_sgblkp;
5810
5811 /* Add 'sgblkp' to the board free list. */
5812 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5813 boardp->adv_sgblkp = sgblkp;
5814 }
1da177e4 5815
27c868c2
MW
5816 /*
5817 * Free the adv_req_t structure used with the command by adding
5818 * it back to the board free list.
5819 */
5820 reqp->next_reqp = boardp->adv_reqp;
5821 boardp->adv_reqp = reqp;
1da177e4 5822
27c868c2 5823 ASC_DBG(1, "adv_isr_callback: done\n");
1da177e4 5824
27c868c2 5825 return;
1da177e4
LT
5826}
5827
5828/*
5829 * adv_async_callback() - Adv Library asynchronous event callback function.
5830 */
27c868c2 5831static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
1da177e4 5832{
27c868c2
MW
5833 switch (code) {
5834 case ADV_ASYNC_SCSI_BUS_RESET_DET:
5835 /*
5836 * The firmware detected a SCSI Bus reset.
5837 */
5838 ASC_DBG(0,
5839 "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
5840 break;
5841
5842 case ADV_ASYNC_RDMA_FAILURE:
5843 /*
5844 * Handle RDMA failure by resetting the SCSI Bus and
5845 * possibly the chip if it is unresponsive. Log the error
5846 * with a unique code.
5847 */
5848 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
5849 AdvResetChipAndSB(adv_dvc_varp);
5850 break;
5851
5852 case ADV_HOST_SCSI_BUS_RESET:
5853 /*
5854 * Host generated SCSI bus reset occurred.
5855 */
5856 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
5857 break;
5858
5859 default:
5860 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
5861 break;
5862 }
1da177e4
LT
5863}
5864
5865/*
5866 * Add a 'REQP' to the end of specified queue. Set 'tidmask'
5867 * to indicate a command is queued for the device.
5868 *
5869 * 'flag' may be either ASC_FRONT or ASC_BACK.
5870 *
5871 * 'REQPNEXT(reqp)' returns reqp's next pointer.
5872 */
27c868c2 5873static void asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
1da177e4 5874{
27c868c2
MW
5875 int tid;
5876
5877 ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
5878 (ulong)ascq, (ulong)reqp, flag);
5879 ASC_ASSERT(reqp != NULL);
5880 ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
5881 tid = REQPTID(reqp);
5882 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5883 if (flag == ASC_FRONT) {
5884 reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
5885 ascq->q_first[tid] = reqp;
5886 /* If the queue was empty, set the last pointer. */
5887 if (ascq->q_last[tid] == NULL) {
5888 ascq->q_last[tid] = reqp;
5889 }
5890 } else { /* ASC_BACK */
5891 if (ascq->q_last[tid] != NULL) {
5892 ascq->q_last[tid]->host_scribble =
5893 (unsigned char *)reqp;
5894 }
5895 ascq->q_last[tid] = reqp;
5896 reqp->host_scribble = NULL;
5897 /* If the queue was empty, set the first pointer. */
5898 if (ascq->q_first[tid] == NULL) {
5899 ascq->q_first[tid] = reqp;
5900 }
5901 }
5902 /* The queue has at least one entry, set its bit. */
5903 ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
1da177e4 5904#ifdef ADVANSYS_STATS
27c868c2
MW
5905 /* Maintain request queue statistics. */
5906 ascq->q_tot_cnt[tid]++;
5907 ascq->q_cur_cnt[tid]++;
5908 if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
5909 ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
5910 ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
5911 tid, ascq->q_max_cnt[tid]);
5912 }
5913 REQPTIME(reqp) = REQTIMESTAMP();
1da177e4 5914#endif /* ADVANSYS_STATS */
27c868c2
MW
5915 ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong)reqp);
5916 return;
1da177e4
LT
5917}
5918
5919/*
5920 * Return first queued 'REQP' on the specified queue for
5921 * the specified target device. Clear the 'tidmask' bit for
5922 * the device if no more commands are left queued for it.
5923 *
5924 * 'REQPNEXT(reqp)' returns reqp's next pointer.
5925 */
27c868c2 5926static REQP asc_dequeue(asc_queue_t *ascq, int tid)
1da177e4 5927{
27c868c2
MW
5928 REQP reqp;
5929
5930 ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5931 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5932 if ((reqp = ascq->q_first[tid]) != NULL) {
5933 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
5934 ascq->q_first[tid] = REQPNEXT(reqp);
5935 /* If the queue is empty, clear its bit and the last pointer. */
5936 if (ascq->q_first[tid] == NULL) {
5937 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5938 ASC_ASSERT(ascq->q_last[tid] == reqp);
5939 ascq->q_last[tid] = NULL;
5940 }
1da177e4 5941#ifdef ADVANSYS_STATS
27c868c2
MW
5942 /* Maintain request queue statistics. */
5943 ascq->q_cur_cnt[tid]--;
5944 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
5945 REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
1da177e4 5946#endif /* ADVANSYS_STATS */
27c868c2
MW
5947 }
5948 ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong)reqp);
5949 return reqp;
1da177e4
LT
5950}
5951
5952/*
5953 * Return a pointer to a singly linked list of all the requests queued
5954 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
5955 *
5956 * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
5957 * the last request returned in the singly linked list.
5958 *
5959 * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
5960 * then all queued requests are concatenated into one list and
5961 * returned.
5962 *
5963 * Note: If 'lastpp' is used to append a new list to the end of
5964 * an old list, only change the old list last pointer if '*lastpp'
5965 * (or the function return value) is not NULL, i.e. use a temporary
5966 * variable for 'lastpp' and check its value after the function return
5967 * before assigning it to the list last pointer.
5968 *
5969 * Unfortunately collecting queuing time statistics adds overhead to
5970 * the function that isn't inherent to the function's algorithm.
5971 */
27c868c2 5972static REQP asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
1da177e4 5973{
27c868c2
MW
5974 REQP firstp, lastp;
5975 int i;
5976
5977 ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5978 ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
5979
5980 /*
5981 * If 'tid' is not ASC_TID_ALL, return requests only for
5982 * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
5983 * requests for all tids.
5984 */
5985 if (tid != ASC_TID_ALL) {
5986 /* Return all requests for the specified 'tid'. */
5987 if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
5988 /* List is empty; Set first and last return pointers to NULL. */
5989 firstp = lastp = NULL;
5990 } else {
5991 firstp = ascq->q_first[tid];
5992 lastp = ascq->q_last[tid];
5993 ascq->q_first[tid] = ascq->q_last[tid] = NULL;
5994 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
1da177e4 5995#ifdef ADVANSYS_STATS
27c868c2
MW
5996 {
5997 REQP reqp;
5998 ascq->q_cur_cnt[tid] = 0;
5999 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
6000 REQTIMESTAT("asc_dequeue_list", ascq,
6001 reqp, tid);
6002 }
6003 }
1da177e4 6004#endif /* ADVANSYS_STATS */
27c868c2
MW
6005 }
6006 } else {
6007 /* Return all requests for all tids. */
6008 firstp = lastp = NULL;
6009 for (i = 0; i <= ADV_MAX_TID; i++) {
6010 if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
6011 if (firstp == NULL) {
6012 firstp = ascq->q_first[i];
6013 lastp = ascq->q_last[i];
6014 } else {
6015 ASC_ASSERT(lastp != NULL);
6016 lastp->host_scribble =
6017 (unsigned char *)ascq->q_first[i];
6018 lastp = ascq->q_last[i];
6019 }
6020 ascq->q_first[i] = ascq->q_last[i] = NULL;
6021 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
1da177e4 6022#ifdef ADVANSYS_STATS
27c868c2 6023 ascq->q_cur_cnt[i] = 0;
1da177e4 6024#endif /* ADVANSYS_STATS */
27c868c2
MW
6025 }
6026 }
1da177e4 6027#ifdef ADVANSYS_STATS
27c868c2
MW
6028 {
6029 REQP reqp;
6030 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
6031 REQTIMESTAT("asc_dequeue_list", ascq, reqp,
6032 reqp->device->id);
6033 }
6034 }
1da177e4 6035#endif /* ADVANSYS_STATS */
27c868c2
MW
6036 }
6037 if (lastpp) {
6038 *lastpp = lastp;
6039 }
6040 ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong)firstp);
6041 return firstp;
1da177e4
LT
6042}
6043
6044/*
6045 * Remove the specified 'REQP' from the specified queue for
6046 * the specified target device. Clear the 'tidmask' bit for the
6047 * device if no more commands are left queued for it.
6048 *
6049 * 'REQPNEXT(reqp)' returns reqp's the next pointer.
6050 *
6051 * Return ASC_TRUE if the command was found and removed,
6052 * otherwise return ASC_FALSE.
6053 */
27c868c2 6054static int asc_rmqueue(asc_queue_t *ascq, REQP reqp)
1da177e4 6055{
27c868c2
MW
6056 REQP currp, prevp;
6057 int tid;
6058 int ret = ASC_FALSE;
6059
6060 ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
6061 (ulong)ascq, (ulong)reqp);
6062 ASC_ASSERT(reqp != NULL);
6063
6064 tid = REQPTID(reqp);
6065 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
6066
6067 /*
6068 * Handle the common case of 'reqp' being the first
6069 * entry on the queue.
6070 */
6071 if (reqp == ascq->q_first[tid]) {
6072 ret = ASC_TRUE;
6073 ascq->q_first[tid] = REQPNEXT(reqp);
6074 /* If the queue is now empty, clear its bit and the last pointer. */
6075 if (ascq->q_first[tid] == NULL) {
6076 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
6077 ASC_ASSERT(ascq->q_last[tid] == reqp);
6078 ascq->q_last[tid] = NULL;
6079 }
6080 } else if (ascq->q_first[tid] != NULL) {
6081 ASC_ASSERT(ascq->q_last[tid] != NULL);
6082 /*
6083 * Because the case of 'reqp' being the first entry has been
6084 * handled above and it is known the queue is not empty, if
6085 * 'reqp' is found on the queue it is guaranteed the queue will
6086 * not become empty and that 'q_first[tid]' will not be changed.
6087 *
6088 * Set 'prevp' to the first entry, 'currp' to the second entry,
6089 * and search for 'reqp'.
6090 */
6091 for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
6092 currp; prevp = currp, currp = REQPNEXT(currp)) {
6093 if (currp == reqp) {
6094 ret = ASC_TRUE;
6095 prevp->host_scribble =
6096 (unsigned char *)REQPNEXT(currp);
6097 reqp->host_scribble = NULL;
6098 if (ascq->q_last[tid] == reqp) {
6099 ascq->q_last[tid] = prevp;
6100 }
6101 break;
6102 }
6103 }
6104 }
1da177e4 6105#ifdef ADVANSYS_STATS
27c868c2
MW
6106 /* Maintain request queue statistics. */
6107 if (ret == ASC_TRUE) {
6108 ascq->q_cur_cnt[tid]--;
6109 REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
6110 }
6111 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
1da177e4 6112#endif /* ADVANSYS_STATS */
27c868c2
MW
6113 ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong)reqp, ret);
6114 return ret;
1da177e4
LT
6115}
6116
6117/*
6118 * Execute as many queued requests as possible for the specified queue.
6119 *
6120 * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd.
6121 */
27c868c2 6122static void asc_execute_queue(asc_queue_t *ascq)
1da177e4 6123{
27c868c2
MW
6124 ADV_SCSI_BIT_ID_TYPE scan_tidmask;
6125 REQP reqp;
6126 int i;
6127
6128 ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong)ascq);
6129 /*
6130 * Execute queued commands for devices attached to
6131 * the current board in round-robin fashion.
6132 */
6133 scan_tidmask = ascq->q_tidmask;
6134 do {
6135 for (i = 0; i <= ADV_MAX_TID; i++) {
6136 if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
6137 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
6138 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
6139 } else
6140 if (asc_execute_scsi_cmnd
6141 ((struct scsi_cmnd *)reqp)
6142 == ASC_BUSY) {
6143 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
6144 /*
6145 * The request returned ASC_BUSY. Enqueue at the front of
6146 * target's waiting list to maintain correct ordering.
6147 */
6148 asc_enqueue(ascq, reqp, ASC_FRONT);
6149 }
6150 }
6151 }
6152 } while (scan_tidmask);
6153 return;
1da177e4
LT
6154}
6155
6156#ifdef CONFIG_PROC_FS
6157/*
6158 * asc_prt_board_devices()
6159 *
6160 * Print driver information for devices attached to the board.
6161 *
6162 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6163 * cf. asc_prt_line().
6164 *
6165 * Return the number of characters copied into 'cp'. No more than
6166 * 'cplen' characters will be copied to 'cp'.
6167 */
27c868c2 6168static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6169{
27c868c2
MW
6170 asc_board_t *boardp;
6171 int leftlen;
6172 int totlen;
6173 int len;
6174 int chip_scsi_id;
6175 int i;
6176
6177 boardp = ASC_BOARDP(shost);
6178 leftlen = cplen;
6179 totlen = len = 0;
6180
6181 len = asc_prt_line(cp, leftlen,
6182 "\nDevice Information for AdvanSys SCSI Host %d:\n",
6183 shost->host_no);
6184 ASC_PRT_NEXT();
6185
6186 if (ASC_NARROW_BOARD(boardp)) {
6187 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6188 } else {
6189 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6190 }
1da177e4 6191
27c868c2
MW
6192 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
6193 ASC_PRT_NEXT();
6194 for (i = 0; i <= ADV_MAX_TID; i++) {
6195 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
6196 len = asc_prt_line(cp, leftlen, " %X,", i);
6197 ASC_PRT_NEXT();
6198 }
6199 }
6200 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
6201 ASC_PRT_NEXT();
1da177e4 6202
27c868c2 6203 return totlen;
1da177e4
LT
6204}
6205
6206/*
6207 * Display Wide Board BIOS Information.
6208 */
27c868c2 6209static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6210{
27c868c2
MW
6211 asc_board_t *boardp;
6212 int leftlen;
6213 int totlen;
6214 int len;
6215 ushort major, minor, letter;
6216
6217 boardp = ASC_BOARDP(shost);
6218 leftlen = cplen;
6219 totlen = len = 0;
6220
6221 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
6222 ASC_PRT_NEXT();
6223
6224 /*
6225 * If the BIOS saved a valid signature, then fill in
6226 * the BIOS code segment base address.
6227 */
6228 if (boardp->bios_signature != 0x55AA) {
6229 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
6230 ASC_PRT_NEXT();
6231 len = asc_prt_line(cp, leftlen,
6232 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
6233 ASC_PRT_NEXT();
6234 len = asc_prt_line(cp, leftlen,
6235 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
6236 ASC_PRT_NEXT();
6237 } else {
6238 major = (boardp->bios_version >> 12) & 0xF;
6239 minor = (boardp->bios_version >> 8) & 0xF;
6240 letter = (boardp->bios_version & 0xFF);
1da177e4 6241
27c868c2
MW
6242 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
6243 major, minor,
6244 letter >= 26 ? '?' : letter + 'A');
6245 ASC_PRT_NEXT();
1da177e4 6246
27c868c2
MW
6247 /*
6248 * Current available ROM BIOS release is 3.1I for UW
6249 * and 3.2I for U2W. This code doesn't differentiate
6250 * UW and U2W boards.
6251 */
6252 if (major < 3 || (major <= 3 && minor < 1) ||
6253 (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
6254 len = asc_prt_line(cp, leftlen,
6255 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
6256 ASC_PRT_NEXT();
6257 len = asc_prt_line(cp, leftlen,
6258 "ftp://ftp.connectcom.net/pub\n");
6259 ASC_PRT_NEXT();
6260 }
6261 }
1da177e4 6262
27c868c2 6263 return totlen;
1da177e4
LT
6264}
6265
6266/*
6267 * Add serial number to information bar if signature AAh
6268 * is found in at bit 15-9 (7 bits) of word 1.
6269 *
6270 * Serial Number consists fo 12 alpha-numeric digits.
6271 *
6272 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
6273 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
6274 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
6275 * 5 - Product revision (A-J) Word0: " "
6276 *
6277 * Signature Word1: 15-9 (7 bits)
6278 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
6279 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
6280 *
6281 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
6282 *
6283 * Note 1: Only production cards will have a serial number.
6284 *
6285 * Note 2: Signature is most significant 7 bits (0xFE).
6286 *
6287 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
6288 */
27c868c2 6289static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
1da177e4 6290{
27c868c2
MW
6291 ushort w, num;
6292
6293 if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
6294 return ASC_FALSE;
6295 } else {
6296 /*
6297 * First word - 6 digits.
6298 */
6299 w = serialnum[0];
6300
6301 /* Product type - 1st digit. */
6302 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
6303 /* Product type is P=Prototype */
6304 *cp += 0x8;
6305 }
6306 cp++;
6307
6308 /* Manufacturing location - 2nd digit. */
6309 *cp++ = 'A' + ((w & 0x1C00) >> 10);
6310
6311 /* Product ID - 3rd, 4th digits. */
6312 num = w & 0x3FF;
6313 *cp++ = '0' + (num / 100);
6314 num %= 100;
6315 *cp++ = '0' + (num / 10);
6316
6317 /* Product revision - 5th digit. */
6318 *cp++ = 'A' + (num % 10);
6319
6320 /*
6321 * Second word
6322 */
6323 w = serialnum[1];
6324
6325 /*
6326 * Year - 6th digit.
6327 *
6328 * If bit 15 of third word is set, then the
6329 * last digit of the year is greater than 7.
6330 */
6331 if (serialnum[2] & 0x8000) {
6332 *cp++ = '8' + ((w & 0x1C0) >> 6);
6333 } else {
6334 *cp++ = '0' + ((w & 0x1C0) >> 6);
6335 }
6336
6337 /* Week of year - 7th, 8th digits. */
6338 num = w & 0x003F;
6339 *cp++ = '0' + num / 10;
6340 num %= 10;
6341 *cp++ = '0' + num;
6342
6343 /*
6344 * Third word
6345 */
6346 w = serialnum[2] & 0x7FFF;
6347
6348 /* Serial number - 9th digit. */
6349 *cp++ = 'A' + (w / 1000);
6350
6351 /* 10th, 11th, 12th digits. */
6352 num = w % 1000;
6353 *cp++ = '0' + num / 100;
6354 num %= 100;
6355 *cp++ = '0' + num / 10;
6356 num %= 10;
6357 *cp++ = '0' + num;
6358
6359 *cp = '\0'; /* Null Terminate the string. */
6360 return ASC_TRUE;
6361 }
1da177e4
LT
6362}
6363
6364/*
6365 * asc_prt_asc_board_eeprom()
6366 *
6367 * Print board EEPROM configuration.
6368 *
6369 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6370 * cf. asc_prt_line().
6371 *
6372 * Return the number of characters copied into 'cp'. No more than
6373 * 'cplen' characters will be copied to 'cp'.
6374 */
27c868c2 6375static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6376{
27c868c2
MW
6377 asc_board_t *boardp;
6378 ASC_DVC_VAR *asc_dvc_varp;
6379 int leftlen;
6380 int totlen;
6381 int len;
6382 ASCEEP_CONFIG *ep;
6383 int i;
1da177e4 6384#ifdef CONFIG_ISA
27c868c2 6385 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
1da177e4 6386#endif /* CONFIG_ISA */
27c868c2
MW
6387 uchar serialstr[13];
6388
6389 boardp = ASC_BOARDP(shost);
6390 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6391 ep = &boardp->eep_config.asc_eep;
6392
6393 leftlen = cplen;
6394 totlen = len = 0;
6395
6396 len = asc_prt_line(cp, leftlen,
6397 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6398 shost->host_no);
6399 ASC_PRT_NEXT();
6400
6401 if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
6402 == ASC_TRUE) {
6403 len =
6404 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6405 serialstr);
6406 ASC_PRT_NEXT();
6407 } else {
6408 if (ep->adapter_info[5] == 0xBB) {
6409 len = asc_prt_line(cp, leftlen,
6410 " Default Settings Used for EEPROM-less Adapter.\n");
6411 ASC_PRT_NEXT();
6412 } else {
6413 len = asc_prt_line(cp, leftlen,
6414 " Serial Number Signature Not Present.\n");
6415 ASC_PRT_NEXT();
6416 }
6417 }
1da177e4 6418
27c868c2
MW
6419 len = asc_prt_line(cp, leftlen,
6420 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6421 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
6422 ep->max_tag_qng);
6423 ASC_PRT_NEXT();
6424
6425 len = asc_prt_line(cp, leftlen,
6426 " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
6427 ASC_PRT_NEXT();
6428
6429 len = asc_prt_line(cp, leftlen, " Target ID: ");
6430 ASC_PRT_NEXT();
6431 for (i = 0; i <= ASC_MAX_TID; i++) {
6432 len = asc_prt_line(cp, leftlen, " %d", i);
6433 ASC_PRT_NEXT();
6434 }
6435 len = asc_prt_line(cp, leftlen, "\n");
6436 ASC_PRT_NEXT();
6437
6438 len = asc_prt_line(cp, leftlen, " Disconnects: ");
6439 ASC_PRT_NEXT();
6440 for (i = 0; i <= ASC_MAX_TID; i++) {
6441 len = asc_prt_line(cp, leftlen, " %c",
6442 (ep->
6443 disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6444 'N');
6445 ASC_PRT_NEXT();
6446 }
6447 len = asc_prt_line(cp, leftlen, "\n");
6448 ASC_PRT_NEXT();
6449
6450 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
6451 ASC_PRT_NEXT();
6452 for (i = 0; i <= ASC_MAX_TID; i++) {
6453 len = asc_prt_line(cp, leftlen, " %c",
6454 (ep->
6455 use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6456 'N');
6457 ASC_PRT_NEXT();
6458 }
6459 len = asc_prt_line(cp, leftlen, "\n");
6460 ASC_PRT_NEXT();
6461
6462 len = asc_prt_line(cp, leftlen, " Start Motor: ");
6463 ASC_PRT_NEXT();
6464 for (i = 0; i <= ASC_MAX_TID; i++) {
6465 len = asc_prt_line(cp, leftlen, " %c",
6466 (ep->
6467 start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6468 'N');
6469 ASC_PRT_NEXT();
6470 }
6471 len = asc_prt_line(cp, leftlen, "\n");
6472 ASC_PRT_NEXT();
6473
6474 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6475 ASC_PRT_NEXT();
6476 for (i = 0; i <= ASC_MAX_TID; i++) {
6477 len = asc_prt_line(cp, leftlen, " %c",
6478 (ep->
6479 init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6480 'N');
6481 ASC_PRT_NEXT();
6482 }
6483 len = asc_prt_line(cp, leftlen, "\n");
6484 ASC_PRT_NEXT();
1da177e4
LT
6485
6486#ifdef CONFIG_ISA
27c868c2
MW
6487 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
6488 len = asc_prt_line(cp, leftlen,
6489 " Host ISA DMA speed: %d MB/S\n",
6490 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
6491 ASC_PRT_NEXT();
6492 }
1da177e4
LT
6493#endif /* CONFIG_ISA */
6494
27c868c2 6495 return totlen;
1da177e4
LT
6496}
6497
6498/*
6499 * asc_prt_adv_board_eeprom()
6500 *
6501 * Print board EEPROM configuration.
6502 *
6503 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6504 * cf. asc_prt_line().
6505 *
6506 * Return the number of characters copied into 'cp'. No more than
6507 * 'cplen' characters will be copied to 'cp'.
6508 */
27c868c2 6509static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6510{
27c868c2
MW
6511 asc_board_t *boardp;
6512 ADV_DVC_VAR *adv_dvc_varp;
6513 int leftlen;
6514 int totlen;
6515 int len;
6516 int i;
6517 char *termstr;
6518 uchar serialstr[13];
6519 ADVEEP_3550_CONFIG *ep_3550 = NULL;
6520 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
6521 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
6522 ushort word;
6523 ushort *wordp;
6524 ushort sdtr_speed = 0;
6525
6526 boardp = ASC_BOARDP(shost);
6527 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6528 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6529 ep_3550 = &boardp->eep_config.adv_3550_eep;
6530 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6531 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
6532 } else {
6533 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
6534 }
1da177e4 6535
27c868c2
MW
6536 leftlen = cplen;
6537 totlen = len = 0;
1da177e4 6538
27c868c2
MW
6539 len = asc_prt_line(cp, leftlen,
6540 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6541 shost->host_no);
6542 ASC_PRT_NEXT();
1da177e4 6543
27c868c2
MW
6544 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6545 wordp = &ep_3550->serial_number_word1;
6546 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6547 wordp = &ep_38C0800->serial_number_word1;
6548 } else {
6549 wordp = &ep_38C1600->serial_number_word1;
6550 }
1da177e4 6551
27c868c2
MW
6552 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
6553 len =
6554 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6555 serialstr);
6556 ASC_PRT_NEXT();
6557 } else {
6558 len = asc_prt_line(cp, leftlen,
6559 " Serial Number Signature Not Present.\n");
6560 ASC_PRT_NEXT();
6561 }
1da177e4 6562
27c868c2
MW
6563 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6564 len = asc_prt_line(cp, leftlen,
6565 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6566 ep_3550->adapter_scsi_id,
6567 ep_3550->max_host_qng, ep_3550->max_dvc_qng);
6568 ASC_PRT_NEXT();
6569 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6570 len = asc_prt_line(cp, leftlen,
6571 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6572 ep_38C0800->adapter_scsi_id,
6573 ep_38C0800->max_host_qng,
6574 ep_38C0800->max_dvc_qng);
6575 ASC_PRT_NEXT();
6576 } else {
6577 len = asc_prt_line(cp, leftlen,
6578 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6579 ep_38C1600->adapter_scsi_id,
6580 ep_38C1600->max_host_qng,
6581 ep_38C1600->max_dvc_qng);
6582 ASC_PRT_NEXT();
6583 }
6584 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6585 word = ep_3550->termination;
6586 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6587 word = ep_38C0800->termination_lvd;
6588 } else {
6589 word = ep_38C1600->termination_lvd;
6590 }
6591 switch (word) {
6592 case 1:
6593 termstr = "Low Off/High Off";
6594 break;
6595 case 2:
6596 termstr = "Low Off/High On";
6597 break;
6598 case 3:
6599 termstr = "Low On/High On";
6600 break;
6601 default:
6602 case 0:
6603 termstr = "Automatic";
6604 break;
6605 }
1da177e4 6606
27c868c2
MW
6607 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6608 len = asc_prt_line(cp, leftlen,
6609 " termination: %u (%s), bios_ctrl: 0x%x\n",
6610 ep_3550->termination, termstr,
6611 ep_3550->bios_ctrl);
6612 ASC_PRT_NEXT();
6613 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6614 len = asc_prt_line(cp, leftlen,
6615 " termination: %u (%s), bios_ctrl: 0x%x\n",
6616 ep_38C0800->termination_lvd, termstr,
6617 ep_38C0800->bios_ctrl);
6618 ASC_PRT_NEXT();
6619 } else {
6620 len = asc_prt_line(cp, leftlen,
6621 " termination: %u (%s), bios_ctrl: 0x%x\n",
6622 ep_38C1600->termination_lvd, termstr,
6623 ep_38C1600->bios_ctrl);
6624 ASC_PRT_NEXT();
6625 }
1da177e4 6626
27c868c2
MW
6627 len = asc_prt_line(cp, leftlen, " Target ID: ");
6628 ASC_PRT_NEXT();
6629 for (i = 0; i <= ADV_MAX_TID; i++) {
6630 len = asc_prt_line(cp, leftlen, " %X", i);
6631 ASC_PRT_NEXT();
6632 }
6633 len = asc_prt_line(cp, leftlen, "\n");
6634 ASC_PRT_NEXT();
1da177e4 6635
27c868c2
MW
6636 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6637 word = ep_3550->disc_enable;
6638 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6639 word = ep_38C0800->disc_enable;
6640 } else {
6641 word = ep_38C1600->disc_enable;
6642 }
6643 len = asc_prt_line(cp, leftlen, " Disconnects: ");
6644 ASC_PRT_NEXT();
6645 for (i = 0; i <= ADV_MAX_TID; i++) {
6646 len = asc_prt_line(cp, leftlen, " %c",
6647 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6648 ASC_PRT_NEXT();
6649 }
6650 len = asc_prt_line(cp, leftlen, "\n");
6651 ASC_PRT_NEXT();
1da177e4 6652
27c868c2
MW
6653 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6654 word = ep_3550->tagqng_able;
6655 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6656 word = ep_38C0800->tagqng_able;
6657 } else {
6658 word = ep_38C1600->tagqng_able;
6659 }
6660 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
6661 ASC_PRT_NEXT();
6662 for (i = 0; i <= ADV_MAX_TID; i++) {
6663 len = asc_prt_line(cp, leftlen, " %c",
6664 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6665 ASC_PRT_NEXT();
6666 }
6667 len = asc_prt_line(cp, leftlen, "\n");
6668 ASC_PRT_NEXT();
6669
6670 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6671 word = ep_3550->start_motor;
6672 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6673 word = ep_38C0800->start_motor;
6674 } else {
6675 word = ep_38C1600->start_motor;
6676 }
6677 len = asc_prt_line(cp, leftlen, " Start Motor: ");
6678 ASC_PRT_NEXT();
6679 for (i = 0; i <= ADV_MAX_TID; i++) {
6680 len = asc_prt_line(cp, leftlen, " %c",
6681 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6682 ASC_PRT_NEXT();
6683 }
6684 len = asc_prt_line(cp, leftlen, "\n");
6685 ASC_PRT_NEXT();
6686
6687 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6688 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6689 ASC_PRT_NEXT();
6690 for (i = 0; i <= ADV_MAX_TID; i++) {
6691 len = asc_prt_line(cp, leftlen, " %c",
6692 (ep_3550->
6693 sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
6694 'Y' : 'N');
6695 ASC_PRT_NEXT();
6696 }
6697 len = asc_prt_line(cp, leftlen, "\n");
6698 ASC_PRT_NEXT();
6699 }
6700
6701 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6702 len = asc_prt_line(cp, leftlen, " Ultra Transfer: ");
6703 ASC_PRT_NEXT();
6704 for (i = 0; i <= ADV_MAX_TID; i++) {
6705 len = asc_prt_line(cp, leftlen, " %c",
6706 (ep_3550->
6707 ultra_able & ADV_TID_TO_TIDMASK(i))
6708 ? 'Y' : 'N');
6709 ASC_PRT_NEXT();
6710 }
6711 len = asc_prt_line(cp, leftlen, "\n");
6712 ASC_PRT_NEXT();
6713 }
6714
6715 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6716 word = ep_3550->wdtr_able;
6717 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6718 word = ep_38C0800->wdtr_able;
6719 } else {
6720 word = ep_38C1600->wdtr_able;
6721 }
6722 len = asc_prt_line(cp, leftlen, " Wide Transfer: ");
6723 ASC_PRT_NEXT();
6724 for (i = 0; i <= ADV_MAX_TID; i++) {
6725 len = asc_prt_line(cp, leftlen, " %c",
6726 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6727 ASC_PRT_NEXT();
6728 }
6729 len = asc_prt_line(cp, leftlen, "\n");
6730 ASC_PRT_NEXT();
6731
6732 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
6733 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
6734 len = asc_prt_line(cp, leftlen,
6735 " Synchronous Transfer Speed (Mhz):\n ");
6736 ASC_PRT_NEXT();
6737 for (i = 0; i <= ADV_MAX_TID; i++) {
6738 char *speed_str;
6739
6740 if (i == 0) {
6741 sdtr_speed = adv_dvc_varp->sdtr_speed1;
6742 } else if (i == 4) {
6743 sdtr_speed = adv_dvc_varp->sdtr_speed2;
6744 } else if (i == 8) {
6745 sdtr_speed = adv_dvc_varp->sdtr_speed3;
6746 } else if (i == 12) {
6747 sdtr_speed = adv_dvc_varp->sdtr_speed4;
6748 }
6749 switch (sdtr_speed & ADV_MAX_TID) {
6750 case 0:
6751 speed_str = "Off";
6752 break;
6753 case 1:
6754 speed_str = " 5";
6755 break;
6756 case 2:
6757 speed_str = " 10";
6758 break;
6759 case 3:
6760 speed_str = " 20";
6761 break;
6762 case 4:
6763 speed_str = " 40";
6764 break;
6765 case 5:
6766 speed_str = " 80";
6767 break;
6768 default:
6769 speed_str = "Unk";
6770 break;
6771 }
6772 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
6773 ASC_PRT_NEXT();
6774 if (i == 7) {
6775 len = asc_prt_line(cp, leftlen, "\n ");
6776 ASC_PRT_NEXT();
6777 }
6778 sdtr_speed >>= 4;
6779 }
6780 len = asc_prt_line(cp, leftlen, "\n");
6781 ASC_PRT_NEXT();
6782 }
6783
6784 return totlen;
6785}
6786
6787/*
6788 * asc_prt_driver_conf()
6789 *
6790 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6791 * cf. asc_prt_line().
1da177e4
LT
6792 *
6793 * Return the number of characters copied into 'cp'. No more than
6794 * 'cplen' characters will be copied to 'cp'.
6795 */
27c868c2 6796static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6797{
27c868c2
MW
6798 asc_board_t *boardp;
6799 int leftlen;
6800 int totlen;
6801 int len;
6802 int chip_scsi_id;
6803
6804 boardp = ASC_BOARDP(shost);
6805
6806 leftlen = cplen;
6807 totlen = len = 0;
6808
6809 len = asc_prt_line(cp, leftlen,
6810 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
6811 shost->host_no);
6812 ASC_PRT_NEXT();
6813
6814 len = asc_prt_line(cp, leftlen,
6815 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
6816 shost->host_busy, shost->last_reset, shost->max_id,
6817 shost->max_lun, shost->max_channel);
6818 ASC_PRT_NEXT();
6819
6820 len = asc_prt_line(cp, leftlen,
6821 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
6822 shost->unique_id, shost->can_queue, shost->this_id,
6823 shost->sg_tablesize, shost->cmd_per_lun);
6824 ASC_PRT_NEXT();
6825
6826 len = asc_prt_line(cp, leftlen,
6827 " unchecked_isa_dma %d, use_clustering %d\n",
6828 shost->unchecked_isa_dma, shost->use_clustering);
6829 ASC_PRT_NEXT();
6830
6831 len = asc_prt_line(cp, leftlen,
6832 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
6833 boardp->flags, boardp->last_reset, jiffies,
6834 boardp->asc_n_io_port);
6835 ASC_PRT_NEXT();
6836
6837 /* 'shost->n_io_port' may be truncated because it is only one byte. */
6838 len = asc_prt_line(cp, leftlen,
6839 " io_port 0x%x, n_io_port 0x%x\n",
6840 shost->io_port, shost->n_io_port);
6841 ASC_PRT_NEXT();
6842
6843 if (ASC_NARROW_BOARD(boardp)) {
6844 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6845 } else {
6846 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6847 }
1da177e4 6848
27c868c2 6849 return totlen;
1da177e4
LT
6850}
6851
6852/*
6853 * asc_prt_asc_board_info()
6854 *
6855 * Print dynamic board configuration information.
6856 *
6857 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6858 * cf. asc_prt_line().
6859 *
6860 * Return the number of characters copied into 'cp'. No more than
6861 * 'cplen' characters will be copied to 'cp'.
6862 */
27c868c2 6863static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6864{
27c868c2
MW
6865 asc_board_t *boardp;
6866 int chip_scsi_id;
6867 int leftlen;
6868 int totlen;
6869 int len;
6870 ASC_DVC_VAR *v;
6871 ASC_DVC_CFG *c;
6872 int i;
6873 int renegotiate = 0;
6874
6875 boardp = ASC_BOARDP(shost);
6876 v = &boardp->dvc_var.asc_dvc_var;
6877 c = &boardp->dvc_cfg.asc_dvc_cfg;
6878 chip_scsi_id = c->chip_scsi_id;
6879
6880 leftlen = cplen;
6881 totlen = len = 0;
6882
6883 len = asc_prt_line(cp, leftlen,
6884 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6885 shost->host_no);
6886 ASC_PRT_NEXT();
6887
6888 len = asc_prt_line(cp, leftlen,
6889 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
6890 c->chip_version, c->lib_version, c->lib_serial_no,
6891 c->mcode_date);
6892 ASC_PRT_NEXT();
6893
6894 len = asc_prt_line(cp, leftlen,
6895 " mcode_version 0x%x, err_code %u\n",
6896 c->mcode_version, v->err_code);
6897 ASC_PRT_NEXT();
6898
6899 /* Current number of commands waiting for the host. */
6900 len = asc_prt_line(cp, leftlen,
6901 " Total Command Pending: %d\n", v->cur_total_qng);
6902 ASC_PRT_NEXT();
6903
6904 len = asc_prt_line(cp, leftlen, " Command Queuing:");
6905 ASC_PRT_NEXT();
6906 for (i = 0; i <= ASC_MAX_TID; i++) {
6907 if ((chip_scsi_id == i) ||
6908 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6909 continue;
6910 }
6911 len = asc_prt_line(cp, leftlen, " %X:%c",
6912 i,
6913 (v->
6914 use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
6915 'Y' : 'N');
6916 ASC_PRT_NEXT();
6917 }
6918 len = asc_prt_line(cp, leftlen, "\n");
6919 ASC_PRT_NEXT();
6920
6921 /* Current number of commands waiting for a device. */
6922 len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
6923 ASC_PRT_NEXT();
6924 for (i = 0; i <= ASC_MAX_TID; i++) {
6925 if ((chip_scsi_id == i) ||
6926 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6927 continue;
6928 }
6929 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
6930 ASC_PRT_NEXT();
6931 }
6932 len = asc_prt_line(cp, leftlen, "\n");
6933 ASC_PRT_NEXT();
6934
6935 /* Current limit on number of commands that can be sent to a device. */
6936 len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
6937 ASC_PRT_NEXT();
6938 for (i = 0; i <= ASC_MAX_TID; i++) {
6939 if ((chip_scsi_id == i) ||
6940 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6941 continue;
6942 }
6943 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
6944 ASC_PRT_NEXT();
6945 }
6946 len = asc_prt_line(cp, leftlen, "\n");
6947 ASC_PRT_NEXT();
6948
6949 /* Indicate whether the device has returned queue full status. */
6950 len = asc_prt_line(cp, leftlen, " Command Queue Full:");
6951 ASC_PRT_NEXT();
6952 for (i = 0; i <= ASC_MAX_TID; i++) {
6953 if ((chip_scsi_id == i) ||
6954 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6955 continue;
6956 }
6957 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
6958 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
6959 i, boardp->queue_full_cnt[i]);
6960 } else {
6961 len = asc_prt_line(cp, leftlen, " %X:N", i);
6962 }
6963 ASC_PRT_NEXT();
6964 }
6965 len = asc_prt_line(cp, leftlen, "\n");
6966 ASC_PRT_NEXT();
6967
6968 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6969 ASC_PRT_NEXT();
6970 for (i = 0; i <= ASC_MAX_TID; i++) {
6971 if ((chip_scsi_id == i) ||
6972 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6973 continue;
6974 }
6975 len = asc_prt_line(cp, leftlen, " %X:%c",
6976 i,
6977 (v->
6978 sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6979 'N');
6980 ASC_PRT_NEXT();
6981 }
6982 len = asc_prt_line(cp, leftlen, "\n");
6983 ASC_PRT_NEXT();
6984
6985 for (i = 0; i <= ASC_MAX_TID; i++) {
6986 uchar syn_period_ix;
6987
6988 if ((chip_scsi_id == i) ||
6989 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
6990 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
6991 continue;
6992 }
6993
6994 len = asc_prt_line(cp, leftlen, " %X:", i);
6995 ASC_PRT_NEXT();
6996
6997 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
6998 len = asc_prt_line(cp, leftlen, " Asynchronous");
6999 ASC_PRT_NEXT();
7000 } else {
7001 syn_period_ix =
7002 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
7003 1);
7004
7005 len = asc_prt_line(cp, leftlen,
7006 " Transfer Period Factor: %d (%d.%d Mhz),",
7007 v->sdtr_period_tbl[syn_period_ix],
7008 250 /
7009 v->sdtr_period_tbl[syn_period_ix],
7010 ASC_TENTHS(250,
7011 v->
7012 sdtr_period_tbl
7013 [syn_period_ix]));
7014 ASC_PRT_NEXT();
7015
7016 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
7017 boardp->
7018 sdtr_data[i] & ASC_SYN_MAX_OFFSET);
7019 ASC_PRT_NEXT();
7020 }
7021
7022 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7023 len = asc_prt_line(cp, leftlen, "*\n");
7024 renegotiate = 1;
7025 } else {
7026 len = asc_prt_line(cp, leftlen, "\n");
7027 }
7028 ASC_PRT_NEXT();
7029 }
1da177e4 7030
27c868c2
MW
7031 if (renegotiate) {
7032 len = asc_prt_line(cp, leftlen,
7033 " * = Re-negotiation pending before next command.\n");
7034 ASC_PRT_NEXT();
7035 }
1da177e4 7036
27c868c2 7037 return totlen;
1da177e4
LT
7038}
7039
7040/*
7041 * asc_prt_adv_board_info()
7042 *
7043 * Print dynamic board configuration information.
7044 *
7045 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7046 * cf. asc_prt_line().
7047 *
7048 * Return the number of characters copied into 'cp'. No more than
7049 * 'cplen' characters will be copied to 'cp'.
7050 */
27c868c2 7051static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 7052{
27c868c2
MW
7053 asc_board_t *boardp;
7054 int leftlen;
7055 int totlen;
7056 int len;
7057 int i;
7058 ADV_DVC_VAR *v;
7059 ADV_DVC_CFG *c;
7060 AdvPortAddr iop_base;
7061 ushort chip_scsi_id;
7062 ushort lramword;
7063 uchar lrambyte;
7064 ushort tagqng_able;
7065 ushort sdtr_able, wdtr_able;
7066 ushort wdtr_done, sdtr_done;
7067 ushort period = 0;
7068 int renegotiate = 0;
7069
7070 boardp = ASC_BOARDP(shost);
7071 v = &boardp->dvc_var.adv_dvc_var;
7072 c = &boardp->dvc_cfg.adv_dvc_cfg;
7073 iop_base = v->iop_base;
7074 chip_scsi_id = v->chip_scsi_id;
7075
7076 leftlen = cplen;
7077 totlen = len = 0;
7078
7079 len = asc_prt_line(cp, leftlen,
7080 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
7081 shost->host_no);
7082 ASC_PRT_NEXT();
7083
7084 len = asc_prt_line(cp, leftlen,
7085 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
7086 v->iop_base,
7087 AdvReadWordRegister(iop_base,
7088 IOPW_SCSI_CFG1) & CABLE_DETECT,
7089 v->err_code);
7090 ASC_PRT_NEXT();
7091
7092 len = asc_prt_line(cp, leftlen,
7093 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
7094 c->chip_version, c->lib_version, c->mcode_date,
7095 c->mcode_version);
7096 ASC_PRT_NEXT();
7097
7098 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
7099 len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
7100 ASC_PRT_NEXT();
7101 for (i = 0; i <= ADV_MAX_TID; i++) {
7102 if ((chip_scsi_id == i) ||
7103 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7104 continue;
7105 }
7106
7107 len = asc_prt_line(cp, leftlen, " %X:%c",
7108 i,
7109 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7110 'N');
7111 ASC_PRT_NEXT();
7112 }
7113 len = asc_prt_line(cp, leftlen, "\n");
7114 ASC_PRT_NEXT();
7115
7116 len = asc_prt_line(cp, leftlen, " Queue Limit:");
7117 ASC_PRT_NEXT();
7118 for (i = 0; i <= ADV_MAX_TID; i++) {
7119 if ((chip_scsi_id == i) ||
7120 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7121 continue;
7122 }
7123
7124 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
7125 lrambyte);
7126
7127 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
7128 ASC_PRT_NEXT();
7129 }
7130 len = asc_prt_line(cp, leftlen, "\n");
7131 ASC_PRT_NEXT();
7132
7133 len = asc_prt_line(cp, leftlen, " Command Pending:");
7134 ASC_PRT_NEXT();
7135 for (i = 0; i <= ADV_MAX_TID; i++) {
7136 if ((chip_scsi_id == i) ||
7137 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7138 continue;
7139 }
7140
7141 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
7142 lrambyte);
7143
7144 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
7145 ASC_PRT_NEXT();
7146 }
7147 len = asc_prt_line(cp, leftlen, "\n");
7148 ASC_PRT_NEXT();
7149
7150 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7151 len = asc_prt_line(cp, leftlen, " Wide Enabled:");
7152 ASC_PRT_NEXT();
7153 for (i = 0; i <= ADV_MAX_TID; i++) {
7154 if ((chip_scsi_id == i) ||
7155 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7156 continue;
7157 }
7158
7159 len = asc_prt_line(cp, leftlen, " %X:%c",
7160 i,
7161 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7162 'N');
7163 ASC_PRT_NEXT();
7164 }
7165 len = asc_prt_line(cp, leftlen, "\n");
7166 ASC_PRT_NEXT();
7167
7168 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
7169 len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
7170 ASC_PRT_NEXT();
7171 for (i = 0; i <= ADV_MAX_TID; i++) {
7172 if ((chip_scsi_id == i) ||
7173 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7174 continue;
7175 }
7176
7177 AdvReadWordLram(iop_base,
7178 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7179 lramword);
7180
7181 len = asc_prt_line(cp, leftlen, " %X:%d",
7182 i, (lramword & 0x8000) ? 16 : 8);
7183 ASC_PRT_NEXT();
7184
7185 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
7186 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7187 len = asc_prt_line(cp, leftlen, "*");
7188 ASC_PRT_NEXT();
7189 renegotiate = 1;
7190 }
7191 }
7192 len = asc_prt_line(cp, leftlen, "\n");
7193 ASC_PRT_NEXT();
7194
7195 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7196 len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
7197 ASC_PRT_NEXT();
7198 for (i = 0; i <= ADV_MAX_TID; i++) {
7199 if ((chip_scsi_id == i) ||
7200 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7201 continue;
7202 }
7203
7204 len = asc_prt_line(cp, leftlen, " %X:%c",
7205 i,
7206 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7207 'N');
7208 ASC_PRT_NEXT();
7209 }
7210 len = asc_prt_line(cp, leftlen, "\n");
7211 ASC_PRT_NEXT();
7212
7213 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
7214 for (i = 0; i <= ADV_MAX_TID; i++) {
7215
7216 AdvReadWordLram(iop_base,
7217 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7218 lramword);
7219 lramword &= ~0x8000;
7220
7221 if ((chip_scsi_id == i) ||
7222 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
7223 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
7224 continue;
7225 }
7226
7227 len = asc_prt_line(cp, leftlen, " %X:", i);
7228 ASC_PRT_NEXT();
7229
7230 if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */
7231 len = asc_prt_line(cp, leftlen, " Asynchronous");
7232 ASC_PRT_NEXT();
7233 } else {
7234 len =
7235 asc_prt_line(cp, leftlen,
7236 " Transfer Period Factor: ");
7237 ASC_PRT_NEXT();
7238
7239 if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */
7240 len =
7241 asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
7242 ASC_PRT_NEXT();
7243 } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */
7244 len =
7245 asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
7246 ASC_PRT_NEXT();
7247 } else { /* 20 Mhz or below. */
7248
7249 period = (((lramword >> 8) * 25) + 50) / 4;
7250
7251 if (period == 0) { /* Should never happen. */
7252 len =
7253 asc_prt_line(cp, leftlen,
7254 "%d (? Mhz), ");
7255 ASC_PRT_NEXT();
7256 } else {
7257 len = asc_prt_line(cp, leftlen,
7258 "%d (%d.%d Mhz),",
7259 period, 250 / period,
7260 ASC_TENTHS(250,
7261 period));
7262 ASC_PRT_NEXT();
7263 }
7264 }
7265
7266 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
7267 lramword & 0x1F);
7268 ASC_PRT_NEXT();
7269 }
7270
7271 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7272 len = asc_prt_line(cp, leftlen, "*\n");
7273 renegotiate = 1;
7274 } else {
7275 len = asc_prt_line(cp, leftlen, "\n");
7276 }
7277 ASC_PRT_NEXT();
7278 }
1da177e4 7279
27c868c2
MW
7280 if (renegotiate) {
7281 len = asc_prt_line(cp, leftlen,
7282 " * = Re-negotiation pending before next command.\n");
7283 ASC_PRT_NEXT();
7284 }
1da177e4 7285
27c868c2 7286 return totlen;
1da177e4
LT
7287}
7288
7289/*
7290 * asc_proc_copy()
7291 *
7292 * Copy proc information to a read buffer taking into account the current
7293 * read offset in the file and the remaining space in the read buffer.
7294 */
27c868c2 7295static int
1da177e4 7296asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
27c868c2 7297 char *cp, int cplen)
1da177e4 7298{
27c868c2
MW
7299 int cnt = 0;
7300
7301 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
7302 (unsigned)offset, (unsigned)advoffset, cplen);
7303 if (offset <= advoffset) {
7304 /* Read offset below current offset, copy everything. */
7305 cnt = min(cplen, leftlen);
7306 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7307 (ulong)curbuf, (ulong)cp, cnt);
7308 memcpy(curbuf, cp, cnt);
7309 } else if (offset < advoffset + cplen) {
7310 /* Read offset within current range, partial copy. */
7311 cnt = (advoffset + cplen) - offset;
7312 cp = (cp + cplen) - cnt;
7313 cnt = min(cnt, leftlen);
7314 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7315 (ulong)curbuf, (ulong)cp, cnt);
7316 memcpy(curbuf, cp, cnt);
7317 }
7318 return cnt;
1da177e4
LT
7319}
7320
7321/*
7322 * asc_prt_line()
7323 *
7324 * If 'cp' is NULL print to the console, otherwise print to a buffer.
7325 *
7326 * Return 0 if printing to the console, otherwise return the number of
7327 * bytes written to the buffer.
7328 *
7329 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
7330 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
7331 */
27c868c2 7332static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
1da177e4 7333{
27c868c2
MW
7334 va_list args;
7335 int ret;
7336 char s[ASC_PRTLINE_SIZE];
7337
7338 va_start(args, fmt);
7339 ret = vsprintf(s, fmt, args);
7340 ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
7341 if (buf == NULL) {
7342 (void)printk(s);
7343 ret = 0;
7344 } else {
7345 ret = min(buflen, ret);
7346 memcpy(buf, s, ret);
7347 }
7348 va_end(args);
7349 return ret;
1da177e4
LT
7350}
7351#endif /* CONFIG_PROC_FS */
7352
1da177e4
LT
7353/*
7354 * --- Functions Required by the Asc Library
7355 */
7356
7357/*
7358 * Delay for 'n' milliseconds. Don't use the 'jiffies'
7359 * global variable which is incremented once every 5 ms
7360 * from a timer interrupt, because this function may be
7361 * called when interrupts are disabled.
7362 */
27c868c2 7363static void DvcSleepMilliSecond(ADV_DCNT n)
1da177e4 7364{
27c868c2
MW
7365 ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong)n);
7366 mdelay(n);
1da177e4
LT
7367}
7368
7369/*
7370 * Currently and inline noop but leave as a placeholder.
7371 * Leave DvcEnterCritical() as a noop placeholder.
7372 */
27c868c2 7373static inline ulong DvcEnterCritical(void)
1da177e4 7374{
27c868c2 7375 return 0;
1da177e4
LT
7376}
7377
7378/*
7379 * Critical sections are all protected by the board spinlock.
7380 * Leave DvcLeaveCritical() as a noop placeholder.
7381 */
27c868c2 7382static inline void DvcLeaveCritical(ulong flags)
1da177e4 7383{
27c868c2 7384 return;
1da177e4
LT
7385}
7386
7387/*
7388 * void
7389 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7390 *
7391 * Calling/Exit State:
7392 * none
7393 *
7394 * Description:
7395 * Output an ASC_SCSI_Q structure to the chip
7396 */
27c868c2 7397static void
1da177e4
LT
7398DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7399{
27c868c2
MW
7400 int i;
7401
7402 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
7403 AscSetChipLramAddr(iop_base, s_addr);
7404 for (i = 0; i < 2 * words; i += 2) {
7405 if (i == 4 || i == 20) {
7406 continue;
7407 }
7408 outpw(iop_base + IOP_RAM_DATA,
7409 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
7410 }
1da177e4
LT
7411}
7412
7413/*
7414 * void
7415 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7416 *
7417 * Calling/Exit State:
7418 * none
7419 *
7420 * Description:
7421 * Input an ASC_QDONE_INFO structure from the chip
7422 */
27c868c2 7423static void
1da177e4
LT
7424DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7425{
27c868c2
MW
7426 int i;
7427 ushort word;
7428
7429 AscSetChipLramAddr(iop_base, s_addr);
7430 for (i = 0; i < 2 * words; i += 2) {
7431 if (i == 10) {
7432 continue;
7433 }
7434 word = inpw(iop_base + IOP_RAM_DATA);
7435 inbuf[i] = word & 0xff;
7436 inbuf[i + 1] = (word >> 8) & 0xff;
7437 }
7438 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
1da177e4
LT
7439}
7440
7441/*
7442 * Read a PCI configuration byte.
7443 */
27c868c2 7444static uchar __init DvcReadPCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset)
1da177e4
LT
7445{
7446#ifdef CONFIG_PCI
27c868c2
MW
7447 uchar byte_data;
7448 pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
7449 return byte_data;
1da177e4 7450#else /* !defined(CONFIG_PCI) */
27c868c2 7451 return 0;
1da177e4
LT
7452#endif /* !defined(CONFIG_PCI) */
7453}
7454
7455/*
7456 * Write a PCI configuration byte.
7457 */
27c868c2
MW
7458static void __init
7459DvcWritePCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset, uchar byte_data)
1da177e4
LT
7460{
7461#ifdef CONFIG_PCI
27c868c2 7462 pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
1da177e4
LT
7463#endif /* CONFIG_PCI */
7464}
7465
7466/*
7467 * Return the BIOS address of the adapter at the specified
7468 * I/O port and with the specified bus type.
7469 */
27c868c2 7470static ushort __init AscGetChipBiosAddress(PortAddr iop_base, ushort bus_type)
1da177e4 7471{
27c868c2
MW
7472 ushort cfg_lsw;
7473 ushort bios_addr;
7474
7475 /*
7476 * The PCI BIOS is re-located by the motherboard BIOS. Because
7477 * of this the driver can not determine where a PCI BIOS is
7478 * loaded and executes.
7479 */
7480 if (bus_type & ASC_IS_PCI) {
7481 return (0);
7482 }
1da177e4 7483#ifdef CONFIG_ISA
27c868c2
MW
7484 if ((bus_type & ASC_IS_EISA) != 0) {
7485 cfg_lsw = AscGetEisaChipCfg(iop_base);
7486 cfg_lsw &= 0x000F;
7487 bios_addr = (ushort)(ASC_BIOS_MIN_ADDR +
7488 (cfg_lsw * ASC_BIOS_BANK_SIZE));
7489 return (bios_addr);
7490 } /* if */
1da177e4
LT
7491#endif /* CONFIG_ISA */
7492
27c868c2 7493 cfg_lsw = AscGetChipCfgLsw(iop_base);
1da177e4 7494
27c868c2
MW
7495 /*
7496 * ISA PnP uses the top bit as the 32K BIOS flag
7497 */
7498 if (bus_type == ASC_IS_ISAPNP) {
7499 cfg_lsw &= 0x7FFF;
7500 }
7501 /* if */
7502 bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
7503 ASC_BIOS_MIN_ADDR);
7504 return (bios_addr);
1da177e4
LT
7505}
7506
1da177e4
LT
7507/*
7508 * --- Functions Required by the Adv Library
7509 */
7510
7511/*
7512 * DvcGetPhyAddr()
7513 *
7514 * Return the physical address of 'vaddr' and set '*lenp' to the
7515 * number of physically contiguous bytes that follow 'vaddr'.
7516 * 'flag' indicates the type of structure whose physical address
7517 * is being translated.
7518 *
7519 * Note: Because Linux currently doesn't page the kernel and all
7520 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
7521 */
7522ADV_PADDR
7523DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
27c868c2 7524 uchar *vaddr, ADV_SDCNT *lenp, int flag)
1da177e4 7525{
27c868c2 7526 ADV_PADDR paddr;
1da177e4 7527
27c868c2 7528 paddr = virt_to_bus(vaddr);
1da177e4 7529
27c868c2
MW
7530 ASC_DBG4(4,
7531 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
7532 (ulong)vaddr, (ulong)lenp, (ulong)*((ulong *)lenp),
7533 (ulong)paddr);
1da177e4 7534
27c868c2 7535 return paddr;
1da177e4
LT
7536}
7537
7538/*
7539 * Read a PCI configuration byte.
7540 */
27c868c2 7541static uchar __init DvcAdvReadPCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset)
1da177e4
LT
7542{
7543#ifdef CONFIG_PCI
27c868c2
MW
7544 uchar byte_data;
7545 pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
7546 return byte_data;
1da177e4 7547#else /* CONFIG_PCI */
27c868c2 7548 return 0;
1da177e4
LT
7549#endif /* CONFIG_PCI */
7550}
7551
7552/*
7553 * Write a PCI configuration byte.
7554 */
27c868c2
MW
7555static void __init
7556DvcAdvWritePCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset, uchar byte_data)
1da177e4
LT
7557{
7558#ifdef CONFIG_PCI
27c868c2 7559 pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
1da177e4 7560#else /* CONFIG_PCI */
27c868c2 7561 return;
1da177e4
LT
7562#endif /* CONFIG_PCI */
7563}
7564
7565/*
7566 * --- Tracing and Debugging Functions
7567 */
7568
7569#ifdef ADVANSYS_STATS
7570#ifdef CONFIG_PROC_FS
7571/*
7572 * asc_prt_board_stats()
7573 *
7574 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7575 * cf. asc_prt_line().
7576 *
7577 * Return the number of characters copied into 'cp'. No more than
7578 * 'cplen' characters will be copied to 'cp'.
7579 */
27c868c2 7580static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 7581{
27c868c2
MW
7582 int leftlen;
7583 int totlen;
7584 int len;
7585 struct asc_stats *s;
7586 asc_board_t *boardp;
1da177e4 7587
27c868c2
MW
7588 leftlen = cplen;
7589 totlen = len = 0;
7590
7591 boardp = ASC_BOARDP(shost);
7592 s = &boardp->asc_stats;
7593
7594 len = asc_prt_line(cp, leftlen,
7595 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
7596 shost->host_no);
7597 ASC_PRT_NEXT();
7598
7599 len = asc_prt_line(cp, leftlen,
7600 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
7601 s->queuecommand, s->reset, s->biosparam,
7602 s->interrupt);
7603 ASC_PRT_NEXT();
7604
7605 len = asc_prt_line(cp, leftlen,
7606 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
7607 s->callback, s->done, s->build_error,
7608 s->adv_build_noreq, s->adv_build_nosg);
7609 ASC_PRT_NEXT();
7610
7611 len = asc_prt_line(cp, leftlen,
7612 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
7613 s->exe_noerror, s->exe_busy, s->exe_error,
7614 s->exe_unknown);
7615 ASC_PRT_NEXT();
7616
7617 /*
7618 * Display data transfer statistics.
7619 */
7620 if (s->cont_cnt > 0) {
7621 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
7622 ASC_PRT_NEXT();
7623
7624 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
7625 s->cont_xfer / 2,
7626 ASC_TENTHS(s->cont_xfer, 2));
7627 ASC_PRT_NEXT();
7628
7629 /* Contiguous transfer average size */
7630 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
7631 (s->cont_xfer / 2) / s->cont_cnt,
7632 ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
7633 ASC_PRT_NEXT();
7634 }
1da177e4 7635
27c868c2 7636 if (s->sg_cnt > 0) {
1da177e4 7637
27c868c2
MW
7638 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
7639 s->sg_cnt, s->sg_elem);
7640 ASC_PRT_NEXT();
1da177e4 7641
27c868c2
MW
7642 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
7643 s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
7644 ASC_PRT_NEXT();
1da177e4 7645
27c868c2
MW
7646 /* Scatter gather transfer statistics */
7647 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
7648 s->sg_elem / s->sg_cnt,
7649 ASC_TENTHS(s->sg_elem, s->sg_cnt));
7650 ASC_PRT_NEXT();
1da177e4 7651
27c868c2
MW
7652 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
7653 (s->sg_xfer / 2) / s->sg_elem,
7654 ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
7655 ASC_PRT_NEXT();
1da177e4 7656
27c868c2
MW
7657 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
7658 (s->sg_xfer / 2) / s->sg_cnt,
7659 ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
7660 ASC_PRT_NEXT();
7661 }
1da177e4 7662
27c868c2
MW
7663 /*
7664 * Display request queuing statistics.
7665 */
7666 len = asc_prt_line(cp, leftlen,
7667 " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
7668 HZ);
7669 ASC_PRT_NEXT();
1da177e4 7670
27c868c2 7671 return totlen;
1da177e4
LT
7672}
7673
7674/*
7675 * asc_prt_target_stats()
7676 *
7677 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7678 * cf. asc_prt_line().
7679 *
7680 * This is separated from asc_prt_board_stats because a full set
7681 * of targets will overflow ASC_PRTBUF_SIZE.
7682 *
7683 * Return the number of characters copied into 'cp'. No more than
7684 * 'cplen' characters will be copied to 'cp'.
7685 */
27c868c2
MW
7686static int
7687asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen)
1da177e4 7688{
27c868c2
MW
7689 int leftlen;
7690 int totlen;
7691 int len;
7692 struct asc_stats *s;
7693 ushort chip_scsi_id;
7694 asc_board_t *boardp;
7695 asc_queue_t *active;
7696 asc_queue_t *waiting;
1da177e4 7697
27c868c2
MW
7698 leftlen = cplen;
7699 totlen = len = 0;
7700
7701 boardp = ASC_BOARDP(shost);
7702 s = &boardp->asc_stats;
7703
7704 active = &ASC_BOARDP(shost)->active;
7705 waiting = &ASC_BOARDP(shost)->waiting;
7706
7707 if (ASC_NARROW_BOARD(boardp)) {
7708 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7709 } else {
7710 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7711 }
7712
7713 if ((chip_scsi_id == tgt_id) ||
7714 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
7715 return 0;
7716 }
1da177e4 7717
27c868c2
MW
7718 do {
7719 if (active->q_tot_cnt[tgt_id] > 0
7720 || waiting->q_tot_cnt[tgt_id] > 0) {
7721 len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
7722 ASC_PRT_NEXT();
7723
7724 len = asc_prt_line(cp, leftlen,
7725 " active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
7726 active->q_cur_cnt[tgt_id],
7727 active->q_max_cnt[tgt_id],
7728 active->q_tot_cnt[tgt_id],
7729 active->q_min_tim[tgt_id],
7730 active->q_max_tim[tgt_id],
7731 (active->q_tot_cnt[tgt_id] ==
7732 0) ? 0 : (active->
7733 q_tot_tim[tgt_id] /
7734 active->
7735 q_tot_cnt[tgt_id]),
7736 (active->q_tot_cnt[tgt_id] ==
7737 0) ? 0 : ASC_TENTHS(active->
7738 q_tot_tim
7739 [tgt_id],
7740 active->
7741 q_tot_cnt
7742 [tgt_id]));
7743 ASC_PRT_NEXT();
7744
7745 len = asc_prt_line(cp, leftlen,
7746 " waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
7747 waiting->q_cur_cnt[tgt_id],
7748 waiting->q_max_cnt[tgt_id],
7749 waiting->q_tot_cnt[tgt_id],
7750 waiting->q_min_tim[tgt_id],
7751 waiting->q_max_tim[tgt_id],
7752 (waiting->q_tot_cnt[tgt_id] ==
7753 0) ? 0 : (waiting->
7754 q_tot_tim[tgt_id] /
7755 waiting->
7756 q_tot_cnt[tgt_id]),
7757 (waiting->q_tot_cnt[tgt_id] ==
7758 0) ? 0 : ASC_TENTHS(waiting->
7759 q_tot_tim
7760 [tgt_id],
7761 waiting->
7762 q_tot_cnt
7763 [tgt_id]));
7764 ASC_PRT_NEXT();
7765 }
7766 } while (0);
7767
7768 return totlen;
1da177e4
LT
7769}
7770#endif /* CONFIG_PROC_FS */
7771#endif /* ADVANSYS_STATS */
7772
7773#ifdef ADVANSYS_DEBUG
7774/*
7775 * asc_prt_scsi_host()
7776 */
27c868c2 7777static void asc_prt_scsi_host(struct Scsi_Host *s)
1da177e4 7778{
27c868c2
MW
7779 asc_board_t *boardp;
7780
7781 boardp = ASC_BOARDP(s);
7782
7783 printk("Scsi_Host at addr 0x%lx\n", (ulong)s);
7784 printk(" host_busy %u, host_no %d, last_reset %d,\n",
7785 s->host_busy, s->host_no, (unsigned)s->last_reset);
7786
7787 printk(" base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
7788 (ulong)s->base, (ulong)s->io_port, s->n_io_port, s->irq);
7789
7790 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
7791 s->dma_channel, s->this_id, s->can_queue);
7792
7793 printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
7794 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
7795
7796 if (ASC_NARROW_BOARD(boardp)) {
7797 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
7798 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
7799 } else {
7800 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
7801 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
7802 }
1da177e4
LT
7803}
7804
7805/*
7806 * asc_prt_scsi_cmnd()
7807 */
27c868c2 7808static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
1da177e4 7809{
27c868c2 7810 printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s);
1da177e4 7811
27c868c2
MW
7812 printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
7813 (ulong)s->device->host, (ulong)s->device, s->device->id,
7814 s->device->lun, s->device->channel);
1da177e4 7815
27c868c2 7816 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
1da177e4 7817
27c868c2
MW
7818 printk("sc_data_direction %u, resid %d\n",
7819 s->sc_data_direction, s->resid);
1da177e4 7820
27c868c2 7821 printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len);
1da177e4 7822
27c868c2
MW
7823 printk(" serial_number 0x%x, retries %d, allowed %d\n",
7824 (unsigned)s->serial_number, s->retries, s->allowed);
1da177e4 7825
27c868c2 7826 printk(" timeout_per_command %d\n", s->timeout_per_command);
1da177e4 7827
27c868c2
MW
7828 printk
7829 (" scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
7830 (ulong)s->scsi_done, (ulong)s->done, (ulong)s->host_scribble,
7831 s->result);
1da177e4 7832
27c868c2 7833 printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
1da177e4
LT
7834}
7835
7836/*
7837 * asc_prt_asc_dvc_var()
7838 */
27c868c2 7839static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
1da177e4 7840{
27c868c2
MW
7841 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
7842
7843 printk
7844 (" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n",
7845 h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
7846
7847 printk
7848 (" bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n",
7849 h->bus_type, (ulong)h->isr_callback, (ulong)h->exe_callback,
7850 (unsigned)h->init_sdtr);
7851
7852 printk
7853 (" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n",
7854 (unsigned)h->sdtr_done, (unsigned)h->use_tagged_qng,
7855 (unsigned)h->unit_not_ready, (unsigned)h->chip_no);
7856
7857 printk
7858 (" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n",
7859 (unsigned)h->queue_full_or_busy, (unsigned)h->start_motor,
7860 (unsigned)h->scsi_reset_wait);
7861
7862 printk
7863 (" is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n",
7864 (unsigned)h->is_in_int, (unsigned)h->max_total_qng,
7865 (unsigned)h->cur_total_qng, (unsigned)h->in_critical_cnt);
7866
7867 printk
7868 (" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n",
7869 (unsigned)h->last_q_shortage, (unsigned)h->init_state,
7870 (unsigned)h->no_scam, (unsigned)h->pci_fix_asyn_xfer);
7871
7872 printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no);
1da177e4
LT
7873}
7874
7875/*
7876 * asc_prt_asc_dvc_cfg()
7877 */
27c868c2 7878static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
1da177e4 7879{
27c868c2
MW
7880 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
7881
7882 printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
7883 h->can_tagged_qng, h->cmd_qng_enabled);
7884 printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
7885 h->disc_enable, h->sdtr_enable);
7886
7887 printk
7888 (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
7889 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
7890 h->chip_version);
7891
7892 printk
7893 (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
7894 to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
7895 h->mcode_date);
7896
7897 printk(" mcode_version %d, overrun_buf 0x%lx\n",
7898 h->mcode_version, (ulong)h->overrun_buf);
1da177e4
LT
7899}
7900
7901/*
7902 * asc_prt_asc_scsi_q()
7903 */
27c868c2 7904static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
1da177e4 7905{
27c868c2
MW
7906 ASC_SG_HEAD *sgp;
7907 int i;
7908
7909 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
7910
7911 printk
7912 (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
7913 q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
7914 q->q2.tag_code);
7915
7916 printk
7917 (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7918 (ulong)le32_to_cpu(q->q1.data_addr),
7919 (ulong)le32_to_cpu(q->q1.data_cnt),
7920 (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
7921
7922 printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
7923 (ulong)q->cdbptr, q->q2.cdb_len,
7924 (ulong)q->sg_head, q->q1.sg_queue_cnt);
7925
7926 if (q->sg_head) {
7927 sgp = q->sg_head;
7928 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
7929 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
7930 sgp->queue_cnt);
7931 for (i = 0; i < sgp->entry_cnt; i++) {
7932 printk(" [%u]: addr 0x%lx, bytes %lu\n",
7933 i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
7934 (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
7935 }
1da177e4 7936
27c868c2 7937 }
1da177e4
LT
7938}
7939
7940/*
7941 * asc_prt_asc_qdone_info()
7942 */
27c868c2 7943static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
1da177e4 7944{
27c868c2
MW
7945 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
7946 printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
7947 (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
7948 q->d2.tag_code);
7949 printk
7950 (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
7951 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
1da177e4
LT
7952}
7953
7954/*
7955 * asc_prt_adv_dvc_var()
7956 *
7957 * Display an ADV_DVC_VAR structure.
7958 */
27c868c2 7959static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
1da177e4 7960{
27c868c2
MW
7961 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
7962
7963 printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
7964 (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
7965
7966 printk(" isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
7967 (ulong)h->isr_callback, (unsigned)h->sdtr_able,
7968 (unsigned)h->wdtr_able);
7969
7970 printk(" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
7971 (unsigned)h->start_motor,
7972 (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no);
7973
7974 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
7975 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
7976 (ulong)h->carr_freelist);
7977
7978 printk(" icq_sp 0x%lx, irq_sp 0x%lx\n",
7979 (ulong)h->icq_sp, (ulong)h->irq_sp);
7980
7981 printk(" no_scam 0x%x, tagqng_able 0x%x\n",
7982 (unsigned)h->no_scam, (unsigned)h->tagqng_able);
7983
7984 printk(" chip_scsi_id 0x%x, cfg 0x%lx\n",
7985 (unsigned)h->chip_scsi_id, (ulong)h->cfg);
1da177e4
LT
7986}
7987
7988/*
7989 * asc_prt_adv_dvc_cfg()
7990 *
7991 * Display an ADV_DVC_CFG structure.
7992 */
27c868c2 7993static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
1da177e4 7994{
27c868c2 7995 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
1da177e4 7996
27c868c2
MW
7997 printk(" disc_enable 0x%x, termination 0x%x\n",
7998 h->disc_enable, h->termination);
1da177e4 7999
27c868c2
MW
8000 printk(" chip_version 0x%x, mcode_date 0x%x\n",
8001 h->chip_version, h->mcode_date);
1da177e4 8002
27c868c2
MW
8003 printk(" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
8004 h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
1da177e4 8005
27c868c2
MW
8006 printk(" control_flag 0x%x, pci_slot_info 0x%x\n",
8007 h->control_flag, h->pci_slot_info);
1da177e4
LT
8008}
8009
8010/*
8011 * asc_prt_adv_scsi_req_q()
8012 *
8013 * Display an ADV_SCSI_REQ_Q structure.
8014 */
27c868c2 8015static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
1da177e4 8016{
27c868c2
MW
8017 int sg_blk_cnt;
8018 struct asc_sg_block *sg_ptr;
8019
8020 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
8021
8022 printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
8023 q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
8024
8025 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
8026 q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
8027
8028 printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
8029 (ulong)le32_to_cpu(q->data_cnt),
8030 (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
8031
8032 printk
8033 (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
8034 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
8035
8036 printk(" sg_working_ix 0x%x, target_cmd %u\n",
8037 q->sg_working_ix, q->target_cmd);
8038
8039 printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
8040 (ulong)le32_to_cpu(q->scsiq_rptr),
8041 (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
8042
8043 /* Display the request's ADV_SG_BLOCK structures. */
8044 if (q->sg_list_ptr != NULL) {
8045 sg_blk_cnt = 0;
8046 while (1) {
8047 /*
8048 * 'sg_ptr' is a physical address. Convert it to a virtual
8049 * address by indexing 'sg_blk_cnt' into the virtual address
8050 * array 'sg_list_ptr'.
8051 *
8052 * XXX - Assumes all SG physical blocks are virtually contiguous.
8053 */
8054 sg_ptr =
8055 &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
8056 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
8057 if (sg_ptr->sg_ptr == 0) {
8058 break;
8059 }
8060 sg_blk_cnt++;
8061 }
8062 }
1da177e4
LT
8063}
8064
8065/*
8066 * asc_prt_adv_sgblock()
8067 *
8068 * Display an ADV_SG_BLOCK structure.
8069 */
27c868c2 8070static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
1da177e4 8071{
27c868c2
MW
8072 int i;
8073
8074 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
8075 (ulong)b, sgblockno);
8076 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
8077 b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
8078 ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
8079 if (b->sg_ptr != 0) {
8080 ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
8081 }
8082 for (i = 0; i < b->sg_cnt; i++) {
8083 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
8084 i, (ulong)b->sg_list[i].sg_addr,
8085 (ulong)b->sg_list[i].sg_count);
8086 }
1da177e4
LT
8087}
8088
8089/*
8090 * asc_prt_hex()
8091 *
8092 * Print hexadecimal output in 4 byte groupings 32 bytes
8093 * or 8 double-words per line.
8094 */
27c868c2 8095static void asc_prt_hex(char *f, uchar *s, int l)
1da177e4 8096{
27c868c2
MW
8097 int i;
8098 int j;
8099 int k;
8100 int m;
8101
8102 printk("%s: (%d bytes)\n", f, l);
8103
8104 for (i = 0; i < l; i += 32) {
8105
8106 /* Display a maximum of 8 double-words per line. */
8107 if ((k = (l - i) / 4) >= 8) {
8108 k = 8;
8109 m = 0;
8110 } else {
8111 m = (l - i) % 4;
8112 }
8113
8114 for (j = 0; j < k; j++) {
8115 printk(" %2.2X%2.2X%2.2X%2.2X",
8116 (unsigned)s[i + (j * 4)],
8117 (unsigned)s[i + (j * 4) + 1],
8118 (unsigned)s[i + (j * 4) + 2],
8119 (unsigned)s[i + (j * 4) + 3]);
8120 }
8121
8122 switch (m) {
8123 case 0:
8124 default:
8125 break;
8126 case 1:
8127 printk(" %2.2X", (unsigned)s[i + (j * 4)]);
8128 break;
8129 case 2:
8130 printk(" %2.2X%2.2X",
8131 (unsigned)s[i + (j * 4)],
8132 (unsigned)s[i + (j * 4) + 1]);
8133 break;
8134 case 3:
8135 printk(" %2.2X%2.2X%2.2X",
8136 (unsigned)s[i + (j * 4) + 1],
8137 (unsigned)s[i + (j * 4) + 2],
8138 (unsigned)s[i + (j * 4) + 3]);
8139 break;
8140 }
8141
8142 printk("\n");
8143 }
1da177e4
LT
8144}
8145#endif /* ADVANSYS_DEBUG */
8146
8147/*
8148 * --- Asc Library Functions
8149 */
8150
27c868c2 8151static ushort __init AscGetEisaChipCfg(PortAddr iop_base)
1da177e4 8152{
27c868c2 8153 PortAddr eisa_cfg_iop;
1da177e4 8154
27c868c2
MW
8155 eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8156 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
8157 return (inpw(eisa_cfg_iop));
1da177e4
LT
8158}
8159
27c868c2 8160static uchar __init AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
1da177e4 8161{
27c868c2 8162 ushort cfg_lsw;
1da177e4 8163
27c868c2
MW
8164 if (AscGetChipScsiID(iop_base) == new_host_id) {
8165 return (new_host_id);
8166 }
8167 cfg_lsw = AscGetChipCfgLsw(iop_base);
8168 cfg_lsw &= 0xF8FF;
8169 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
8170 AscSetChipCfgLsw(iop_base, cfg_lsw);
8171 return (AscGetChipScsiID(iop_base));
1da177e4
LT
8172}
8173
27c868c2 8174static uchar __init AscGetChipScsiCtrl(PortAddr iop_base)
1da177e4 8175{
27c868c2 8176 uchar sc;
1da177e4 8177
27c868c2
MW
8178 AscSetBank(iop_base, 1);
8179 sc = inp(iop_base + IOP_REG_SC);
8180 AscSetBank(iop_base, 0);
8181 return (sc);
1da177e4
LT
8182}
8183
27c868c2 8184static uchar __init AscGetChipVersion(PortAddr iop_base, ushort bus_type)
1da177e4 8185{
27c868c2
MW
8186 if ((bus_type & ASC_IS_EISA) != 0) {
8187 PortAddr eisa_iop;
8188 uchar revision;
8189 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8190 (PortAddr) ASC_EISA_REV_IOP_MASK;
8191 revision = inp(eisa_iop);
8192 return ((uchar)((ASC_CHIP_MIN_VER_EISA - 1) + revision));
8193 }
8194 return (AscGetChipVerNo(iop_base));
1da177e4
LT
8195}
8196
27c868c2 8197static ushort __init AscGetChipBusType(PortAddr iop_base)
1da177e4 8198{
27c868c2
MW
8199 ushort chip_ver;
8200
8201 chip_ver = AscGetChipVerNo(iop_base);
8202 if ((chip_ver >= ASC_CHIP_MIN_VER_VL)
8203 && (chip_ver <= ASC_CHIP_MAX_VER_VL)
8204 ) {
8205 if (((iop_base & 0x0C30) == 0x0C30)
8206 || ((iop_base & 0x0C50) == 0x0C50)
8207 ) {
8208 return (ASC_IS_EISA);
8209 }
8210 return (ASC_IS_VL);
8211 }
8212 if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
8213 (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
8214 if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
8215 return (ASC_IS_ISAPNP);
8216 }
8217 return (ASC_IS_ISA);
8218 } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
8219 (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
8220 return (ASC_IS_PCI);
8221 }
8222 return (0);
1da177e4
LT
8223}
8224
27c868c2
MW
8225static ASC_DCNT
8226AscLoadMicroCode(PortAddr iop_base,
8227 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
1da177e4 8228{
27c868c2
MW
8229 ASC_DCNT chksum;
8230 ushort mcode_word_size;
8231 ushort mcode_chksum;
8232
8233 /* Write the microcode buffer starting at LRAM address 0. */
8234 mcode_word_size = (ushort)(mcode_size >> 1);
8235 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
8236 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
8237
8238 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
8239 ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum);
8240 mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
8241 (ushort)ASC_CODE_SEC_BEG,
8242 (ushort)((mcode_size -
8243 s_addr - (ushort)
8244 ASC_CODE_SEC_BEG) /
8245 2));
8246 ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
8247 (ulong)mcode_chksum);
8248 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
8249 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
8250 return (chksum);
1da177e4
LT
8251}
8252
27c868c2 8253static int AscFindSignature(PortAddr iop_base)
1da177e4 8254{
27c868c2
MW
8255 ushort sig_word;
8256
8257 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
8258 iop_base, AscGetChipSignatureByte(iop_base));
8259 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
8260 ASC_DBG2(1,
8261 "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
8262 iop_base, AscGetChipSignatureWord(iop_base));
8263 sig_word = AscGetChipSignatureWord(iop_base);
8264 if ((sig_word == (ushort)ASC_1000_ID0W) ||
8265 (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
8266 return (1);
8267 }
8268 }
8269 return (0);
1da177e4
LT
8270}
8271
27c868c2
MW
8272static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __initdata = {
8273 0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
8274 ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
1da177e4
LT
8275};
8276
8277#ifdef CONFIG_ISA
27c868c2 8278static uchar _isa_pnp_inited __initdata = 0;
1da177e4 8279
27c868c2 8280static PortAddr __init AscSearchIOPortAddr(PortAddr iop_beg, ushort bus_type)
1da177e4 8281{
27c868c2
MW
8282 if (bus_type & ASC_IS_VL) {
8283 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
8284 if (AscGetChipVersion(iop_beg, bus_type) <=
8285 ASC_CHIP_MAX_VER_VL) {
8286 return (iop_beg);
8287 }
8288 }
8289 return (0);
8290 }
8291 if (bus_type & ASC_IS_ISA) {
8292 if (_isa_pnp_inited == 0) {
8293 AscSetISAPNPWaitForKey();
8294 _isa_pnp_inited++;
8295 }
8296 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
8297 if ((AscGetChipVersion(iop_beg, bus_type) &
8298 ASC_CHIP_VER_ISA_BIT) != 0) {
8299 return (iop_beg);
8300 }
8301 }
8302 return (0);
8303 }
8304 if (bus_type & ASC_IS_EISA) {
8305 if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
8306 return (iop_beg);
8307 }
8308 return (0);
8309 }
8310 return (0);
1da177e4
LT
8311}
8312
27c868c2 8313static PortAddr __init AscSearchIOPortAddr11(PortAddr s_addr)
1da177e4 8314{
27c868c2
MW
8315 int i;
8316 PortAddr iop_base;
1da177e4 8317
27c868c2
MW
8318 for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
8319 if (_asc_def_iop_base[i] > s_addr) {
8320 break;
8321 }
8322 }
8323 for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
8324 iop_base = _asc_def_iop_base[i];
8325 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
8326 ASC_DBG1(1,
8327 "AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n",
8328 iop_base);
8329 continue;
8330 }
8331 ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n",
8332 iop_base);
8333 release_region(iop_base, ASC_IOADR_GAP);
8334 if (AscFindSignature(iop_base)) {
8335 return (iop_base);
8336 }
8337 }
8338 return (0);
1da177e4
LT
8339}
8340
27c868c2 8341static void __init AscSetISAPNPWaitForKey(void)
1da177e4 8342{
27c868c2
MW
8343 outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
8344 outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
8345 return;
1da177e4
LT
8346}
8347#endif /* CONFIG_ISA */
8348
27c868c2 8349static void __init AscToggleIRQAct(PortAddr iop_base)
1da177e4 8350{
27c868c2
MW
8351 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
8352 AscSetChipStatus(iop_base, 0);
8353 return;
1da177e4
LT
8354}
8355
27c868c2 8356static uchar __init AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
1da177e4 8357{
27c868c2
MW
8358 ushort cfg_lsw;
8359 uchar chip_irq;
8360
8361 if ((bus_type & ASC_IS_EISA) != 0) {
8362 cfg_lsw = AscGetEisaChipCfg(iop_base);
8363 chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10);
8364 if ((chip_irq == 13) || (chip_irq > 15)) {
8365 return (0);
8366 }
8367 return (chip_irq);
8368 }
8369 if ((bus_type & ASC_IS_VL) != 0) {
8370 cfg_lsw = AscGetChipCfgLsw(iop_base);
8371 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07));
8372 if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) {
8373 return (0);
8374 }
8375 return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1)));
8376 }
8377 cfg_lsw = AscGetChipCfgLsw(iop_base);
8378 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03));
8379 if (chip_irq == 3)
8380 chip_irq += (uchar)2;
8381 return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
1da177e4
LT
8382}
8383
27c868c2
MW
8384static uchar __init
8385AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
1da177e4 8386{
27c868c2
MW
8387 ushort cfg_lsw;
8388
8389 if ((bus_type & ASC_IS_VL) != 0) {
8390 if (irq_no != 0) {
8391 if ((irq_no < ASC_MIN_IRQ_NO)
8392 || (irq_no > ASC_MAX_IRQ_NO)) {
8393 irq_no = 0;
8394 } else {
8395 irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1));
8396 }
8397 }
8398 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3);
8399 cfg_lsw |= (ushort)0x0010;
8400 AscSetChipCfgLsw(iop_base, cfg_lsw);
8401 AscToggleIRQAct(iop_base);
8402 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0);
8403 cfg_lsw |= (ushort)((irq_no & 0x07) << 2);
8404 AscSetChipCfgLsw(iop_base, cfg_lsw);
8405 AscToggleIRQAct(iop_base);
8406 return (AscGetChipIRQ(iop_base, bus_type));
8407 }
8408 if ((bus_type & (ASC_IS_ISA)) != 0) {
8409 if (irq_no == 15)
8410 irq_no -= (uchar)2;
8411 irq_no -= (uchar)ASC_MIN_IRQ_NO;
8412 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3);
8413 cfg_lsw |= (ushort)((irq_no & 0x03) << 2);
8414 AscSetChipCfgLsw(iop_base, cfg_lsw);
8415 return (AscGetChipIRQ(iop_base, bus_type));
8416 }
8417 return (0);
1da177e4
LT
8418}
8419
8420#ifdef CONFIG_ISA
27c868c2 8421static void __init AscEnableIsaDma(uchar dma_channel)
1da177e4 8422{
27c868c2
MW
8423 if (dma_channel < 4) {
8424 outp(0x000B, (ushort)(0xC0 | dma_channel));
8425 outp(0x000A, dma_channel);
8426 } else if (dma_channel < 8) {
8427 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
8428 outp(0x00D4, (ushort)(dma_channel - 4));
8429 }
8430 return;
1da177e4
LT
8431}
8432#endif /* CONFIG_ISA */
8433
27c868c2 8434static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
1da177e4 8435{
27c868c2
MW
8436 EXT_MSG ext_msg;
8437 EXT_MSG out_msg;
8438 ushort halt_q_addr;
8439 int sdtr_accept;
8440 ushort int_halt_code;
8441 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8442 ASC_SCSI_BIT_ID_TYPE target_id;
8443 PortAddr iop_base;
8444 uchar tag_code;
8445 uchar q_status;
8446 uchar halt_qp;
8447 uchar sdtr_data;
8448 uchar target_ix;
8449 uchar q_cntl, tid_no;
8450 uchar cur_dvc_qng;
8451 uchar asyn_sdtr;
8452 uchar scsi_status;
8453 asc_board_t *boardp;
8454
8455 ASC_ASSERT(asc_dvc->drv_ptr != NULL);
8456 boardp = asc_dvc->drv_ptr;
8457
8458 iop_base = asc_dvc->iop_base;
8459 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
8460
8461 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
8462 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
8463 target_ix = AscReadLramByte(iop_base,
8464 (ushort)(halt_q_addr +
8465 (ushort)ASC_SCSIQ_B_TARGET_IX));
8466 q_cntl =
8467 AscReadLramByte(iop_base,
8468 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8469 tid_no = ASC_TIX_TO_TID(target_ix);
8470 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
8471 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8472 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
8473 } else {
8474 asyn_sdtr = 0;
8475 }
8476 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
8477 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8478 AscSetChipSDTR(iop_base, 0, tid_no);
8479 boardp->sdtr_data[tid_no] = 0;
8480 }
8481 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8482 return (0);
8483 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
8484 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8485 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8486 boardp->sdtr_data[tid_no] = asyn_sdtr;
8487 }
8488 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8489 return (0);
8490 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
8491
8492 AscMemWordCopyPtrFromLram(iop_base,
8493 ASCV_MSGIN_BEG,
8494 (uchar *)&ext_msg,
8495 sizeof(EXT_MSG) >> 1);
8496
8497 if (ext_msg.msg_type == MS_EXTEND &&
8498 ext_msg.msg_req == MS_SDTR_CODE &&
8499 ext_msg.msg_len == MS_SDTR_LEN) {
8500 sdtr_accept = TRUE;
8501 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
8502
8503 sdtr_accept = FALSE;
8504 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
8505 }
8506 if ((ext_msg.xfer_period <
8507 asc_dvc->sdtr_period_tbl[asc_dvc->
8508 host_init_sdtr_index])
8509 || (ext_msg.xfer_period >
8510 asc_dvc->sdtr_period_tbl[asc_dvc->
8511 max_sdtr_index])) {
8512 sdtr_accept = FALSE;
8513 ext_msg.xfer_period =
8514 asc_dvc->sdtr_period_tbl[asc_dvc->
8515 host_init_sdtr_index];
8516 }
8517 if (sdtr_accept) {
8518 sdtr_data =
8519 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
8520 ext_msg.req_ack_offset);
8521 if ((sdtr_data == 0xFF)) {
8522
8523 q_cntl |= QC_MSG_OUT;
8524 asc_dvc->init_sdtr &= ~target_id;
8525 asc_dvc->sdtr_done &= ~target_id;
8526 AscSetChipSDTR(iop_base, asyn_sdtr,
8527 tid_no);
8528 boardp->sdtr_data[tid_no] = asyn_sdtr;
8529 }
8530 }
8531 if (ext_msg.req_ack_offset == 0) {
8532
8533 q_cntl &= ~QC_MSG_OUT;
8534 asc_dvc->init_sdtr &= ~target_id;
8535 asc_dvc->sdtr_done &= ~target_id;
8536 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8537 } else {
8538 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
8539
8540 q_cntl &= ~QC_MSG_OUT;
8541 asc_dvc->sdtr_done |= target_id;
8542 asc_dvc->init_sdtr |= target_id;
8543 asc_dvc->pci_fix_asyn_xfer &=
8544 ~target_id;
8545 sdtr_data =
8546 AscCalSDTRData(asc_dvc,
8547 ext_msg.xfer_period,
8548 ext_msg.
8549 req_ack_offset);
8550 AscSetChipSDTR(iop_base, sdtr_data,
8551 tid_no);
8552 boardp->sdtr_data[tid_no] = sdtr_data;
8553 } else {
8554
8555 q_cntl |= QC_MSG_OUT;
8556 AscMsgOutSDTR(asc_dvc,
8557 ext_msg.xfer_period,
8558 ext_msg.req_ack_offset);
8559 asc_dvc->pci_fix_asyn_xfer &=
8560 ~target_id;
8561 sdtr_data =
8562 AscCalSDTRData(asc_dvc,
8563 ext_msg.xfer_period,
8564 ext_msg.
8565 req_ack_offset);
8566 AscSetChipSDTR(iop_base, sdtr_data,
8567 tid_no);
8568 boardp->sdtr_data[tid_no] = sdtr_data;
8569 asc_dvc->sdtr_done |= target_id;
8570 asc_dvc->init_sdtr |= target_id;
8571 }
8572 }
8573
8574 AscWriteLramByte(iop_base,
8575 (ushort)(halt_q_addr +
8576 (ushort)ASC_SCSIQ_B_CNTL),
8577 q_cntl);
8578 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8579 return (0);
8580 } else if (ext_msg.msg_type == MS_EXTEND &&
8581 ext_msg.msg_req == MS_WDTR_CODE &&
8582 ext_msg.msg_len == MS_WDTR_LEN) {
8583
8584 ext_msg.wdtr_width = 0;
8585 AscMemWordCopyPtrToLram(iop_base,
8586 ASCV_MSGOUT_BEG,
8587 (uchar *)&ext_msg,
8588 sizeof(EXT_MSG) >> 1);
8589 q_cntl |= QC_MSG_OUT;
8590 AscWriteLramByte(iop_base,
8591 (ushort)(halt_q_addr +
8592 (ushort)ASC_SCSIQ_B_CNTL),
8593 q_cntl);
8594 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8595 return (0);
8596 } else {
8597
8598 ext_msg.msg_type = MESSAGE_REJECT;
8599 AscMemWordCopyPtrToLram(iop_base,
8600 ASCV_MSGOUT_BEG,
8601 (uchar *)&ext_msg,
8602 sizeof(EXT_MSG) >> 1);
8603 q_cntl |= QC_MSG_OUT;
8604 AscWriteLramByte(iop_base,
8605 (ushort)(halt_q_addr +
8606 (ushort)ASC_SCSIQ_B_CNTL),
8607 q_cntl);
8608 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8609 return (0);
8610 }
8611 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
8612
8613 q_cntl |= QC_REQ_SENSE;
8614
8615 if ((asc_dvc->init_sdtr & target_id) != 0) {
8616
8617 asc_dvc->sdtr_done &= ~target_id;
8618
8619 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8620 q_cntl |= QC_MSG_OUT;
8621 AscMsgOutSDTR(asc_dvc,
8622 asc_dvc->
8623 sdtr_period_tbl[(sdtr_data >> 4) &
8624 (uchar)(asc_dvc->
8625 max_sdtr_index -
8626 1)],
8627 (uchar)(sdtr_data & (uchar)
8628 ASC_SYN_MAX_OFFSET));
8629 }
8630
8631 AscWriteLramByte(iop_base,
8632 (ushort)(halt_q_addr +
8633 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8634
8635 tag_code = AscReadLramByte(iop_base,
8636 (ushort)(halt_q_addr + (ushort)
8637 ASC_SCSIQ_B_TAG_CODE));
8638 tag_code &= 0xDC;
8639 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
8640 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
8641 ) {
8642
8643 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
8644 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
8645
8646 }
8647 AscWriteLramByte(iop_base,
8648 (ushort)(halt_q_addr +
8649 (ushort)ASC_SCSIQ_B_TAG_CODE),
8650 tag_code);
8651
8652 q_status = AscReadLramByte(iop_base,
8653 (ushort)(halt_q_addr + (ushort)
8654 ASC_SCSIQ_B_STATUS));
8655 q_status |= (QS_READY | QS_BUSY);
8656 AscWriteLramByte(iop_base,
8657 (ushort)(halt_q_addr +
8658 (ushort)ASC_SCSIQ_B_STATUS),
8659 q_status);
8660
8661 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
8662 scsi_busy &= ~target_id;
8663 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8664
8665 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8666 return (0);
8667 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
8668
8669 AscMemWordCopyPtrFromLram(iop_base,
8670 ASCV_MSGOUT_BEG,
8671 (uchar *)&out_msg,
8672 sizeof(EXT_MSG) >> 1);
8673
8674 if ((out_msg.msg_type == MS_EXTEND) &&
8675 (out_msg.msg_len == MS_SDTR_LEN) &&
8676 (out_msg.msg_req == MS_SDTR_CODE)) {
8677
8678 asc_dvc->init_sdtr &= ~target_id;
8679 asc_dvc->sdtr_done &= ~target_id;
8680 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8681 boardp->sdtr_data[tid_no] = asyn_sdtr;
8682 }
8683 q_cntl &= ~QC_MSG_OUT;
8684 AscWriteLramByte(iop_base,
8685 (ushort)(halt_q_addr +
8686 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8687 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8688 return (0);
8689 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
8690
8691 scsi_status = AscReadLramByte(iop_base,
8692 (ushort)((ushort)halt_q_addr +
8693 (ushort)
8694 ASC_SCSIQ_SCSI_STATUS));
8695 cur_dvc_qng =
8696 AscReadLramByte(iop_base,
8697 (ushort)((ushort)ASC_QADR_BEG +
8698 (ushort)target_ix));
8699 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
8700
8701 scsi_busy = AscReadLramByte(iop_base,
8702 (ushort)ASCV_SCSIBUSY_B);
8703 scsi_busy |= target_id;
8704 AscWriteLramByte(iop_base,
8705 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8706 asc_dvc->queue_full_or_busy |= target_id;
8707
8708 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
8709 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
8710 cur_dvc_qng -= 1;
8711 asc_dvc->max_dvc_qng[tid_no] =
8712 cur_dvc_qng;
8713
8714 AscWriteLramByte(iop_base,
8715 (ushort)((ushort)
8716 ASCV_MAX_DVC_QNG_BEG
8717 + (ushort)
8718 tid_no),
8719 cur_dvc_qng);
8720
8721 /*
8722 * Set the device queue depth to the number of
8723 * active requests when the QUEUE FULL condition
8724 * was encountered.
8725 */
8726 boardp->queue_full |= target_id;
8727 boardp->queue_full_cnt[tid_no] =
8728 cur_dvc_qng;
8729 }
8730 }
8731 }
8732 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8733 return (0);
8734 }
1da177e4 8735#if CC_VERY_LONG_SG_LIST
27c868c2
MW
8736 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
8737 uchar q_no;
8738 ushort q_addr;
8739 uchar sg_wk_q_no;
8740 uchar first_sg_wk_q_no;
8741 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
8742 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
8743 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
8744 ushort sg_list_dwords;
8745 ushort sg_entry_cnt;
8746 uchar next_qp;
8747 int i;
8748
8749 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
8750 if (q_no == ASC_QLINK_END) {
8751 return (0);
8752 }
8753
8754 q_addr = ASC_QNO_TO_QADDR(q_no);
8755
8756 /*
8757 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
8758 * structure pointer using a macro provided by the driver.
8759 * The ASC_SCSI_REQ pointer provides a pointer to the
8760 * host ASC_SG_HEAD structure.
8761 */
8762 /* Read request's SRB pointer. */
8763 scsiq = (ASC_SCSI_Q *)
8764 ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
8765 (ushort)
8766 (q_addr +
8767 ASC_SCSIQ_D_SRBPTR))));
8768
8769 /*
8770 * Get request's first and working SG queue.
8771 */
8772 sg_wk_q_no = AscReadLramByte(iop_base,
8773 (ushort)(q_addr +
8774 ASC_SCSIQ_B_SG_WK_QP));
8775
8776 first_sg_wk_q_no = AscReadLramByte(iop_base,
8777 (ushort)(q_addr +
8778 ASC_SCSIQ_B_FIRST_SG_WK_QP));
8779
8780 /*
8781 * Reset request's working SG queue back to the
8782 * first SG queue.
8783 */
8784 AscWriteLramByte(iop_base,
8785 (ushort)(q_addr +
8786 (ushort)ASC_SCSIQ_B_SG_WK_QP),
8787 first_sg_wk_q_no);
8788
8789 sg_head = scsiq->sg_head;
8790
8791 /*
8792 * Set sg_entry_cnt to the number of SG elements
8793 * that will be completed on this interrupt.
8794 *
8795 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
8796 * SG elements. The data_cnt and data_addr fields which
8797 * add 1 to the SG element capacity are not used when
8798 * restarting SG handling after a halt.
8799 */
8800 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
8801 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
8802
8803 /*
8804 * Keep track of remaining number of SG elements that will
8805 * need to be handled on the next interrupt.
8806 */
8807 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
8808 } else {
8809 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
8810 scsiq->remain_sg_entry_cnt = 0;
8811 }
8812
8813 /*
8814 * Copy SG elements into the list of allocated SG queues.
8815 *
8816 * Last index completed is saved in scsiq->next_sg_index.
8817 */
8818 next_qp = first_sg_wk_q_no;
8819 q_addr = ASC_QNO_TO_QADDR(next_qp);
8820 scsi_sg_q.sg_head_qp = q_no;
8821 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
8822 for (i = 0; i < sg_head->queue_cnt; i++) {
8823 scsi_sg_q.seq_no = i + 1;
8824 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
8825 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
8826 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
8827 /*
8828 * After very first SG queue RISC FW uses next
8829 * SG queue first element then checks sg_list_cnt
8830 * against zero and then decrements, so set
8831 * sg_list_cnt 1 less than number of SG elements
8832 * in each SG queue.
8833 */
8834 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
8835 scsi_sg_q.sg_cur_list_cnt =
8836 ASC_SG_LIST_PER_Q - 1;
8837 } else {
8838 /*
8839 * This is the last SG queue in the list of
8840 * allocated SG queues. If there are more
8841 * SG elements than will fit in the allocated
8842 * queues, then set the QCSG_SG_XFER_MORE flag.
8843 */
8844 if (scsiq->remain_sg_entry_cnt != 0) {
8845 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
8846 } else {
8847 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
8848 }
8849 /* equals sg_entry_cnt * 2 */
8850 sg_list_dwords = sg_entry_cnt << 1;
8851 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
8852 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
8853 sg_entry_cnt = 0;
8854 }
8855
8856 scsi_sg_q.q_no = next_qp;
8857 AscMemWordCopyPtrToLram(iop_base,
8858 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
8859 (uchar *)&scsi_sg_q,
8860 sizeof(ASC_SG_LIST_Q) >> 1);
8861
8862 AscMemDWordCopyPtrToLram(iop_base,
8863 q_addr + ASC_SGQ_LIST_BEG,
8864 (uchar *)&sg_head->
8865 sg_list[scsiq->next_sg_index],
8866 sg_list_dwords);
8867
8868 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
8869
8870 /*
8871 * If the just completed SG queue contained the
8872 * last SG element, then no more SG queues need
8873 * to be written.
8874 */
8875 if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
8876 break;
8877 }
8878
8879 next_qp = AscReadLramByte(iop_base,
8880 (ushort)(q_addr +
8881 ASC_SCSIQ_B_FWD));
8882 q_addr = ASC_QNO_TO_QADDR(next_qp);
8883 }
8884
8885 /*
8886 * Clear the halt condition so the RISC will be restarted
8887 * after the return.
8888 */
8889 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8890 return (0);
8891 }
1da177e4 8892#endif /* CC_VERY_LONG_SG_LIST */
27c868c2 8893 return (0);
1da177e4
LT
8894}
8895
27c868c2
MW
8896static uchar
8897_AscCopyLramScsiDoneQ(PortAddr iop_base,
8898 ushort q_addr,
8899 ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
1da177e4 8900{
27c868c2
MW
8901 ushort _val;
8902 uchar sg_queue_cnt;
8903
8904 DvcGetQinfo(iop_base,
8905 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
8906 (uchar *)scsiq,
8907 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
8908
8909 _val = AscReadLramWord(iop_base,
8910 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
8911 scsiq->q_status = (uchar)_val;
8912 scsiq->q_no = (uchar)(_val >> 8);
8913 _val = AscReadLramWord(iop_base,
8914 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8915 scsiq->cntl = (uchar)_val;
8916 sg_queue_cnt = (uchar)(_val >> 8);
8917 _val = AscReadLramWord(iop_base,
8918 (ushort)(q_addr +
8919 (ushort)ASC_SCSIQ_B_SENSE_LEN));
8920 scsiq->sense_len = (uchar)_val;
8921 scsiq->extra_bytes = (uchar)(_val >> 8);
8922
8923 /*
8924 * Read high word of remain bytes from alternate location.
8925 */
8926 scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
8927 (ushort)(q_addr +
8928 (ushort)
8929 ASC_SCSIQ_W_ALT_DC1)))
8930 << 16);
8931 /*
8932 * Read low word of remain bytes from original location.
8933 */
8934 scsiq->remain_bytes += AscReadLramWord(iop_base,
8935 (ushort)(q_addr + (ushort)
8936 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
8937
8938 scsiq->remain_bytes &= max_dma_count;
8939 return (sg_queue_cnt);
1da177e4
LT
8940}
8941
27c868c2 8942static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
1da177e4 8943{
27c868c2
MW
8944 uchar next_qp;
8945 uchar n_q_used;
8946 uchar sg_list_qp;
8947 uchar sg_queue_cnt;
8948 uchar q_cnt;
8949 uchar done_q_tail;
8950 uchar tid_no;
8951 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8952 ASC_SCSI_BIT_ID_TYPE target_id;
8953 PortAddr iop_base;
8954 ushort q_addr;
8955 ushort sg_q_addr;
8956 uchar cur_target_qng;
8957 ASC_QDONE_INFO scsiq_buf;
8958 ASC_QDONE_INFO *scsiq;
8959 int false_overrun;
8960 ASC_ISR_CALLBACK asc_isr_callback;
8961
8962 iop_base = asc_dvc->iop_base;
8963 asc_isr_callback = asc_dvc->isr_callback;
8964 n_q_used = 1;
8965 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
8966 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
8967 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
8968 next_qp = AscReadLramByte(iop_base,
8969 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
8970 if (next_qp != ASC_QLINK_END) {
8971 AscPutVarDoneQTail(iop_base, next_qp);
8972 q_addr = ASC_QNO_TO_QADDR(next_qp);
8973 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
8974 asc_dvc->max_dma_count);
8975 AscWriteLramByte(iop_base,
8976 (ushort)(q_addr +
8977 (ushort)ASC_SCSIQ_B_STATUS),
8978 (uchar)(scsiq->
8979 q_status & (uchar)~(QS_READY |
8980 QS_ABORTED)));
8981 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
8982 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
8983 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
8984 sg_q_addr = q_addr;
8985 sg_list_qp = next_qp;
8986 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
8987 sg_list_qp = AscReadLramByte(iop_base,
8988 (ushort)(sg_q_addr
8989 + (ushort)
8990 ASC_SCSIQ_B_FWD));
8991 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
8992 if (sg_list_qp == ASC_QLINK_END) {
8993 AscSetLibErrorCode(asc_dvc,
8994 ASCQ_ERR_SG_Q_LINKS);
8995 scsiq->d3.done_stat = QD_WITH_ERROR;
8996 scsiq->d3.host_stat =
8997 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
8998 goto FATAL_ERR_QDONE;
8999 }
9000 AscWriteLramByte(iop_base,
9001 (ushort)(sg_q_addr + (ushort)
9002 ASC_SCSIQ_B_STATUS),
9003 QS_FREE);
9004 }
9005 n_q_used = sg_queue_cnt + 1;
9006 AscPutVarDoneQTail(iop_base, sg_list_qp);
9007 }
9008 if (asc_dvc->queue_full_or_busy & target_id) {
9009 cur_target_qng = AscReadLramByte(iop_base,
9010 (ushort)((ushort)
9011 ASC_QADR_BEG
9012 + (ushort)
9013 scsiq->d2.
9014 target_ix));
9015 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
9016 scsi_busy = AscReadLramByte(iop_base, (ushort)
9017 ASCV_SCSIBUSY_B);
9018 scsi_busy &= ~target_id;
9019 AscWriteLramByte(iop_base,
9020 (ushort)ASCV_SCSIBUSY_B,
9021 scsi_busy);
9022 asc_dvc->queue_full_or_busy &= ~target_id;
9023 }
9024 }
9025 if (asc_dvc->cur_total_qng >= n_q_used) {
9026 asc_dvc->cur_total_qng -= n_q_used;
9027 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
9028 asc_dvc->cur_dvc_qng[tid_no]--;
9029 }
9030 } else {
9031 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
9032 scsiq->d3.done_stat = QD_WITH_ERROR;
9033 goto FATAL_ERR_QDONE;
9034 }
9035 if ((scsiq->d2.srb_ptr == 0UL) ||
9036 ((scsiq->q_status & QS_ABORTED) != 0)) {
9037 return (0x11);
9038 } else if (scsiq->q_status == QS_DONE) {
9039 false_overrun = FALSE;
9040 if (scsiq->extra_bytes != 0) {
9041 scsiq->remain_bytes +=
9042 (ADV_DCNT)scsiq->extra_bytes;
9043 }
9044 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
9045 if (scsiq->d3.host_stat ==
9046 QHSTA_M_DATA_OVER_RUN) {
9047 if ((scsiq->
9048 cntl & (QC_DATA_IN | QC_DATA_OUT))
9049 == 0) {
9050 scsiq->d3.done_stat =
9051 QD_NO_ERROR;
9052 scsiq->d3.host_stat =
9053 QHSTA_NO_ERROR;
9054 } else if (false_overrun) {
9055 scsiq->d3.done_stat =
9056 QD_NO_ERROR;
9057 scsiq->d3.host_stat =
9058 QHSTA_NO_ERROR;
9059 }
9060 } else if (scsiq->d3.host_stat ==
9061 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
9062 AscStopChip(iop_base);
9063 AscSetChipControl(iop_base,
9064 (uchar)(CC_SCSI_RESET
9065 | CC_HALT));
9066 DvcDelayNanoSecond(asc_dvc, 60000);
9067 AscSetChipControl(iop_base, CC_HALT);
9068 AscSetChipStatus(iop_base,
9069 CIW_CLR_SCSI_RESET_INT);
9070 AscSetChipStatus(iop_base, 0);
9071 AscSetChipControl(iop_base, 0);
9072 }
9073 }
9074 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9075 (*asc_isr_callback) (asc_dvc, scsiq);
9076 } else {
9077 if ((AscReadLramByte(iop_base,
9078 (ushort)(q_addr + (ushort)
9079 ASC_SCSIQ_CDB_BEG))
9080 == START_STOP)) {
9081 asc_dvc->unit_not_ready &= ~target_id;
9082 if (scsiq->d3.done_stat != QD_NO_ERROR) {
9083 asc_dvc->start_motor &=
9084 ~target_id;
9085 }
9086 }
9087 }
9088 return (1);
9089 } else {
9090 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
9091 FATAL_ERR_QDONE:
9092 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9093 (*asc_isr_callback) (asc_dvc, scsiq);
9094 }
9095 return (0x80);
9096 }
9097 }
9098 return (0);
1da177e4
LT
9099}
9100
27c868c2 9101static int AscISR(ASC_DVC_VAR *asc_dvc)
1da177e4 9102{
27c868c2
MW
9103 ASC_CS_TYPE chipstat;
9104 PortAddr iop_base;
9105 ushort saved_ram_addr;
9106 uchar ctrl_reg;
9107 uchar saved_ctrl_reg;
9108 int int_pending;
9109 int status;
9110 uchar host_flag;
9111
9112 iop_base = asc_dvc->iop_base;
9113 int_pending = FALSE;
9114
9115 if (AscIsIntPending(iop_base) == 0) {
9116 return int_pending;
9117 }
1da177e4 9118
27c868c2
MW
9119 if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
9120 || (asc_dvc->isr_callback == 0)
9121 ) {
9122 return (ERR);
9123 }
9124 if (asc_dvc->in_critical_cnt != 0) {
9125 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
9126 return (ERR);
9127 }
9128 if (asc_dvc->is_in_int) {
9129 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
9130 return (ERR);
9131 }
9132 asc_dvc->is_in_int = TRUE;
9133 ctrl_reg = AscGetChipControl(iop_base);
9134 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
9135 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
9136 chipstat = AscGetChipStatus(iop_base);
9137 if (chipstat & CSW_SCSI_RESET_LATCH) {
9138 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
9139 int i = 10;
9140 int_pending = TRUE;
9141 asc_dvc->sdtr_done = 0;
9142 saved_ctrl_reg &= (uchar)(~CC_HALT);
9143 while ((AscGetChipStatus(iop_base) &
9144 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
9145 DvcSleepMilliSecond(100);
9146 }
9147 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
9148 AscSetChipControl(iop_base, CC_HALT);
9149 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
9150 AscSetChipStatus(iop_base, 0);
9151 chipstat = AscGetChipStatus(iop_base);
9152 }
9153 }
9154 saved_ram_addr = AscGetChipLramAddr(iop_base);
9155 host_flag = AscReadLramByte(iop_base,
9156 ASCV_HOST_FLAG_B) &
9157 (uchar)(~ASC_HOST_FLAG_IN_ISR);
9158 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
9159 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
9160 if ((chipstat & CSW_INT_PENDING)
9161 || (int_pending)
9162 ) {
9163 AscAckInterrupt(iop_base);
9164 int_pending = TRUE;
9165 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
9166 if (AscIsrChipHalted(asc_dvc) == ERR) {
9167 goto ISR_REPORT_QDONE_FATAL_ERROR;
9168 } else {
9169 saved_ctrl_reg &= (uchar)(~CC_HALT);
9170 }
9171 } else {
9172 ISR_REPORT_QDONE_FATAL_ERROR:
9173 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
9174 while (((status =
9175 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
9176 }
9177 } else {
9178 do {
9179 if ((status =
9180 AscIsrQDone(asc_dvc)) == 1) {
9181 break;
9182 }
9183 } while (status == 0x11);
9184 }
9185 if ((status & 0x80) != 0)
9186 int_pending = ERR;
9187 }
9188 }
9189 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
9190 AscSetChipLramAddr(iop_base, saved_ram_addr);
9191 AscSetChipControl(iop_base, saved_ctrl_reg);
9192 asc_dvc->is_in_int = FALSE;
9193 return (int_pending);
1da177e4
LT
9194}
9195
9196/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
9197static uchar _asc_mcode_buf[] = {
9198 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9199 0x00, 0x00, 0x00, 0x00,
9200 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00,
9201 0x00, 0x00, 0x00, 0x00,
9202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9203 0x00, 0x00, 0x00, 0x00,
9204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9205 0x00, 0x00, 0x00, 0x00,
9206 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00,
9207 0x00, 0xFF, 0x00, 0x00,
9208 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00,
9209 0x00, 0x00, 0x00, 0x00,
9210 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
9211 0x00, 0x00, 0x00, 0x00,
9212 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88,
9213 0x00, 0x00, 0x00, 0x00,
9214 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73,
9215 0x03, 0x23, 0x36, 0x40,
9216 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
9217 0xC2, 0x00, 0x92, 0x80,
9218 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60,
9219 0xB6, 0x00, 0x92, 0x80,
9220 0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00,
9221 0x92, 0x80, 0x80, 0x62,
9222 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
9223 0xCD, 0x04, 0x4D, 0x00,
9224 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01,
9225 0xE6, 0x84, 0xD2, 0xC1,
9226 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97,
9227 0xC6, 0x81, 0xC2, 0x88,
9228 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
9229 0x84, 0x97, 0x07, 0xA6,
9230 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE,
9231 0xC2, 0x88, 0xCE, 0x00,
9232 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01,
9233 0x80, 0x63, 0x07, 0xA6,
9234 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
9235 0x34, 0x01, 0x00, 0x33,
9236 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23,
9237 0x68, 0x98, 0x4D, 0x04,
9238 0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23,
9239 0xF8, 0x88, 0xFB, 0x23,
9240 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
9241 0x00, 0x33, 0x0A, 0x00,
9242 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00,
9243 0xC2, 0x88, 0xCD, 0x04,
9244 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81,
9245 0x06, 0xAB, 0x82, 0x01,
9246 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
9247 0x3C, 0x01, 0x00, 0x05,
9248 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01,
9249 0x15, 0x23, 0xA1, 0x01,
9250 0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00,
9251 0x06, 0x61, 0x00, 0xA0,
9252 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
9253 0xC2, 0x88, 0x06, 0x23,
9254 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01,
9255 0x57, 0x60, 0x00, 0xA0,
9256 0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73,
9257 0x4B, 0x00, 0x06, 0x61,
9258 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
9259 0x4F, 0x00, 0x84, 0x97,
9260 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97,
9261 0x48, 0x04, 0x84, 0x80,
9262 0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00,
9263 0x81, 0x73, 0x06, 0x29,
9264 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
9265 0x04, 0x98, 0xF0, 0x80,
9266 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6,
9267 0x34, 0x02, 0x03, 0xA6,
9268 0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96,
9269 0x46, 0x82, 0xFE, 0x95,
9270 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
9271 0x07, 0xA6, 0x5A, 0x02,
9272 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95,
9273 0x48, 0x82, 0x60, 0x96,
9274 0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84,
9275 0x04, 0x01, 0x0C, 0xDC,
9276 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
9277 0x6F, 0x00, 0xA5, 0x01,
9278 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01,
9279 0x02, 0xA6, 0xAA, 0x02,
9280 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04,
9281 0x01, 0xA6, 0xB4, 0x02,
9282 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
9283 0x80, 0x63, 0x00, 0x43,
9284 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23,
9285 0x04, 0x61, 0x84, 0x01,
9286 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F,
9287 0x00, 0x00, 0xEA, 0x82,
9288 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
9289 0x00, 0x33, 0x1F, 0x00,
9290 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98,
9291 0xB6, 0x2D, 0x01, 0xA6,
9292 0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6,
9293 0x10, 0x03, 0x03, 0xA6,
9294 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
9295 0x7C, 0x95, 0xEE, 0x82,
9296 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4,
9297 0x04, 0x01, 0x2D, 0xC8,
9298 0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01,
9299 0x05, 0x05, 0x86, 0x98,
9300 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
9301 0x3C, 0x04, 0x06, 0xA6,
9302 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88,
9303 0x7C, 0x95, 0x32, 0x83,
9304 0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05,
9305 0xEB, 0x04, 0x00, 0x33,
9306 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
9307 0xFF, 0xA2, 0x7A, 0x03,
9308 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01,
9309 0x00, 0xA2, 0x9A, 0x03,
9310 0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00,
9311 0x01, 0xA6, 0x96, 0x03,
9312 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
9313 0xA4, 0x03, 0x00, 0xA6,
9314 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03,
9315 0x07, 0xA6, 0xB2, 0x03,
9316 0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88,
9317 0xA8, 0x98, 0x80, 0x42,
9318 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
9319 0xC0, 0x83, 0x00, 0x33,
9320 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23,
9321 0xA0, 0x01, 0x12, 0x23,
9322 0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B,
9323 0x80, 0x67, 0x05, 0x23,
9324 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
9325 0x06, 0xA6, 0x0A, 0x04,
9326 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96,
9327 0xF4, 0x83, 0x20, 0x84,
9328 0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
9329 0x83, 0x03, 0x80, 0x63,
9330 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
9331 0x38, 0x04, 0x00, 0x33,
9332 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84,
9333 0x1D, 0x01, 0x06, 0xCC,
9334 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62,
9335 0xA2, 0x0D, 0x80, 0x63,
9336 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
9337 0x80, 0x63, 0xA3, 0x01,
9338 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0,
9339 0x76, 0x04, 0xE0, 0x00,
9340 0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00,
9341 0x00, 0x33, 0x1E, 0x00,
9342 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
9343 0x08, 0x23, 0x22, 0xA3,
9344 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3,
9345 0xC4, 0x04, 0x42, 0x23,
9346 0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23,
9347 0xF8, 0x88, 0x04, 0x98,
9348 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
9349 0x81, 0x62, 0xE8, 0x81,
9350 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98,
9351 0x00, 0x33, 0x00, 0x81,
9352 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23,
9353 0xF8, 0x88, 0x04, 0x23,
9354 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
9355 0xF4, 0x04, 0x00, 0x33,
9356 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01,
9357 0x04, 0x23, 0xA0, 0x01,
9358 0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00,
9359 0x00, 0xA3, 0x22, 0x05,
9360 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
9361 0x46, 0x97, 0xCD, 0x04,
9362 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23,
9363 0x82, 0x01, 0x34, 0x85,
9364 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05,
9365 0x1D, 0x01, 0x04, 0xD6,
9366 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
9367 0x49, 0x00, 0x81, 0x01,
9368 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01,
9369 0x49, 0x04, 0x80, 0x01,
9370 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04,
9371 0x01, 0x23, 0xEA, 0x00,
9372 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
9373 0x07, 0xA4, 0xF8, 0x05,
9374 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00,
9375 0xC2, 0x88, 0x04, 0xA0,
9376 0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61,
9377 0x00, 0xA2, 0xA4, 0x05,
9378 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
9379 0x62, 0x97, 0x04, 0x85,
9380 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05,
9381 0xF4, 0x85, 0x03, 0xA0,
9382 0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63,
9383 0xCC, 0x86, 0x07, 0xA0,
9384 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
9385 0x80, 0x67, 0x80, 0x63,
9386 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23,
9387 0xF8, 0x88, 0x07, 0x23,
9388 0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00,
9389 0x00, 0x63, 0x4A, 0x00,
9390 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
9391 0x07, 0x41, 0x83, 0x03,
9392 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88,
9393 0x1D, 0x01, 0x01, 0xD6,
9394 0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00,
9395 0x07, 0xA6, 0x7C, 0x05,
9396 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
9397 0x52, 0x00, 0x06, 0x61,
9398 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41,
9399 0x00, 0x63, 0x1D, 0x01,
9400 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23,
9401 0x07, 0x41, 0x00, 0x63,
9402 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
9403 0xDF, 0x00, 0x06, 0xA6,
9404 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33,
9405 0x00, 0x40, 0xC0, 0x20,
9406 0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63,
9407 0x06, 0xA6, 0x94, 0x06,
9408 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
9409 0x40, 0x0E, 0x80, 0x63,
9410 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E,
9411 0x80, 0x63, 0x00, 0x43,
9412 0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05,
9413 0x80, 0x67, 0x40, 0x0E,
9414 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
9415 0x07, 0xA6, 0xD6, 0x06,
9416 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00,
9417 0x0A, 0x2B, 0x07, 0xA6,
9418 0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2,
9419 0xF4, 0x06, 0xC0, 0x0E,
9420 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
9421 0x81, 0x62, 0x04, 0x01,
9422 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6,
9423 0x8C, 0x06, 0x00, 0x33,
9424 0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03,
9425 0x80, 0x63, 0x06, 0xA6,
9426 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
9427 0x00, 0x00, 0x80, 0x67,
9428 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05,
9429 0xBF, 0x23, 0x04, 0x61,
9430 0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00,
9431 0x00, 0x01, 0xF2, 0x00,
9432 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
9433 0x80, 0x05, 0x81, 0x05,
9434 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00,
9435 0x70, 0x00, 0x81, 0x01,
9436 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04,
9437 0x70, 0x00, 0x80, 0x01,
9438 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
9439 0xF1, 0x00, 0x70, 0x00,
9440 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01,
9441 0x71, 0x04, 0x70, 0x00,
9442 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05,
9443 0xA3, 0x01, 0xA2, 0x01,
9444 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
9445 0xC4, 0x07, 0x00, 0x33,
9446 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8,
9447 0x48, 0x00, 0xB0, 0x01,
9448 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43,
9449 0x00, 0xA2, 0xE4, 0x07,
9450 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
9451 0x05, 0x05, 0x00, 0x63,
9452 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43,
9453 0x76, 0x08, 0x80, 0x02,
9454 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
9455 0x00, 0x02, 0x00, 0xA0,
9456 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
9457 0x00, 0x63, 0xF3, 0x04,
9458 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40,
9459 0x00, 0xA2, 0x44, 0x08,
9460 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1,
9461 0x24, 0x08, 0x04, 0x98,
9462 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
9463 0x5A, 0x88, 0x02, 0x01,
9464 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00,
9465 0x00, 0xA3, 0x64, 0x08,
9466 0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63,
9467 0x06, 0xA6, 0x76, 0x08,
9468 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
9469 0x00, 0x63, 0x38, 0x2B,
9470 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98,
9471 0x05, 0x05, 0xB2, 0x09,
9472 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63,
9473 0x80, 0x32, 0x80, 0x36,
9474 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
9475 0x40, 0x36, 0x40, 0x3A,
9476 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08,
9477 0x5D, 0x00, 0xFE, 0xC3,
9478 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73,
9479 0xFF, 0xFD, 0x80, 0x73,
9480 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
9481 0xA1, 0x23, 0xA1, 0x01,
9482 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2,
9483 0x80, 0x00, 0x03, 0xC2,
9484 0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23,
9485 0xA0, 0x01, 0xE6, 0x84,
1da177e4
LT
9486};
9487
27c868c2
MW
9488static ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
9489static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
1da177e4
LT
9490
9491#define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
27c868c2
MW
9492static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
9493 INQUIRY,
9494 REQUEST_SENSE,
9495 READ_CAPACITY,
9496 READ_TOC,
9497 MODE_SELECT,
9498 MODE_SENSE,
9499 MODE_SELECT_10,
9500 MODE_SENSE_10,
9501 0xFF,
9502 0xFF,
9503 0xFF,
9504 0xFF,
9505 0xFF,
9506 0xFF,
9507 0xFF,
9508 0xFF
1da177e4
LT
9509};
9510
27c868c2 9511static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
1da177e4 9512{
27c868c2
MW
9513 PortAddr iop_base;
9514 ulong last_int_level;
9515 int sta;
9516 int n_q_required;
9517 int disable_syn_offset_one_fix;
9518 int i;
9519 ASC_PADDR addr;
9520 ASC_EXE_CALLBACK asc_exe_callback;
9521 ushort sg_entry_cnt = 0;
9522 ushort sg_entry_cnt_minus_one = 0;
9523 uchar target_ix;
9524 uchar tid_no;
9525 uchar sdtr_data;
9526 uchar extra_bytes;
9527 uchar scsi_cmd;
9528 uchar disable_cmd;
9529 ASC_SG_HEAD *sg_head;
9530 ASC_DCNT data_cnt;
9531
9532 iop_base = asc_dvc->iop_base;
9533 sg_head = scsiq->sg_head;
9534 asc_exe_callback = asc_dvc->exe_callback;
9535 if (asc_dvc->err_code != 0)
9536 return (ERR);
9537 if (scsiq == (ASC_SCSI_Q *)0L) {
9538 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
9539 return (ERR);
9540 }
9541 scsiq->q1.q_no = 0;
9542 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
9543 scsiq->q1.extra_bytes = 0;
9544 }
9545 sta = 0;
9546 target_ix = scsiq->q2.target_ix;
9547 tid_no = ASC_TIX_TO_TID(target_ix);
9548 n_q_required = 1;
9549 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
9550 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
9551 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
9552 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9553 AscMsgOutSDTR(asc_dvc,
9554 asc_dvc->
9555 sdtr_period_tbl[(sdtr_data >> 4) &
9556 (uchar)(asc_dvc->
9557 max_sdtr_index -
9558 1)],
9559 (uchar)(sdtr_data & (uchar)
9560 ASC_SYN_MAX_OFFSET));
9561 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
9562 }
9563 }
9564 last_int_level = DvcEnterCritical();
9565 if (asc_dvc->in_critical_cnt != 0) {
9566 DvcLeaveCritical(last_int_level);
9567 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
9568 return (ERR);
9569 }
9570 asc_dvc->in_critical_cnt++;
9571 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9572 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
9573 asc_dvc->in_critical_cnt--;
9574 DvcLeaveCritical(last_int_level);
9575 return (ERR);
9576 }
1da177e4 9577#if !CC_VERY_LONG_SG_LIST
27c868c2
MW
9578 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9579 asc_dvc->in_critical_cnt--;
9580 DvcLeaveCritical(last_int_level);
9581 return (ERR);
9582 }
1da177e4 9583#endif /* !CC_VERY_LONG_SG_LIST */
27c868c2
MW
9584 if (sg_entry_cnt == 1) {
9585 scsiq->q1.data_addr =
9586 (ADV_PADDR)sg_head->sg_list[0].addr;
9587 scsiq->q1.data_cnt =
9588 (ADV_DCNT)sg_head->sg_list[0].bytes;
9589 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
9590 }
9591 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
9592 }
9593 scsi_cmd = scsiq->cdbptr[0];
9594 disable_syn_offset_one_fix = FALSE;
9595 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
9596 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
9597 if (scsiq->q1.cntl & QC_SG_HEAD) {
9598 data_cnt = 0;
9599 for (i = 0; i < sg_entry_cnt; i++) {
9600 data_cnt +=
9601 (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
9602 bytes);
9603 }
9604 } else {
9605 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
9606 }
9607 if (data_cnt != 0UL) {
9608 if (data_cnt < 512UL) {
9609 disable_syn_offset_one_fix = TRUE;
9610 } else {
9611 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
9612 i++) {
9613 disable_cmd =
9614 _syn_offset_one_disable_cmd[i];
9615 if (disable_cmd == 0xFF) {
9616 break;
9617 }
9618 if (scsi_cmd == disable_cmd) {
9619 disable_syn_offset_one_fix =
9620 TRUE;
9621 break;
9622 }
9623 }
9624 }
9625 }
9626 }
9627 if (disable_syn_offset_one_fix) {
9628 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9629 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
9630 ASC_TAG_FLAG_DISABLE_DISCONNECT);
9631 } else {
9632 scsiq->q2.tag_code &= 0x27;
9633 }
9634 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9635 if (asc_dvc->bug_fix_cntl) {
9636 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9637 if ((scsi_cmd == READ_6) ||
9638 (scsi_cmd == READ_10)) {
9639 addr =
9640 (ADV_PADDR)le32_to_cpu(sg_head->
9641 sg_list
9642 [sg_entry_cnt_minus_one].
9643 addr) +
9644 (ADV_DCNT)le32_to_cpu(sg_head->
9645 sg_list
9646 [sg_entry_cnt_minus_one].
9647 bytes);
9648 extra_bytes =
9649 (uchar)((ushort)addr & 0x0003);
9650 if ((extra_bytes != 0)
9651 &&
9652 ((scsiq->q2.
9653 tag_code &
9654 ASC_TAG_FLAG_EXTRA_BYTES)
9655 == 0)) {
9656 scsiq->q2.tag_code |=
9657 ASC_TAG_FLAG_EXTRA_BYTES;
9658 scsiq->q1.extra_bytes =
9659 extra_bytes;
9660 data_cnt =
9661 le32_to_cpu(sg_head->
9662 sg_list
9663 [sg_entry_cnt_minus_one].
9664 bytes);
9665 data_cnt -=
9666 (ASC_DCNT) extra_bytes;
9667 sg_head->
9668 sg_list
9669 [sg_entry_cnt_minus_one].
9670 bytes =
9671 cpu_to_le32(data_cnt);
9672 }
9673 }
9674 }
9675 }
9676 sg_head->entry_to_copy = sg_head->entry_cnt;
1da177e4 9677#if CC_VERY_LONG_SG_LIST
27c868c2
MW
9678 /*
9679 * Set the sg_entry_cnt to the maximum possible. The rest of
9680 * the SG elements will be copied when the RISC completes the
9681 * SG elements that fit and halts.
9682 */
9683 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9684 sg_entry_cnt = ASC_MAX_SG_LIST;
9685 }
1da177e4 9686#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
9687 n_q_required = AscSgListToQueue(sg_entry_cnt);
9688 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
9689 (uint) n_q_required)
9690 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9691 if ((sta =
9692 AscSendScsiQueue(asc_dvc, scsiq,
9693 n_q_required)) == 1) {
9694 asc_dvc->in_critical_cnt--;
9695 if (asc_exe_callback != 0) {
9696 (*asc_exe_callback) (asc_dvc, scsiq);
9697 }
9698 DvcLeaveCritical(last_int_level);
9699 return (sta);
9700 }
9701 }
9702 } else {
9703 if (asc_dvc->bug_fix_cntl) {
9704 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9705 if ((scsi_cmd == READ_6) ||
9706 (scsi_cmd == READ_10)) {
9707 addr =
9708 le32_to_cpu(scsiq->q1.data_addr) +
9709 le32_to_cpu(scsiq->q1.data_cnt);
9710 extra_bytes =
9711 (uchar)((ushort)addr & 0x0003);
9712 if ((extra_bytes != 0)
9713 &&
9714 ((scsiq->q2.
9715 tag_code &
9716 ASC_TAG_FLAG_EXTRA_BYTES)
9717 == 0)) {
9718 data_cnt =
9719 le32_to_cpu(scsiq->q1.
9720 data_cnt);
9721 if (((ushort)data_cnt & 0x01FF)
9722 == 0) {
9723 scsiq->q2.tag_code |=
9724 ASC_TAG_FLAG_EXTRA_BYTES;
9725 data_cnt -= (ASC_DCNT)
9726 extra_bytes;
9727 scsiq->q1.data_cnt =
9728 cpu_to_le32
9729 (data_cnt);
9730 scsiq->q1.extra_bytes =
9731 extra_bytes;
9732 }
9733 }
9734 }
9735 }
9736 }
9737 n_q_required = 1;
9738 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
9739 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9740 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
9741 n_q_required)) == 1) {
9742 asc_dvc->in_critical_cnt--;
9743 if (asc_exe_callback != 0) {
9744 (*asc_exe_callback) (asc_dvc, scsiq);
9745 }
9746 DvcLeaveCritical(last_int_level);
9747 return (sta);
9748 }
9749 }
9750 }
9751 asc_dvc->in_critical_cnt--;
9752 DvcLeaveCritical(last_int_level);
9753 return (sta);
1da177e4
LT
9754}
9755
27c868c2
MW
9756static int
9757AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
1da177e4 9758{
27c868c2
MW
9759 PortAddr iop_base;
9760 uchar free_q_head;
9761 uchar next_qp;
9762 uchar tid_no;
9763 uchar target_ix;
9764 int sta;
9765
9766 iop_base = asc_dvc->iop_base;
9767 target_ix = scsiq->q2.target_ix;
9768 tid_no = ASC_TIX_TO_TID(target_ix);
9769 sta = 0;
9770 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
9771 if (n_q_required > 1) {
9772 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
9773 free_q_head, (uchar)
9774 (n_q_required)))
9775 != (uchar)ASC_QLINK_END) {
9776 asc_dvc->last_q_shortage = 0;
9777 scsiq->sg_head->queue_cnt = n_q_required - 1;
9778 scsiq->q1.q_no = free_q_head;
9779 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
9780 free_q_head)) == 1) {
9781 AscPutVarFreeQHead(iop_base, next_qp);
9782 asc_dvc->cur_total_qng += (uchar)(n_q_required);
9783 asc_dvc->cur_dvc_qng[tid_no]++;
9784 }
9785 return (sta);
9786 }
9787 } else if (n_q_required == 1) {
9788 if ((next_qp = AscAllocFreeQueue(iop_base,
9789 free_q_head)) !=
9790 ASC_QLINK_END) {
9791 scsiq->q1.q_no = free_q_head;
9792 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
9793 free_q_head)) == 1) {
9794 AscPutVarFreeQHead(iop_base, next_qp);
9795 asc_dvc->cur_total_qng++;
9796 asc_dvc->cur_dvc_qng[tid_no]++;
9797 }
9798 return (sta);
9799 }
9800 }
9801 return (sta);
1da177e4
LT
9802}
9803
27c868c2 9804static int AscSgListToQueue(int sg_list)
1da177e4 9805{
27c868c2 9806 int n_sg_list_qs;
1da177e4 9807
27c868c2
MW
9808 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
9809 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
9810 n_sg_list_qs++;
9811 return (n_sg_list_qs + 1);
1da177e4
LT
9812}
9813
27c868c2
MW
9814static uint
9815AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
1da177e4 9816{
27c868c2
MW
9817 uint cur_used_qs;
9818 uint cur_free_qs;
9819 ASC_SCSI_BIT_ID_TYPE target_id;
9820 uchar tid_no;
9821
9822 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
9823 tid_no = ASC_TIX_TO_TID(target_ix);
9824 if ((asc_dvc->unit_not_ready & target_id) ||
9825 (asc_dvc->queue_full_or_busy & target_id)) {
9826 return (0);
9827 }
9828 if (n_qs == 1) {
9829 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9830 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
9831 } else {
9832 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9833 (uint) ASC_MIN_FREE_Q;
9834 }
9835 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
9836 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
9837 if (asc_dvc->cur_dvc_qng[tid_no] >=
9838 asc_dvc->max_dvc_qng[tid_no]) {
9839 return (0);
9840 }
9841 return (cur_free_qs);
9842 }
9843 if (n_qs > 1) {
9844 if ((n_qs > asc_dvc->last_q_shortage)
9845 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
9846 asc_dvc->last_q_shortage = n_qs;
9847 }
9848 }
9849 return (0);
1da177e4
LT
9850}
9851
27c868c2 9852static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
1da177e4 9853{
27c868c2
MW
9854 ushort q_addr;
9855 uchar tid_no;
9856 uchar sdtr_data;
9857 uchar syn_period_ix;
9858 uchar syn_offset;
9859 PortAddr iop_base;
9860
9861 iop_base = asc_dvc->iop_base;
9862 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
9863 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
9864 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
9865 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9866 syn_period_ix =
9867 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
9868 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
9869 AscMsgOutSDTR(asc_dvc,
9870 asc_dvc->sdtr_period_tbl[syn_period_ix],
9871 syn_offset);
9872 scsiq->q1.cntl |= QC_MSG_OUT;
9873 }
9874 q_addr = ASC_QNO_TO_QADDR(q_no);
9875 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
9876 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9877 }
9878 scsiq->q1.status = QS_FREE;
9879 AscMemWordCopyPtrToLram(iop_base,
9880 q_addr + ASC_SCSIQ_CDB_BEG,
9881 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
9882
9883 DvcPutScsiQ(iop_base,
9884 q_addr + ASC_SCSIQ_CPY_BEG,
9885 (uchar *)&scsiq->q1.cntl,
9886 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
9887 AscWriteLramWord(iop_base,
9888 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
9889 (ushort)(((ushort)scsiq->q1.
9890 q_no << 8) | (ushort)QS_READY));
9891 return (1);
1da177e4
LT
9892}
9893
27c868c2
MW
9894static int
9895AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
1da177e4 9896{
27c868c2
MW
9897 int sta;
9898 int i;
9899 ASC_SG_HEAD *sg_head;
9900 ASC_SG_LIST_Q scsi_sg_q;
9901 ASC_DCNT saved_data_addr;
9902 ASC_DCNT saved_data_cnt;
9903 PortAddr iop_base;
9904 ushort sg_list_dwords;
9905 ushort sg_index;
9906 ushort sg_entry_cnt;
9907 ushort q_addr;
9908 uchar next_qp;
9909
9910 iop_base = asc_dvc->iop_base;
9911 sg_head = scsiq->sg_head;
9912 saved_data_addr = scsiq->q1.data_addr;
9913 saved_data_cnt = scsiq->q1.data_cnt;
9914 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
9915 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
1da177e4 9916#if CC_VERY_LONG_SG_LIST
27c868c2
MW
9917 /*
9918 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
9919 * then not all SG elements will fit in the allocated queues.
9920 * The rest of the SG elements will be copied when the RISC
9921 * completes the SG elements that fit and halts.
9922 */
9923 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9924 /*
9925 * Set sg_entry_cnt to be the number of SG elements that
9926 * will fit in the allocated SG queues. It is minus 1, because
9927 * the first SG element is handled above. ASC_MAX_SG_LIST is
9928 * already inflated by 1 to account for this. For example it
9929 * may be 50 which is 1 + 7 queues * 7 SG elements.
9930 */
9931 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
9932
9933 /*
9934 * Keep track of remaining number of SG elements that will
9935 * need to be handled from a_isr.c.
9936 */
9937 scsiq->remain_sg_entry_cnt =
9938 sg_head->entry_cnt - ASC_MAX_SG_LIST;
9939 } else {
1da177e4 9940#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
9941 /*
9942 * Set sg_entry_cnt to be the number of SG elements that
9943 * will fit in the allocated SG queues. It is minus 1, because
9944 * the first SG element is handled above.
9945 */
9946 sg_entry_cnt = sg_head->entry_cnt - 1;
1da177e4 9947#if CC_VERY_LONG_SG_LIST
27c868c2 9948 }
1da177e4 9949#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
9950 if (sg_entry_cnt != 0) {
9951 scsiq->q1.cntl |= QC_SG_HEAD;
9952 q_addr = ASC_QNO_TO_QADDR(q_no);
9953 sg_index = 1;
9954 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
9955 scsi_sg_q.sg_head_qp = q_no;
9956 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
9957 for (i = 0; i < sg_head->queue_cnt; i++) {
9958 scsi_sg_q.seq_no = i + 1;
9959 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
9960 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
9961 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
9962 if (i == 0) {
9963 scsi_sg_q.sg_list_cnt =
9964 ASC_SG_LIST_PER_Q;
9965 scsi_sg_q.sg_cur_list_cnt =
9966 ASC_SG_LIST_PER_Q;
9967 } else {
9968 scsi_sg_q.sg_list_cnt =
9969 ASC_SG_LIST_PER_Q - 1;
9970 scsi_sg_q.sg_cur_list_cnt =
9971 ASC_SG_LIST_PER_Q - 1;
9972 }
9973 } else {
1da177e4 9974#if CC_VERY_LONG_SG_LIST
27c868c2
MW
9975 /*
9976 * This is the last SG queue in the list of
9977 * allocated SG queues. If there are more
9978 * SG elements than will fit in the allocated
9979 * queues, then set the QCSG_SG_XFER_MORE flag.
9980 */
9981 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9982 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
9983 } else {
1da177e4 9984#endif /* CC_VERY_LONG_SG_LIST */
27c868c2 9985 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
1da177e4 9986#if CC_VERY_LONG_SG_LIST
27c868c2 9987 }
1da177e4 9988#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
9989 sg_list_dwords = sg_entry_cnt << 1;
9990 if (i == 0) {
9991 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
9992 scsi_sg_q.sg_cur_list_cnt =
9993 sg_entry_cnt;
9994 } else {
9995 scsi_sg_q.sg_list_cnt =
9996 sg_entry_cnt - 1;
9997 scsi_sg_q.sg_cur_list_cnt =
9998 sg_entry_cnt - 1;
9999 }
10000 sg_entry_cnt = 0;
10001 }
10002 next_qp = AscReadLramByte(iop_base,
10003 (ushort)(q_addr +
10004 ASC_SCSIQ_B_FWD));
10005 scsi_sg_q.q_no = next_qp;
10006 q_addr = ASC_QNO_TO_QADDR(next_qp);
10007 AscMemWordCopyPtrToLram(iop_base,
10008 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
10009 (uchar *)&scsi_sg_q,
10010 sizeof(ASC_SG_LIST_Q) >> 1);
10011 AscMemDWordCopyPtrToLram(iop_base,
10012 q_addr + ASC_SGQ_LIST_BEG,
10013 (uchar *)&sg_head->
10014 sg_list[sg_index],
10015 sg_list_dwords);
10016 sg_index += ASC_SG_LIST_PER_Q;
10017 scsiq->next_sg_index = sg_index;
10018 }
10019 } else {
10020 scsiq->q1.cntl &= ~QC_SG_HEAD;
10021 }
10022 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
10023 scsiq->q1.data_addr = saved_data_addr;
10024 scsiq->q1.data_cnt = saved_data_cnt;
10025 return (sta);
1da177e4
LT
10026}
10027
27c868c2
MW
10028static int
10029AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
1da177e4 10030{
27c868c2 10031 int sta = FALSE;
1da177e4 10032
27c868c2
MW
10033 if (AscHostReqRiscHalt(iop_base)) {
10034 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
10035 AscStartChip(iop_base);
10036 return (sta);
10037 }
10038 return (sta);
1da177e4
LT
10039}
10040
27c868c2 10041static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
1da177e4 10042{
27c868c2
MW
10043 ASC_SCSI_BIT_ID_TYPE org_id;
10044 int i;
10045 int sta = TRUE;
10046
10047 AscSetBank(iop_base, 1);
10048 org_id = AscReadChipDvcID(iop_base);
10049 for (i = 0; i <= ASC_MAX_TID; i++) {
10050 if (org_id == (0x01 << i))
10051 break;
10052 }
10053 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
10054 AscWriteChipDvcID(iop_base, id);
10055 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
10056 AscSetBank(iop_base, 0);
10057 AscSetChipSyn(iop_base, sdtr_data);
10058 if (AscGetChipSyn(iop_base) != sdtr_data) {
10059 sta = FALSE;
10060 }
10061 } else {
10062 sta = FALSE;
10063 }
10064 AscSetBank(iop_base, 1);
10065 AscWriteChipDvcID(iop_base, org_id);
10066 AscSetBank(iop_base, 0);
10067 return (sta);
10068}
1da177e4 10069
27c868c2 10070static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
1da177e4 10071{
27c868c2
MW
10072 uchar i;
10073 ushort s_addr;
10074 PortAddr iop_base;
10075 ushort warn_code;
10076
10077 iop_base = asc_dvc->iop_base;
10078 warn_code = 0;
10079 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
10080 (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
10081 64) >> 1)
10082 );
10083 i = ASC_MIN_ACTIVE_QNO;
10084 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
10085 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
10086 (uchar)(i + 1));
10087 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
10088 (uchar)(asc_dvc->max_total_qng));
10089 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
10090 (uchar)i);
10091 i++;
10092 s_addr += ASC_QBLK_SIZE;
10093 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
10094 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
10095 (uchar)(i + 1));
10096 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
10097 (uchar)(i - 1));
10098 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
10099 (uchar)i);
10100 }
10101 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
10102 (uchar)ASC_QLINK_END);
10103 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
10104 (uchar)(asc_dvc->max_total_qng - 1));
10105 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
10106 (uchar)asc_dvc->max_total_qng);
10107 i++;
10108 s_addr += ASC_QBLK_SIZE;
10109 for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
10110 i++, s_addr += ASC_QBLK_SIZE) {
10111 AscWriteLramByte(iop_base,
10112 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
10113 AscWriteLramByte(iop_base,
10114 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
10115 AscWriteLramByte(iop_base,
10116 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
10117 }
10118 return (warn_code);
1da177e4
LT
10119}
10120
27c868c2 10121static ushort AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
1da177e4 10122{
27c868c2
MW
10123 PortAddr iop_base;
10124 int i;
10125 ushort lram_addr;
10126
10127 iop_base = asc_dvc->iop_base;
10128 AscPutRiscVarFreeQHead(iop_base, 1);
10129 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
10130 AscPutVarFreeQHead(iop_base, 1);
10131 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
10132 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
10133 (uchar)((int)asc_dvc->max_total_qng + 1));
10134 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
10135 (uchar)((int)asc_dvc->max_total_qng + 2));
10136 AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
10137 asc_dvc->max_total_qng);
10138 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
10139 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10140 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
10141 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
10142 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
10143 AscPutQDoneInProgress(iop_base, 0);
10144 lram_addr = ASC_QADR_BEG;
10145 for (i = 0; i < 32; i++, lram_addr += 2) {
10146 AscWriteLramWord(iop_base, lram_addr, 0);
10147 }
10148 return (0);
1da177e4
LT
10149}
10150
27c868c2 10151static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
1da177e4 10152{
27c868c2
MW
10153 if (asc_dvc->err_code == 0) {
10154 asc_dvc->err_code = err_code;
10155 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
10156 err_code);
10157 }
10158 return (err_code);
1da177e4
LT
10159}
10160
27c868c2
MW
10161static uchar
10162AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
1da177e4 10163{
27c868c2
MW
10164 EXT_MSG sdtr_buf;
10165 uchar sdtr_period_index;
10166 PortAddr iop_base;
10167
10168 iop_base = asc_dvc->iop_base;
10169 sdtr_buf.msg_type = MS_EXTEND;
10170 sdtr_buf.msg_len = MS_SDTR_LEN;
10171 sdtr_buf.msg_req = MS_SDTR_CODE;
10172 sdtr_buf.xfer_period = sdtr_period;
10173 sdtr_offset &= ASC_SYN_MAX_OFFSET;
10174 sdtr_buf.req_ack_offset = sdtr_offset;
10175 if ((sdtr_period_index =
10176 AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
10177 asc_dvc->max_sdtr_index) {
10178 AscMemWordCopyPtrToLram(iop_base,
10179 ASCV_MSGOUT_BEG,
10180 (uchar *)&sdtr_buf,
10181 sizeof(EXT_MSG) >> 1);
10182 return ((sdtr_period_index << 4) | sdtr_offset);
10183 } else {
10184
10185 sdtr_buf.req_ack_offset = 0;
10186 AscMemWordCopyPtrToLram(iop_base,
10187 ASCV_MSGOUT_BEG,
10188 (uchar *)&sdtr_buf,
10189 sizeof(EXT_MSG) >> 1);
10190 return (0);
10191 }
1da177e4
LT
10192}
10193
27c868c2
MW
10194static uchar
10195AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
1da177e4 10196{
27c868c2
MW
10197 uchar byte;
10198 uchar sdtr_period_ix;
10199
10200 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
10201 if ((sdtr_period_ix > asc_dvc->max_sdtr_index)
10202 ) {
10203 return (0xFF);
10204 }
10205 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
10206 return (byte);
1da177e4
LT
10207}
10208
27c868c2 10209static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
1da177e4 10210{
27c868c2
MW
10211 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
10212 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
10213 return;
1da177e4
LT
10214}
10215
27c868c2 10216static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
1da177e4 10217{
27c868c2
MW
10218 uchar *period_table;
10219 int max_index;
10220 int min_index;
10221 int i;
10222
10223 period_table = asc_dvc->sdtr_period_tbl;
10224 max_index = (int)asc_dvc->max_sdtr_index;
10225 min_index = (int)asc_dvc->host_init_sdtr_index;
10226 if ((syn_time <= period_table[max_index])) {
10227 for (i = min_index; i < (max_index - 1); i++) {
10228 if (syn_time <= period_table[i]) {
10229 return ((uchar)i);
10230 }
10231 }
10232 return ((uchar)max_index);
10233 } else {
10234 return ((uchar)(max_index + 1));
10235 }
1da177e4
LT
10236}
10237
27c868c2 10238static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
1da177e4 10239{
27c868c2
MW
10240 ushort q_addr;
10241 uchar next_qp;
10242 uchar q_status;
10243
10244 q_addr = ASC_QNO_TO_QADDR(free_q_head);
10245 q_status = (uchar)AscReadLramByte(iop_base,
10246 (ushort)(q_addr +
10247 ASC_SCSIQ_B_STATUS));
10248 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
10249 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
10250 return (next_qp);
10251 }
10252 return (ASC_QLINK_END);
1da177e4
LT
10253}
10254
27c868c2
MW
10255static uchar
10256AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
1da177e4 10257{
27c868c2 10258 uchar i;
1da177e4 10259
27c868c2
MW
10260 for (i = 0; i < n_free_q; i++) {
10261 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
10262 == ASC_QLINK_END) {
10263 return (ASC_QLINK_END);
10264 }
10265 }
10266 return (free_q_head);
1da177e4
LT
10267}
10268
27c868c2 10269static int AscHostReqRiscHalt(PortAddr iop_base)
1da177e4 10270{
27c868c2
MW
10271 int count = 0;
10272 int sta = 0;
10273 uchar saved_stop_code;
10274
10275 if (AscIsChipHalted(iop_base))
10276 return (1);
10277 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
10278 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
10279 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
10280 do {
10281 if (AscIsChipHalted(iop_base)) {
10282 sta = 1;
10283 break;
10284 }
10285 DvcSleepMilliSecond(100);
10286 } while (count++ < 20);
10287 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
10288 return (sta);
1da177e4
LT
10289}
10290
27c868c2 10291static int AscStopQueueExe(PortAddr iop_base)
1da177e4 10292{
27c868c2
MW
10293 int count = 0;
10294
10295 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
10296 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
10297 ASC_STOP_REQ_RISC_STOP);
10298 do {
10299 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
10300 ASC_STOP_ACK_RISC_STOP) {
10301 return (1);
10302 }
10303 DvcSleepMilliSecond(100);
10304 } while (count++ < 20);
10305 }
10306 return (0);
1da177e4
LT
10307}
10308
27c868c2 10309static void DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
1da177e4 10310{
27c868c2 10311 udelay(micro_sec);
1da177e4
LT
10312}
10313
27c868c2 10314static void DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
1da177e4 10315{
27c868c2 10316 udelay((nano_sec + 999) / 1000);
1da177e4
LT
10317}
10318
10319#ifdef CONFIG_ISA
27c868c2 10320static ASC_DCNT __init AscGetEisaProductID(PortAddr iop_base)
1da177e4 10321{
27c868c2
MW
10322 PortAddr eisa_iop;
10323 ushort product_id_high, product_id_low;
10324 ASC_DCNT product_id;
10325
10326 eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
10327 product_id_low = inpw(eisa_iop);
10328 product_id_high = inpw(eisa_iop + 2);
10329 product_id = ((ASC_DCNT) product_id_high << 16) |
10330 (ASC_DCNT) product_id_low;
10331 return (product_id);
1da177e4
LT
10332}
10333
27c868c2 10334static PortAddr __init AscSearchIOPortAddrEISA(PortAddr iop_base)
1da177e4 10335{
27c868c2
MW
10336 ASC_DCNT eisa_product_id;
10337
10338 if (iop_base == 0) {
10339 iop_base = ASC_EISA_MIN_IOP_ADDR;
10340 } else {
10341 if (iop_base == ASC_EISA_MAX_IOP_ADDR)
10342 return (0);
10343 if ((iop_base & 0x0050) == 0x0050) {
10344 iop_base += ASC_EISA_BIG_IOP_GAP;
10345 } else {
10346 iop_base += ASC_EISA_SMALL_IOP_GAP;
10347 }
10348 }
10349 while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
10350 eisa_product_id = AscGetEisaProductID(iop_base);
10351 if ((eisa_product_id == ASC_EISA_ID_740) ||
10352 (eisa_product_id == ASC_EISA_ID_750)) {
10353 if (AscFindSignature(iop_base)) {
10354 inpw(iop_base + 4);
10355 return (iop_base);
10356 }
10357 }
10358 if (iop_base == ASC_EISA_MAX_IOP_ADDR)
10359 return (0);
10360 if ((iop_base & 0x0050) == 0x0050) {
10361 iop_base += ASC_EISA_BIG_IOP_GAP;
10362 } else {
10363 iop_base += ASC_EISA_SMALL_IOP_GAP;
10364 }
10365 }
10366 return (0);
1da177e4
LT
10367}
10368#endif /* CONFIG_ISA */
10369
27c868c2 10370static int AscStartChip(PortAddr iop_base)
1da177e4 10371{
27c868c2
MW
10372 AscSetChipControl(iop_base, 0);
10373 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
10374 return (0);
10375 }
10376 return (1);
1da177e4
LT
10377}
10378
27c868c2 10379static int AscStopChip(PortAddr iop_base)
1da177e4 10380{
27c868c2
MW
10381 uchar cc_val;
10382
10383 cc_val =
10384 AscGetChipControl(iop_base) &
10385 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
10386 AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
10387 AscSetChipIH(iop_base, INS_HALT);
10388 AscSetChipIH(iop_base, INS_RFLAG_WTM);
10389 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
10390 return (0);
10391 }
10392 return (1);
1da177e4
LT
10393}
10394
27c868c2 10395static int AscIsChipHalted(PortAddr iop_base)
1da177e4 10396{
27c868c2
MW
10397 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
10398 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
10399 return (1);
10400 }
10401 }
10402 return (0);
1da177e4
LT
10403}
10404
27c868c2 10405static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
1da177e4 10406{
27c868c2
MW
10407 AscSetBank(iop_base, 1);
10408 AscWriteChipIH(iop_base, ins_code);
10409 AscSetBank(iop_base, 0);
10410 return;
1da177e4
LT
10411}
10412
27c868c2 10413static void AscAckInterrupt(PortAddr iop_base)
1da177e4 10414{
27c868c2
MW
10415 uchar host_flag;
10416 uchar risc_flag;
10417 ushort loop;
10418
10419 loop = 0;
10420 do {
10421 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
10422 if (loop++ > 0x7FFF) {
10423 break;
10424 }
10425 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
10426 host_flag =
10427 AscReadLramByte(iop_base,
10428 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
10429 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10430 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
10431 AscSetChipStatus(iop_base, CIW_INT_ACK);
10432 loop = 0;
10433 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
10434 AscSetChipStatus(iop_base, CIW_INT_ACK);
10435 if (loop++ > 3) {
10436 break;
10437 }
10438 }
10439 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10440 return;
1da177e4
LT
10441}
10442
27c868c2 10443static void AscDisableInterrupt(PortAddr iop_base)
1da177e4 10444{
27c868c2 10445 ushort cfg;
1da177e4 10446
27c868c2
MW
10447 cfg = AscGetChipCfgLsw(iop_base);
10448 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
10449 return;
1da177e4
LT
10450}
10451
27c868c2 10452static void AscEnableInterrupt(PortAddr iop_base)
1da177e4 10453{
27c868c2 10454 ushort cfg;
1da177e4 10455
27c868c2
MW
10456 cfg = AscGetChipCfgLsw(iop_base);
10457 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
10458 return;
1da177e4
LT
10459}
10460
27c868c2 10461static void AscSetBank(PortAddr iop_base, uchar bank)
1da177e4 10462{
27c868c2
MW
10463 uchar val;
10464
10465 val = AscGetChipControl(iop_base) &
10466 (~
10467 (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
10468 CC_CHIP_RESET));
10469 if (bank == 1) {
10470 val |= CC_BANK_ONE;
10471 } else if (bank == 2) {
10472 val |= CC_DIAG | CC_BANK_ONE;
10473 } else {
10474 val &= ~CC_BANK_ONE;
10475 }
10476 AscSetChipControl(iop_base, val);
10477 return;
1da177e4
LT
10478}
10479
27c868c2 10480static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
1da177e4 10481{
27c868c2
MW
10482 PortAddr iop_base;
10483 int i = 10;
1da177e4 10484
27c868c2
MW
10485 iop_base = asc_dvc->iop_base;
10486 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
10487 && (i-- > 0)) {
10488 DvcSleepMilliSecond(100);
10489 }
10490 AscStopChip(iop_base);
10491 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
10492 DvcDelayNanoSecond(asc_dvc, 60000);
10493 AscSetChipIH(iop_base, INS_RFLAG_WTM);
10494 AscSetChipIH(iop_base, INS_HALT);
10495 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
10496 AscSetChipControl(iop_base, CC_HALT);
10497 DvcSleepMilliSecond(200);
10498 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10499 AscSetChipStatus(iop_base, 0);
10500 return (AscIsChipHalted(iop_base));
1da177e4
LT
10501}
10502
27c868c2 10503static ASC_DCNT __init AscGetMaxDmaCount(ushort bus_type)
1da177e4 10504{
27c868c2
MW
10505 if (bus_type & ASC_IS_ISA)
10506 return (ASC_MAX_ISA_DMA_COUNT);
10507 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
10508 return (ASC_MAX_VL_DMA_COUNT);
10509 return (ASC_MAX_PCI_DMA_COUNT);
1da177e4
LT
10510}
10511
10512#ifdef CONFIG_ISA
27c868c2 10513static ushort __init AscGetIsaDmaChannel(PortAddr iop_base)
1da177e4 10514{
27c868c2
MW
10515 ushort channel;
10516
10517 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
10518 if (channel == 0x03)
10519 return (0);
10520 else if (channel == 0x00)
10521 return (7);
10522 return (channel + 4);
1da177e4
LT
10523}
10524
27c868c2 10525static ushort __init AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
1da177e4 10526{
27c868c2
MW
10527 ushort cfg_lsw;
10528 uchar value;
10529
10530 if ((dma_channel >= 5) && (dma_channel <= 7)) {
10531 if (dma_channel == 7)
10532 value = 0x00;
10533 else
10534 value = dma_channel - 4;
10535 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
10536 cfg_lsw |= value;
10537 AscSetChipCfgLsw(iop_base, cfg_lsw);
10538 return (AscGetIsaDmaChannel(iop_base));
10539 }
10540 return (0);
1da177e4
LT
10541}
10542
27c868c2 10543static uchar __init AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
1da177e4 10544{
27c868c2
MW
10545 speed_value &= 0x07;
10546 AscSetBank(iop_base, 1);
10547 AscWriteChipDmaSpeed(iop_base, speed_value);
10548 AscSetBank(iop_base, 0);
10549 return (AscGetIsaDmaSpeed(iop_base));
1da177e4
LT
10550}
10551
27c868c2 10552static uchar __init AscGetIsaDmaSpeed(PortAddr iop_base)
1da177e4 10553{
27c868c2 10554 uchar speed_value;
1da177e4 10555
27c868c2
MW
10556 AscSetBank(iop_base, 1);
10557 speed_value = AscReadChipDmaSpeed(iop_base);
10558 speed_value &= 0x07;
10559 AscSetBank(iop_base, 0);
10560 return (speed_value);
1da177e4
LT
10561}
10562#endif /* CONFIG_ISA */
10563
27c868c2
MW
10564static ushort __init
10565AscReadPCIConfigWord(ASC_DVC_VAR *asc_dvc, ushort pci_config_offset)
1da177e4 10566{
27c868c2 10567 uchar lsb, msb;
1da177e4 10568
27c868c2
MW
10569 lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
10570 msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
10571 return ((ushort)((msb << 8) | lsb));
1da177e4
LT
10572}
10573
27c868c2 10574static ushort __init AscInitGetConfig(ASC_DVC_VAR *asc_dvc)
1da177e4 10575{
27c868c2
MW
10576 ushort warn_code;
10577 PortAddr iop_base;
10578 ushort PCIDeviceID;
10579 ushort PCIVendorID;
10580 uchar PCIRevisionID;
10581 uchar prevCmdRegBits;
10582
10583 warn_code = 0;
10584 iop_base = asc_dvc->iop_base;
10585 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
10586 if (asc_dvc->err_code != 0) {
10587 return (UW_ERR);
10588 }
10589 if (asc_dvc->bus_type == ASC_IS_PCI) {
10590 PCIVendorID = AscReadPCIConfigWord(asc_dvc,
10591 AscPCIConfigVendorIDRegister);
10592
10593 PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
10594 AscPCIConfigDeviceIDRegister);
10595
10596 PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
10597 AscPCIConfigRevisionIDRegister);
10598
10599 if (PCIVendorID != PCI_VENDOR_ID_ASP) {
10600 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10601 }
10602 prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
10603 AscPCIConfigCommandRegister);
10604
10605 if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
10606 AscPCICmdRegBits_IOMemBusMaster) {
10607 DvcWritePCIConfigByte(asc_dvc,
10608 AscPCIConfigCommandRegister,
10609 (prevCmdRegBits |
10610 AscPCICmdRegBits_IOMemBusMaster));
10611
10612 if ((DvcReadPCIConfigByte(asc_dvc,
10613 AscPCIConfigCommandRegister)
10614 & AscPCICmdRegBits_IOMemBusMaster)
10615 != AscPCICmdRegBits_IOMemBusMaster) {
10616 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10617 }
10618 }
10619 if ((PCIDeviceID == PCI_DEVICE_ID_ASP_1200A) ||
10620 (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940)) {
10621 DvcWritePCIConfigByte(asc_dvc,
10622 AscPCIConfigLatencyTimer, 0x00);
10623 if (DvcReadPCIConfigByte
10624 (asc_dvc, AscPCIConfigLatencyTimer)
10625 != 0x00) {
10626 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10627 }
10628 } else if (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940U) {
10629 if (DvcReadPCIConfigByte(asc_dvc,
10630 AscPCIConfigLatencyTimer) <
10631 0x20) {
10632 DvcWritePCIConfigByte(asc_dvc,
10633 AscPCIConfigLatencyTimer,
10634 0x20);
10635
10636 if (DvcReadPCIConfigByte(asc_dvc,
10637 AscPCIConfigLatencyTimer)
10638 < 0x20) {
10639 warn_code |=
10640 ASC_WARN_SET_PCI_CONFIG_SPACE;
10641 }
10642 }
10643 }
10644 }
1da177e4 10645
27c868c2
MW
10646 if (AscFindSignature(iop_base)) {
10647 warn_code |= AscInitAscDvcVar(asc_dvc);
10648 warn_code |= AscInitFromEEP(asc_dvc);
10649 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
10650 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
10651 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
10652 }
10653 } else {
10654 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10655 }
10656 return (warn_code);
1da177e4
LT
10657}
10658
27c868c2 10659static ushort __init AscInitSetConfig(ASC_DVC_VAR *asc_dvc)
1da177e4 10660{
27c868c2
MW
10661 ushort warn_code = 0;
10662
10663 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
10664 if (asc_dvc->err_code != 0)
10665 return (UW_ERR);
10666 if (AscFindSignature(asc_dvc->iop_base)) {
10667 warn_code |= AscInitFromAscDvcVar(asc_dvc);
10668 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
10669 } else {
10670 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10671 }
10672 return (warn_code);
1da177e4
LT
10673}
10674
27c868c2 10675static ushort __init AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc)
1da177e4 10676{
27c868c2
MW
10677 PortAddr iop_base;
10678 ushort cfg_msw;
10679 ushort warn_code;
10680 ushort pci_device_id = 0;
1da177e4 10681
27c868c2 10682 iop_base = asc_dvc->iop_base;
1da177e4 10683#ifdef CONFIG_PCI
27c868c2
MW
10684 if (asc_dvc->cfg->dev)
10685 pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device;
1da177e4 10686#endif
27c868c2
MW
10687 warn_code = 0;
10688 cfg_msw = AscGetChipCfgMsw(iop_base);
10689 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10690 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10691 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10692 AscSetChipCfgMsw(iop_base, cfg_msw);
10693 }
10694 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
10695 asc_dvc->cfg->cmd_qng_enabled) {
10696 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
10697 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10698 }
10699 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10700 warn_code |= ASC_WARN_AUTO_CONFIG;
10701 }
10702 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
10703 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
10704 != asc_dvc->irq_no) {
10705 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
10706 }
10707 }
10708 if (asc_dvc->bus_type & ASC_IS_PCI) {
10709 cfg_msw &= 0xFFC0;
10710 AscSetChipCfgMsw(iop_base, cfg_msw);
10711 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
10712 } else {
10713 if ((pci_device_id == PCI_DEVICE_ID_ASP_1200A) ||
10714 (pci_device_id == PCI_DEVICE_ID_ASP_ABP940)) {
10715 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
10716 asc_dvc->bug_fix_cntl |=
10717 ASC_BUG_FIX_ASYN_USE_SYN;
10718 }
10719 }
10720 } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
10721 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
10722 == ASC_CHIP_VER_ASYN_BUG) {
10723 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
10724 }
10725 }
10726 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
10727 asc_dvc->cfg->chip_scsi_id) {
10728 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
10729 }
1da177e4 10730#ifdef CONFIG_ISA
27c868c2
MW
10731 if (asc_dvc->bus_type & ASC_IS_ISA) {
10732 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
10733 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
10734 }
1da177e4 10735#endif /* CONFIG_ISA */
27c868c2 10736 return (warn_code);
1da177e4
LT
10737}
10738
27c868c2 10739static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
1da177e4 10740{
27c868c2
MW
10741 ushort warn_code;
10742 PortAddr iop_base;
10743
10744 iop_base = asc_dvc->iop_base;
10745 warn_code = 0;
10746 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
10747 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
10748 AscResetChipAndScsiBus(asc_dvc);
10749 DvcSleepMilliSecond((ASC_DCNT)
10750 ((ushort)asc_dvc->scsi_reset_wait * 1000));
10751 }
10752 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
10753 if (asc_dvc->err_code != 0)
10754 return (UW_ERR);
10755 if (!AscFindSignature(asc_dvc->iop_base)) {
10756 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10757 return (warn_code);
10758 }
10759 AscDisableInterrupt(iop_base);
10760 warn_code |= AscInitLram(asc_dvc);
10761 if (asc_dvc->err_code != 0)
10762 return (UW_ERR);
10763 ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
10764 (ulong)_asc_mcode_chksum);
10765 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
10766 _asc_mcode_size) != _asc_mcode_chksum) {
10767 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
10768 return (warn_code);
10769 }
10770 warn_code |= AscInitMicroCodeVar(asc_dvc);
10771 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
10772 AscEnableInterrupt(iop_base);
10773 return (warn_code);
1da177e4
LT
10774}
10775
27c868c2 10776static ushort __init AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
1da177e4 10777{
27c868c2
MW
10778 int i;
10779 PortAddr iop_base;
10780 ushort warn_code;
10781 uchar chip_version;
10782
10783 iop_base = asc_dvc->iop_base;
10784 warn_code = 0;
10785 asc_dvc->err_code = 0;
10786 if ((asc_dvc->bus_type &
10787 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
10788 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
10789 }
10790 AscSetChipControl(iop_base, CC_HALT);
10791 AscSetChipStatus(iop_base, 0);
10792 asc_dvc->bug_fix_cntl = 0;
10793 asc_dvc->pci_fix_asyn_xfer = 0;
10794 asc_dvc->pci_fix_asyn_xfer_always = 0;
10795 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
10796 asc_dvc->sdtr_done = 0;
10797 asc_dvc->cur_total_qng = 0;
10798 asc_dvc->is_in_int = 0;
10799 asc_dvc->in_critical_cnt = 0;
10800 asc_dvc->last_q_shortage = 0;
10801 asc_dvc->use_tagged_qng = 0;
10802 asc_dvc->no_scam = 0;
10803 asc_dvc->unit_not_ready = 0;
10804 asc_dvc->queue_full_or_busy = 0;
10805 asc_dvc->redo_scam = 0;
10806 asc_dvc->res2 = 0;
10807 asc_dvc->host_init_sdtr_index = 0;
10808 asc_dvc->cfg->can_tagged_qng = 0;
10809 asc_dvc->cfg->cmd_qng_enabled = 0;
10810 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
10811 asc_dvc->init_sdtr = 0;
10812 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
10813 asc_dvc->scsi_reset_wait = 3;
10814 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
10815 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
10816 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
10817 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
10818 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
10819 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
10820 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
10821 ASC_LIB_VERSION_MINOR;
10822 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
10823 asc_dvc->cfg->chip_version = chip_version;
10824 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
10825 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
10826 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
10827 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
10828 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
10829 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
10830 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
10831 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
10832 asc_dvc->max_sdtr_index = 7;
10833 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
10834 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
10835 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
10836 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
10837 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
10838 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
10839 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
10840 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
10841 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
10842 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
10843 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
10844 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
10845 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
10846 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
10847 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
10848 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
10849 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
10850 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
10851 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
10852 asc_dvc->max_sdtr_index = 15;
10853 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
10854 AscSetExtraControl(iop_base,
10855 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10856 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
10857 AscSetExtraControl(iop_base,
10858 (SEC_ACTIVE_NEGATE |
10859 SEC_ENABLE_FILTER));
10860 }
10861 }
10862 if (asc_dvc->bus_type == ASC_IS_PCI) {
10863 AscSetExtraControl(iop_base,
10864 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10865 }
1da177e4 10866
27c868c2
MW
10867 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
10868 if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
10869 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
10870 asc_dvc->bus_type = ASC_IS_ISAPNP;
10871 }
1da177e4 10872#ifdef CONFIG_ISA
27c868c2
MW
10873 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
10874 asc_dvc->cfg->isa_dma_channel =
10875 (uchar)AscGetIsaDmaChannel(iop_base);
10876 }
1da177e4 10877#endif /* CONFIG_ISA */
27c868c2
MW
10878 for (i = 0; i <= ASC_MAX_TID; i++) {
10879 asc_dvc->cur_dvc_qng[i] = 0;
10880 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
10881 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
10882 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
10883 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
10884 }
10885 return (warn_code);
1da177e4
LT
10886}
10887
27c868c2 10888static ushort __init AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
1da177e4 10889{
27c868c2
MW
10890 ASCEEP_CONFIG eep_config_buf;
10891 ASCEEP_CONFIG *eep_config;
10892 PortAddr iop_base;
10893 ushort chksum;
10894 ushort warn_code;
10895 ushort cfg_msw, cfg_lsw;
10896 int i;
10897 int write_eep = 0;
10898
10899 iop_base = asc_dvc->iop_base;
10900 warn_code = 0;
10901 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
10902 AscStopQueueExe(iop_base);
10903 if ((AscStopChip(iop_base) == FALSE) ||
10904 (AscGetChipScsiCtrl(iop_base) != 0)) {
10905 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
10906 AscResetChipAndScsiBus(asc_dvc);
10907 DvcSleepMilliSecond((ASC_DCNT)
10908 ((ushort)asc_dvc->scsi_reset_wait * 1000));
10909 }
10910 if (AscIsChipHalted(iop_base) == FALSE) {
10911 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10912 return (warn_code);
10913 }
10914 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10915 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10916 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10917 return (warn_code);
10918 }
10919 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
10920 cfg_msw = AscGetChipCfgMsw(iop_base);
10921 cfg_lsw = AscGetChipCfgLsw(iop_base);
10922 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10923 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10924 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10925 AscSetChipCfgMsw(iop_base, cfg_msw);
10926 }
10927 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
10928 ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
10929 if (chksum == 0) {
10930 chksum = 0xaa55;
10931 }
10932 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10933 warn_code |= ASC_WARN_AUTO_CONFIG;
10934 if (asc_dvc->cfg->chip_version == 3) {
10935 if (eep_config->cfg_lsw != cfg_lsw) {
10936 warn_code |= ASC_WARN_EEPROM_RECOVER;
10937 eep_config->cfg_lsw =
10938 AscGetChipCfgLsw(iop_base);
10939 }
10940 if (eep_config->cfg_msw != cfg_msw) {
10941 warn_code |= ASC_WARN_EEPROM_RECOVER;
10942 eep_config->cfg_msw =
10943 AscGetChipCfgMsw(iop_base);
10944 }
10945 }
10946 }
10947 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
10948 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
10949 ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
10950 eep_config->chksum);
10951 if (chksum != eep_config->chksum) {
10952 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
10953 ASC_CHIP_VER_PCI_ULTRA_3050) {
10954 ASC_DBG(1,
10955 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
10956 eep_config->init_sdtr = 0xFF;
10957 eep_config->disc_enable = 0xFF;
10958 eep_config->start_motor = 0xFF;
10959 eep_config->use_cmd_qng = 0;
10960 eep_config->max_total_qng = 0xF0;
10961 eep_config->max_tag_qng = 0x20;
10962 eep_config->cntl = 0xBFFF;
10963 ASC_EEP_SET_CHIP_ID(eep_config, 7);
10964 eep_config->no_scam = 0;
10965 eep_config->adapter_info[0] = 0;
10966 eep_config->adapter_info[1] = 0;
10967 eep_config->adapter_info[2] = 0;
10968 eep_config->adapter_info[3] = 0;
10969 eep_config->adapter_info[4] = 0;
10970 /* Indicate EEPROM-less board. */
10971 eep_config->adapter_info[5] = 0xBB;
10972 } else {
10973 ASC_PRINT
10974 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
10975 write_eep = 1;
10976 warn_code |= ASC_WARN_EEPROM_CHKSUM;
10977 }
10978 }
10979 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
10980 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
10981 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
10982 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
10983 asc_dvc->start_motor = eep_config->start_motor;
10984 asc_dvc->dvc_cntl = eep_config->cntl;
10985 asc_dvc->no_scam = eep_config->no_scam;
10986 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
10987 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
10988 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
10989 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
10990 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
10991 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
10992 if (!AscTestExternalLram(asc_dvc)) {
10993 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
10994 ASC_IS_PCI_ULTRA)) {
10995 eep_config->max_total_qng =
10996 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
10997 eep_config->max_tag_qng =
10998 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
10999 } else {
11000 eep_config->cfg_msw |= 0x0800;
11001 cfg_msw |= 0x0800;
11002 AscSetChipCfgMsw(iop_base, cfg_msw);
11003 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
11004 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
11005 }
11006 } else {
11007 }
11008 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
11009 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
11010 }
11011 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
11012 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
11013 }
11014 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
11015 eep_config->max_tag_qng = eep_config->max_total_qng;
11016 }
11017 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
11018 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
11019 }
11020 asc_dvc->max_total_qng = eep_config->max_total_qng;
11021 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
11022 eep_config->use_cmd_qng) {
11023 eep_config->disc_enable = eep_config->use_cmd_qng;
11024 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
11025 }
11026 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
11027 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
11028 }
11029 ASC_EEP_SET_CHIP_ID(eep_config,
11030 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
11031 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
11032 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
11033 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
11034 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
11035 }
1da177e4 11036
27c868c2
MW
11037 for (i = 0; i <= ASC_MAX_TID; i++) {
11038 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
11039 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
11040 asc_dvc->cfg->sdtr_period_offset[i] =
11041 (uchar)(ASC_DEF_SDTR_OFFSET |
11042 (asc_dvc->host_init_sdtr_index << 4));
11043 }
11044 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
11045 if (write_eep) {
11046 if ((i =
11047 AscSetEEPConfig(iop_base, eep_config,
11048 asc_dvc->bus_type)) != 0) {
11049 ASC_PRINT1
11050 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
11051 i);
11052 } else {
11053 ASC_PRINT
11054 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
11055 }
11056 }
11057 return (warn_code);
1da177e4
LT
11058}
11059
27c868c2 11060static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
1da177e4 11061{
27c868c2
MW
11062 int i;
11063 ushort warn_code;
11064 PortAddr iop_base;
11065 ASC_PADDR phy_addr;
11066 ASC_DCNT phy_size;
11067
11068 iop_base = asc_dvc->iop_base;
11069 warn_code = 0;
11070 for (i = 0; i <= ASC_MAX_TID; i++) {
11071 AscPutMCodeInitSDTRAtID(iop_base, i,
11072 asc_dvc->cfg->sdtr_period_offset[i]
11073 );
11074 }
1da177e4 11075
27c868c2
MW
11076 AscInitQLinkVar(asc_dvc);
11077 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
11078 asc_dvc->cfg->disc_enable);
11079 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
11080 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
11081
11082 /* Align overrun buffer on an 8 byte boundary. */
11083 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
11084 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
11085 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
11086 (uchar *)&phy_addr, 1);
11087 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
11088 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
11089 (uchar *)&phy_size, 1);
11090
11091 asc_dvc->cfg->mcode_date =
11092 AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
11093 asc_dvc->cfg->mcode_version =
11094 AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
11095
11096 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
11097 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
11098 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
11099 return (warn_code);
11100 }
11101 if (AscStartChip(iop_base) != 1) {
11102 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
11103 return (warn_code);
11104 }
1da177e4 11105
27c868c2 11106 return (warn_code);
1da177e4
LT
11107}
11108
27c868c2 11109static int __init AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
1da177e4 11110{
27c868c2
MW
11111 PortAddr iop_base;
11112 ushort q_addr;
11113 ushort saved_word;
11114 int sta;
11115
11116 iop_base = asc_dvc->iop_base;
11117 sta = 0;
11118 q_addr = ASC_QNO_TO_QADDR(241);
11119 saved_word = AscReadLramWord(iop_base, q_addr);
11120 AscSetChipLramAddr(iop_base, q_addr);
11121 AscSetChipLramData(iop_base, 0x55AA);
11122 DvcSleepMilliSecond(10);
11123 AscSetChipLramAddr(iop_base, q_addr);
11124 if (AscGetChipLramData(iop_base) == 0x55AA) {
11125 sta = 1;
11126 AscWriteLramWord(iop_base, q_addr, saved_word);
11127 }
11128 return (sta);
1da177e4
LT
11129}
11130
27c868c2 11131static int __init AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
1da177e4 11132{
27c868c2
MW
11133 uchar read_back;
11134 int retry;
11135
11136 retry = 0;
11137 while (TRUE) {
11138 AscSetChipEEPCmd(iop_base, cmd_reg);
11139 DvcSleepMilliSecond(1);
11140 read_back = AscGetChipEEPCmd(iop_base);
11141 if (read_back == cmd_reg) {
11142 return (1);
11143 }
11144 if (retry++ > ASC_EEP_MAX_RETRY) {
11145 return (0);
11146 }
11147 }
1da177e4
LT
11148}
11149
27c868c2 11150static int __init AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
1da177e4 11151{
27c868c2
MW
11152 ushort read_back;
11153 int retry;
11154
11155 retry = 0;
11156 while (TRUE) {
11157 AscSetChipEEPData(iop_base, data_reg);
11158 DvcSleepMilliSecond(1);
11159 read_back = AscGetChipEEPData(iop_base);
11160 if (read_back == data_reg) {
11161 return (1);
11162 }
11163 if (retry++ > ASC_EEP_MAX_RETRY) {
11164 return (0);
11165 }
11166 }
1da177e4
LT
11167}
11168
27c868c2 11169static void __init AscWaitEEPRead(void)
1da177e4 11170{
27c868c2
MW
11171 DvcSleepMilliSecond(1);
11172 return;
1da177e4
LT
11173}
11174
27c868c2 11175static void __init AscWaitEEPWrite(void)
1da177e4 11176{
27c868c2
MW
11177 DvcSleepMilliSecond(20);
11178 return;
1da177e4
LT
11179}
11180
27c868c2 11181static ushort __init AscReadEEPWord(PortAddr iop_base, uchar addr)
1da177e4 11182{
27c868c2
MW
11183 ushort read_wval;
11184 uchar cmd_reg;
11185
11186 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11187 AscWaitEEPRead();
11188 cmd_reg = addr | ASC_EEP_CMD_READ;
11189 AscWriteEEPCmdReg(iop_base, cmd_reg);
11190 AscWaitEEPRead();
11191 read_wval = AscGetChipEEPData(iop_base);
11192 AscWaitEEPRead();
11193 return (read_wval);
1da177e4
LT
11194}
11195
27c868c2
MW
11196static ushort __init
11197AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
1da177e4 11198{
27c868c2
MW
11199 ushort read_wval;
11200
11201 read_wval = AscReadEEPWord(iop_base, addr);
11202 if (read_wval != word_val) {
11203 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
11204 AscWaitEEPRead();
11205 AscWriteEEPDataReg(iop_base, word_val);
11206 AscWaitEEPRead();
11207 AscWriteEEPCmdReg(iop_base,
11208 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
11209 AscWaitEEPWrite();
11210 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11211 AscWaitEEPRead();
11212 return (AscReadEEPWord(iop_base, addr));
11213 }
11214 return (read_wval);
1da177e4
LT
11215}
11216
27c868c2
MW
11217static ushort __init
11218AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 11219{
27c868c2
MW
11220 ushort wval;
11221 ushort sum;
11222 ushort *wbuf;
11223 int cfg_beg;
11224 int cfg_end;
11225 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11226 int s_addr;
11227
11228 wbuf = (ushort *)cfg_buf;
11229 sum = 0;
11230 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
11231 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11232 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11233 sum += *wbuf;
11234 }
11235 if (bus_type & ASC_IS_VL) {
11236 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11237 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11238 } else {
11239 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11240 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11241 }
11242 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11243 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
11244 if (s_addr <= uchar_end_in_config) {
11245 /*
11246 * Swap all char fields - must unswap bytes already swapped
11247 * by AscReadEEPWord().
11248 */
11249 *wbuf = le16_to_cpu(wval);
11250 } else {
11251 /* Don't swap word field at the end - cntl field. */
11252 *wbuf = wval;
11253 }
11254 sum += wval; /* Checksum treats all EEPROM data as words. */
11255 }
11256 /*
11257 * Read the checksum word which will be compared against 'sum'
11258 * by the caller. Word field already swapped.
11259 */
11260 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11261 return (sum);
1da177e4
LT
11262}
11263
27c868c2
MW
11264static int __init
11265AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 11266{
27c868c2
MW
11267 int n_error;
11268 ushort *wbuf;
11269 ushort word;
11270 ushort sum;
11271 int s_addr;
11272 int cfg_beg;
11273 int cfg_end;
11274 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11275
11276 wbuf = (ushort *)cfg_buf;
11277 n_error = 0;
11278 sum = 0;
11279 /* Write two config words; AscWriteEEPWord() will swap bytes. */
11280 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11281 sum += *wbuf;
11282 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11283 n_error++;
11284 }
11285 }
11286 if (bus_type & ASC_IS_VL) {
11287 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11288 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11289 } else {
11290 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11291 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11292 }
11293 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11294 if (s_addr <= uchar_end_in_config) {
11295 /*
11296 * This is a char field. Swap char fields before they are
11297 * swapped again by AscWriteEEPWord().
11298 */
11299 word = cpu_to_le16(*wbuf);
11300 if (word !=
11301 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
11302 n_error++;
11303 }
11304 } else {
11305 /* Don't swap word field at the end - cntl field. */
11306 if (*wbuf !=
11307 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11308 n_error++;
11309 }
11310 }
11311 sum += *wbuf; /* Checksum calculated from word values. */
11312 }
11313 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
11314 *wbuf = sum;
11315 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
11316 n_error++;
11317 }
1da177e4 11318
27c868c2
MW
11319 /* Read EEPROM back again. */
11320 wbuf = (ushort *)cfg_buf;
11321 /*
11322 * Read two config words; Byte-swapping done by AscReadEEPWord().
11323 */
11324 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11325 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
11326 n_error++;
11327 }
11328 }
11329 if (bus_type & ASC_IS_VL) {
11330 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11331 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11332 } else {
11333 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11334 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11335 }
11336 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11337 if (s_addr <= uchar_end_in_config) {
11338 /*
11339 * Swap all char fields. Must unswap bytes already swapped
11340 * by AscReadEEPWord().
11341 */
11342 word =
11343 le16_to_cpu(AscReadEEPWord
11344 (iop_base, (uchar)s_addr));
11345 } else {
11346 /* Don't swap word field at the end - cntl field. */
11347 word = AscReadEEPWord(iop_base, (uchar)s_addr);
11348 }
11349 if (*wbuf != word) {
11350 n_error++;
11351 }
11352 }
11353 /* Read checksum; Byte swapping not needed. */
11354 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
11355 n_error++;
11356 }
11357 return (n_error);
1da177e4
LT
11358}
11359
27c868c2
MW
11360static int __init
11361AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 11362{
27c868c2
MW
11363 int retry;
11364 int n_error;
11365
11366 retry = 0;
11367 while (TRUE) {
11368 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
11369 bus_type)) == 0) {
11370 break;
11371 }
11372 if (++retry > ASC_EEP_MAX_RETRY) {
11373 break;
11374 }
11375 }
11376 return (n_error);
1da177e4
LT
11377}
11378
27c868c2
MW
11379static void
11380AscAsyncFix(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq)
1da177e4 11381{
27c868c2
MW
11382 uchar dvc_type;
11383 ASC_SCSI_BIT_ID_TYPE tid_bits;
11384
11385 dvc_type = ASC_INQ_DVC_TYPE(inq);
11386 tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
11387
11388 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
11389 if (!(asc_dvc->init_sdtr & tid_bits)) {
11390 if ((dvc_type == TYPE_ROM) &&
11391 (AscCompareString((uchar *)inq->vendor_id,
11392 (uchar *)"HP ", 3) == 0)) {
11393 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
11394 }
11395 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
11396 if ((dvc_type == TYPE_PROCESSOR) ||
11397 (dvc_type == TYPE_SCANNER) ||
11398 (dvc_type == TYPE_ROM) || (dvc_type == TYPE_TAPE)) {
11399 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
11400 }
11401
11402 if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
11403 AscSetRunChipSynRegAtID(asc_dvc->iop_base,
11404 tid_no,
11405 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
11406 }
11407 }
11408 }
11409 return;
1da177e4
LT
11410}
11411
27c868c2 11412static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
1da177e4 11413{
27c868c2
MW
11414 if ((inq->add_len >= 32) &&
11415 (AscCompareString((uchar *)inq->vendor_id,
11416 (uchar *)"QUANTUM XP34301", 15) == 0) &&
11417 (AscCompareString((uchar *)inq->product_rev_level,
11418 (uchar *)"1071", 4) == 0)) {
11419 return 0;
11420 }
11421 return 1;
1da177e4
LT
11422}
11423
27c868c2
MW
11424static void
11425AscInquiryHandling(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq)
1da177e4 11426{
27c868c2
MW
11427 ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
11428 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
11429
11430 orig_init_sdtr = asc_dvc->init_sdtr;
11431 orig_use_tagged_qng = asc_dvc->use_tagged_qng;
11432
11433 asc_dvc->init_sdtr &= ~tid_bit;
11434 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
11435 asc_dvc->use_tagged_qng &= ~tid_bit;
11436
11437 if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) {
11438 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) {
11439 asc_dvc->init_sdtr |= tid_bit;
11440 }
11441 if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) &&
11442 ASC_INQ_CMD_QUEUE(inq)) {
11443 if (AscTagQueuingSafe(inq)) {
11444 asc_dvc->use_tagged_qng |= tid_bit;
11445 asc_dvc->cfg->can_tagged_qng |= tid_bit;
11446 }
11447 }
11448 }
11449 if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
11450 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
11451 asc_dvc->cfg->disc_enable);
11452 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
11453 asc_dvc->use_tagged_qng);
11454 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
11455 asc_dvc->cfg->can_tagged_qng);
11456
11457 asc_dvc->max_dvc_qng[tid_no] =
11458 asc_dvc->cfg->max_tag_qng[tid_no];
11459 AscWriteLramByte(asc_dvc->iop_base,
11460 (ushort)(ASCV_MAX_DVC_QNG_BEG + tid_no),
11461 asc_dvc->max_dvc_qng[tid_no]);
11462 }
11463 if (orig_init_sdtr != asc_dvc->init_sdtr) {
11464 AscAsyncFix(asc_dvc, tid_no, inq);
11465 }
11466 return;
1da177e4
LT
11467}
11468
27c868c2 11469static int AscCompareString(uchar *str1, uchar *str2, int len)
1da177e4 11470{
27c868c2
MW
11471 int i;
11472 int diff;
1da177e4 11473
27c868c2
MW
11474 for (i = 0; i < len; i++) {
11475 diff = (int)(str1[i] - str2[i]);
11476 if (diff != 0)
11477 return (diff);
11478 }
11479 return (0);
1da177e4
LT
11480}
11481
27c868c2 11482static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
1da177e4 11483{
27c868c2
MW
11484 uchar byte_data;
11485 ushort word_data;
11486
11487 if (isodd_word(addr)) {
11488 AscSetChipLramAddr(iop_base, addr - 1);
11489 word_data = AscGetChipLramData(iop_base);
11490 byte_data = (uchar)((word_data >> 8) & 0xFF);
11491 } else {
11492 AscSetChipLramAddr(iop_base, addr);
11493 word_data = AscGetChipLramData(iop_base);
11494 byte_data = (uchar)(word_data & 0xFF);
11495 }
11496 return (byte_data);
1da177e4 11497}
27c868c2
MW
11498
11499static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
1da177e4 11500{
27c868c2 11501 ushort word_data;
1da177e4 11502
27c868c2
MW
11503 AscSetChipLramAddr(iop_base, addr);
11504 word_data = AscGetChipLramData(iop_base);
11505 return (word_data);
1da177e4
LT
11506}
11507
11508#if CC_VERY_LONG_SG_LIST
27c868c2 11509static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
1da177e4 11510{
27c868c2
MW
11511 ushort val_low, val_high;
11512 ASC_DCNT dword_data;
11513
11514 AscSetChipLramAddr(iop_base, addr);
11515 val_low = AscGetChipLramData(iop_base);
11516 val_high = AscGetChipLramData(iop_base);
11517 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
11518 return (dword_data);
1da177e4
LT
11519}
11520#endif /* CC_VERY_LONG_SG_LIST */
11521
27c868c2 11522static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
1da177e4 11523{
27c868c2
MW
11524 AscSetChipLramAddr(iop_base, addr);
11525 AscSetChipLramData(iop_base, word_val);
11526 return;
1da177e4
LT
11527}
11528
27c868c2 11529static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
1da177e4 11530{
27c868c2
MW
11531 ushort word_data;
11532
11533 if (isodd_word(addr)) {
11534 addr--;
11535 word_data = AscReadLramWord(iop_base, addr);
11536 word_data &= 0x00FF;
11537 word_data |= (((ushort)byte_val << 8) & 0xFF00);
11538 } else {
11539 word_data = AscReadLramWord(iop_base, addr);
11540 word_data &= 0xFF00;
11541 word_data |= ((ushort)byte_val & 0x00FF);
11542 }
11543 AscWriteLramWord(iop_base, addr, word_data);
11544 return;
1da177e4
LT
11545}
11546
11547/*
11548 * Copy 2 bytes to LRAM.
11549 *
11550 * The source data is assumed to be in little-endian order in memory
11551 * and is maintained in little-endian order when written to LRAM.
11552 */
27c868c2
MW
11553static void
11554AscMemWordCopyPtrToLram(PortAddr iop_base,
11555 ushort s_addr, uchar *s_buffer, int words)
1da177e4 11556{
27c868c2
MW
11557 int i;
11558
11559 AscSetChipLramAddr(iop_base, s_addr);
11560 for (i = 0; i < 2 * words; i += 2) {
11561 /*
11562 * On a little-endian system the second argument below
11563 * produces a little-endian ushort which is written to
11564 * LRAM in little-endian order. On a big-endian system
11565 * the second argument produces a big-endian ushort which
11566 * is "transparently" byte-swapped by outpw() and written
11567 * in little-endian order to LRAM.
11568 */
11569 outpw(iop_base + IOP_RAM_DATA,
11570 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
11571 }
11572 return;
1da177e4
LT
11573}
11574
11575/*
11576 * Copy 4 bytes to LRAM.
11577 *
11578 * The source data is assumed to be in little-endian order in memory
11579 * and is maintained in little-endian order when writen to LRAM.
11580 */
27c868c2
MW
11581static void
11582AscMemDWordCopyPtrToLram(PortAddr iop_base,
11583 ushort s_addr, uchar *s_buffer, int dwords)
1da177e4 11584{
27c868c2
MW
11585 int i;
11586
11587 AscSetChipLramAddr(iop_base, s_addr);
11588 for (i = 0; i < 4 * dwords; i += 4) {
11589 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
11590 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
11591 }
11592 return;
1da177e4
LT
11593}
11594
11595/*
11596 * Copy 2 bytes from LRAM.
11597 *
11598 * The source data is assumed to be in little-endian order in LRAM
11599 * and is maintained in little-endian order when written to memory.
11600 */
27c868c2
MW
11601static void
11602AscMemWordCopyPtrFromLram(PortAddr iop_base,
11603 ushort s_addr, uchar *d_buffer, int words)
1da177e4 11604{
27c868c2
MW
11605 int i;
11606 ushort word;
11607
11608 AscSetChipLramAddr(iop_base, s_addr);
11609 for (i = 0; i < 2 * words; i += 2) {
11610 word = inpw(iop_base + IOP_RAM_DATA);
11611 d_buffer[i] = word & 0xff;
11612 d_buffer[i + 1] = (word >> 8) & 0xff;
11613 }
11614 return;
1da177e4
LT
11615}
11616
27c868c2 11617static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
1da177e4 11618{
27c868c2
MW
11619 ASC_DCNT sum;
11620 int i;
1da177e4 11621
27c868c2
MW
11622 sum = 0L;
11623 for (i = 0; i < words; i++, s_addr += 2) {
11624 sum += AscReadLramWord(iop_base, s_addr);
11625 }
11626 return (sum);
1da177e4
LT
11627}
11628
27c868c2
MW
11629static void
11630AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
1da177e4 11631{
27c868c2 11632 int i;
1da177e4 11633
27c868c2
MW
11634 AscSetChipLramAddr(iop_base, s_addr);
11635 for (i = 0; i < words; i++) {
11636 AscSetChipLramData(iop_base, set_wval);
11637 }
11638 return;
1da177e4
LT
11639}
11640
1da177e4
LT
11641/*
11642 * --- Adv Library Functions
11643 */
11644
11645/* a_mcode.h */
11646
11647/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
11648static unsigned char _adv_asc3550_buf[] = {
11649 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
11650 0x01, 0x00, 0x48, 0xe4,
11651 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff,
11652 0x28, 0x0e, 0x9e, 0xe7,
11653 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7,
11654 0x55, 0xf0, 0x01, 0xf6,
11655 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
11656 0x00, 0xec, 0x85, 0xf0,
11657 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0,
11658 0x86, 0xf0, 0xb4, 0x00,
11659 0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00,
11660 0xaa, 0x18, 0x02, 0x80,
11661 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
11662 0x00, 0x57, 0x01, 0xea,
11663 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80,
11664 0x03, 0xe6, 0xb6, 0x00,
11665 0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12,
11666 0x02, 0x4a, 0xb9, 0x54,
11667 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
11668 0x3e, 0x00, 0x80, 0x00,
11669 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
11670 0x74, 0x01, 0x76, 0x01,
11671 0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13,
11672 0x4c, 0x1c, 0xbb, 0x55,
11673 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
11674 0x03, 0xf7, 0x06, 0xf7,
11675 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08,
11676 0x30, 0x13, 0x64, 0x15,
11677 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c,
11678 0x04, 0xea, 0x5d, 0xf0,
11679 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
11680 0xcc, 0x00, 0x20, 0x01,
11681 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13,
11682 0x40, 0x13, 0x30, 0x1c,
11683 0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
11684 0x59, 0xf0, 0xa7, 0xf0,
11685 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
11686 0xa4, 0x00, 0xb5, 0x00,
11687 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a,
11688 0x14, 0x0e, 0x02, 0x10,
11689 0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13,
11690 0x10, 0x15, 0x14, 0x15,
11691 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
11692 0x91, 0x44, 0x0a, 0x45,
11693 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58,
11694 0x83, 0x59, 0x05, 0xe6,
11695 0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8,
11696 0x02, 0xfa, 0x03, 0xfa,
11697 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
11698 0x9e, 0x00, 0xa8, 0x00,
11699 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01,
11700 0x7a, 0x01, 0xc0, 0x01,
11701 0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08,
11702 0x69, 0x08, 0xba, 0x08,
11703 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
11704 0xf1, 0x10, 0x06, 0x12,
11705 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14,
11706 0x8a, 0x15, 0xc6, 0x17,
11707 0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
11708 0x0e, 0x47, 0x48, 0x47,
11709 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
11710 0x14, 0x56, 0x77, 0x57,
11711 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c,
11712 0xf0, 0x29, 0x02, 0xfe,
11713 0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf,
11714 0xfe, 0x80, 0x01, 0xff,
11715 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
11716 0x00, 0xfe, 0x57, 0x24,
11717 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09,
11718 0x00, 0x00, 0xff, 0x08,
11719 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
11720 0xff, 0xff, 0xff, 0x0f,
11721 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
11722 0xfe, 0x04, 0xf7, 0xcf,
11723 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67,
11724 0x0b, 0x3c, 0x2a, 0xfe,
11725 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0,
11726 0xfe, 0xf0, 0x01, 0xfe,
11727 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
11728 0x02, 0xfe, 0xd4, 0x0c,
11729 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
11730 0x1c, 0x05, 0xfe, 0xa6,
11731 0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48,
11732 0xf0, 0xfe, 0x86, 0x02,
11733 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
11734 0xfe, 0x46, 0xf0, 0xfe,
11735 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
11736 0x44, 0x02, 0xfe, 0x44,
11737 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b,
11738 0xa0, 0x17, 0x06, 0x18,
11739 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
11740 0x1e, 0x1c, 0xfe, 0xe9,
11741 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7,
11742 0x0a, 0x6b, 0x01, 0x9e,
11743 0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b,
11744 0x01, 0x82, 0xfe, 0xbd,
11745 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
11746 0x58, 0x1c, 0x17, 0x06,
11747 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21,
11748 0xfe, 0x94, 0x02, 0xfe,
11749 0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97,
11750 0x01, 0xfe, 0x54, 0x0f,
11751 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
11752 0x69, 0x10, 0x17, 0x06,
11753 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05,
11754 0xf6, 0xc7, 0x01, 0xfe,
11755 0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6,
11756 0x02, 0x29, 0x0a, 0x40,
11757 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
11758 0x58, 0x0a, 0x99, 0x01,
11759 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29,
11760 0x2a, 0x46, 0xfe, 0x02,
11761 0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc,
11762 0x01, 0xfe, 0x07, 0x4b,
11763 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
11764 0xfe, 0x56, 0x03, 0xfe,
11765 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10,
11766 0xfe, 0x9f, 0xf0, 0xfe,
11767 0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48,
11768 0x1c, 0xeb, 0x09, 0x04,
11769 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
11770 0x01, 0x0e, 0xac, 0x75,
11771 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2,
11772 0xfe, 0x82, 0xf0, 0xfe,
11773 0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25,
11774 0x32, 0x1f, 0xfe, 0xb4,
11775 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
11776 0x0a, 0xf0, 0xfe, 0x7a,
11777 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c,
11778 0x01, 0x33, 0x8f, 0xfe,
11779 0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8,
11780 0xf7, 0xfe, 0x48, 0x1c,
11781 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
11782 0x0a, 0xca, 0x01, 0x0e,
11783 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14,
11784 0x2c, 0x01, 0x33, 0x8f,
11785 0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65,
11786 0xfe, 0x3c, 0x04, 0x1f,
11787 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
11788 0x12, 0x2b, 0xff, 0x02,
11789 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f,
11790 0x22, 0x30, 0x2e, 0xd5,
11791 0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c,
11792 0xfe, 0x4c, 0x54, 0x64,
11793 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
11794 0xfe, 0x2a, 0x13, 0x2f,
11795 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
11796 0xd3, 0xfa, 0xef, 0x86,
11797 0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04,
11798 0x1d, 0xfe, 0x1c, 0x12,
11799 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
11800 0x70, 0x0c, 0x02, 0x22,
11801 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92,
11802 0x01, 0x33, 0x02, 0x29,
11803 0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87,
11804 0x80, 0xfe, 0x31, 0xe4,
11805 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
11806 0xfe, 0x70, 0x12, 0x49,
11807 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe,
11808 0x80, 0x05, 0xfe, 0x31,
11809 0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00,
11810 0x28, 0xfe, 0x42, 0x12,
11811 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
11812 0x11, 0xfe, 0xe3, 0x00,
11813 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
11814 0x64, 0x05, 0x83, 0x24,
11815 0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe,
11816 0x09, 0x48, 0x01, 0x08,
11817 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
11818 0x86, 0x24, 0x06, 0x12,
11819 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47,
11820 0x01, 0xa7, 0x14, 0x92,
11821 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c,
11822 0x02, 0x22, 0x05, 0xfe,
11823 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
11824 0x47, 0x01, 0xa7, 0x26,
11825 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f,
11826 0x01, 0xfe, 0xaa, 0x14,
11827 0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00,
11828 0x05, 0x50, 0xb4, 0x0c,
11829 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
11830 0x13, 0x01, 0xfe, 0x14,
11831 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c,
11832 0xff, 0x02, 0x00, 0x57,
11833 0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe,
11834 0x72, 0x06, 0x49, 0x04,
11835 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
11836 0x06, 0x11, 0x9a, 0x01,
11837 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06,
11838 0x01, 0xa7, 0xec, 0x72,
11839 0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32,
11840 0xfe, 0x0a, 0xf0, 0xfe,
11841 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
11842 0x8d, 0x81, 0x02, 0x22,
11843 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00,
11844 0x01, 0x08, 0x15, 0x00,
11845 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15,
11846 0x00, 0x02, 0xfe, 0x32,
11847 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
11848 0xfe, 0x1b, 0x00, 0x01,
11849 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
11850 0x08, 0x15, 0x06, 0x01,
11851 0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe,
11852 0x9a, 0x81, 0x4b, 0x1d,
11853 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
11854 0x45, 0xfe, 0x32, 0x12,
11855 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0,
11856 0xfe, 0x32, 0x07, 0x8d,
11857 0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a,
11858 0x06, 0x15, 0x19, 0x02,
11859 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
11860 0x90, 0x77, 0xfe, 0xca,
11861 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07,
11862 0x10, 0xfe, 0x0e, 0x12,
11863 0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe,
11864 0x83, 0xe7, 0xc4, 0xa1,
11865 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
11866 0x40, 0x12, 0x58, 0x01,
11867 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6,
11868 0x51, 0x83, 0xfb, 0xfe,
11869 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90,
11870 0xfe, 0x40, 0x50, 0xfe,
11871 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
11872 0xfe, 0x2a, 0x12, 0xfe,
11873 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f,
11874 0x85, 0x01, 0xa8, 0xfe,
11875 0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56,
11876 0x18, 0x57, 0xfb, 0xfe,
11877 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
11878 0x0c, 0x39, 0x18, 0x3a,
11879 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e,
11880 0x11, 0x65, 0xfe, 0x48,
11881 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73,
11882 0xdd, 0xb8, 0xfe, 0x80,
11883 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
11884 0xfe, 0x7a, 0x08, 0x8d,
11885 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9,
11886 0x10, 0x61, 0x04, 0x06,
11887 0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68,
11888 0x12, 0xfe, 0x2e, 0x1c,
11889 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
11890 0x52, 0x12, 0xfe, 0x2c,
11891 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe,
11892 0x08, 0xfe, 0x8a, 0x10,
11893 0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe,
11894 0x24, 0x0a, 0xab, 0xfe,
11895 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
11896 0x1c, 0x12, 0xb5, 0xfe,
11897 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb,
11898 0x1c, 0x06, 0x16, 0x9d,
11899 0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b,
11900 0x14, 0x92, 0x01, 0x33,
11901 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
11902 0xfe, 0x74, 0x18, 0x1c,
11903 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b,
11904 0x01, 0xe6, 0x1e, 0x27,
11905 0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a,
11906 0x09, 0x04, 0x6a, 0xfe,
11907 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
11908 0xfe, 0x83, 0x80, 0xfe,
11909 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63,
11910 0x27, 0xfe, 0x40, 0x59,
11911 0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18,
11912 0x7c, 0xbe, 0x54, 0xbf,
11913 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
11914 0x79, 0x56, 0x68, 0x57,
11915 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5,
11916 0xa2, 0x23, 0x0c, 0x7b,
11917 0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19,
11918 0x16, 0xd7, 0x79, 0x39,
11919 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
11920 0xfe, 0x10, 0x58, 0xfe,
11921 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04,
11922 0x19, 0x16, 0xd7, 0x09,
11923 0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f,
11924 0xfe, 0x10, 0x90, 0xfe,
11925 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
11926 0x11, 0x9b, 0x09, 0x04,
11927 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08,
11928 0xfe, 0x0c, 0x58, 0xfe,
11929 0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04,
11930 0x0b, 0xfe, 0x1a, 0x12,
11931 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
11932 0x14, 0x7a, 0x01, 0x33,
11933 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39,
11934 0xfe, 0xed, 0x19, 0xbf,
11935 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff,
11936 0x34, 0xfe, 0x74, 0x10,
11937 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
11938 0x84, 0x05, 0xcb, 0x1c,
11939 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1,
11940 0xf0, 0xfe, 0xc4, 0x0a,
11941 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe,
11942 0xce, 0xf0, 0xfe, 0xca,
11943 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
11944 0x22, 0x00, 0x02, 0x5a,
11945 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a,
11946 0xfe, 0xd0, 0xf0, 0xfe,
11947 0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f,
11948 0x4c, 0xfe, 0x10, 0x10,
11949 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
11950 0x2a, 0x13, 0xfe, 0x4e,
11951 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1,
11952 0x16, 0x32, 0x2a, 0x73,
11953 0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25,
11954 0x32, 0x8c, 0xfe, 0x48,
11955 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
11956 0xdb, 0x10, 0x11, 0xfe,
11957 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0,
11958 0x22, 0x30, 0x2e, 0xd8,
11959 0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1,
11960 0x45, 0x0f, 0xfe, 0x42,
11961 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
11962 0x09, 0x04, 0x0b, 0xfe,
11963 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28,
11964 0x00, 0x21, 0xfe, 0xa6,
11965 0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00,
11966 0xfe, 0xe2, 0x10, 0x01,
11967 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
11968 0x01, 0x6f, 0x02, 0x29,
11969 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10,
11970 0x01, 0x86, 0x3e, 0x0b,
11971 0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3,
11972 0x3e, 0x0b, 0x0f, 0xfe,
11973 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
11974 0xe8, 0x59, 0x11, 0x2d,
11975 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09,
11976 0x04, 0x0b, 0x84, 0x3e,
11977 0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12,
11978 0x09, 0x04, 0x1b, 0xfe,
11979 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
11980 0x1c, 0x1c, 0xfe, 0x9d,
11981 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f,
11982 0xfe, 0x15, 0x00, 0xfe,
11983 0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10,
11984 0x0f, 0xfe, 0x47, 0x00,
11985 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
11986 0xab, 0x70, 0x05, 0x6b,
11987 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe,
11988 0x1c, 0x42, 0x59, 0x01,
11989 0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31,
11990 0x00, 0x37, 0x97, 0x01,
11991 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
11992 0x1d, 0xfe, 0xce, 0x45,
11993 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75,
11994 0x57, 0x05, 0x51, 0xfe,
11995 0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48,
11996 0x46, 0x09, 0x04, 0x1d,
11997 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
11998 0x99, 0x01, 0x0e, 0xfe,
11999 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51,
12000 0xfe, 0xee, 0x14, 0xee,
12001 0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad,
12002 0x13, 0x02, 0x29, 0x1e,
12003 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
12004 0xce, 0x1e, 0x2d, 0x47,
12005 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06,
12006 0x12, 0x4d, 0x01, 0xfe,
12007 0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe,
12008 0xf0, 0x0d, 0xfe, 0x02,
12009 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
12010 0xf6, 0xfe, 0x34, 0x01,
12011 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13,
12012 0xaf, 0xfe, 0x02, 0xea,
12013 0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c,
12014 0x05, 0xfe, 0x38, 0x01,
12015 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
12016 0x0c, 0xfe, 0x62, 0x01,
12017 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06,
12018 0x03, 0x23, 0x03, 0x1e,
12019 0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe,
12020 0x71, 0x13, 0xfe, 0x24,
12021 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
12022 0xdc, 0xfe, 0x73, 0x57,
12023 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe,
12024 0x80, 0x5d, 0x03, 0xfe,
12025 0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6,
12026 0x75, 0x03, 0x09, 0x04,
12027 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
12028 0xfe, 0x1e, 0x80, 0xe1,
12029 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e,
12030 0x90, 0xa3, 0xfe, 0x3c,
12031 0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82,
12032 0x16, 0x2f, 0x07, 0x2d,
12033 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
12034 0xe8, 0x11, 0xfe, 0xe9,
12035 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe,
12036 0x1e, 0x1c, 0xfe, 0x14,
12037 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01,
12038 0x09, 0x04, 0x4f, 0xfe,
12039 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
12040 0x40, 0x12, 0x20, 0x63,
12041 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08,
12042 0x1c, 0x05, 0xfe, 0xac,
12043 0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05,
12044 0xfe, 0xb0, 0x00, 0xfe,
12045 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
12046 0x24, 0x69, 0x12, 0xc9,
12047 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe,
12048 0x90, 0x4d, 0xfe, 0x91,
12049 0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c,
12050 0xfe, 0x90, 0x4d, 0xfe,
12051 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
12052 0x46, 0x1e, 0x20, 0xed,
12053 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea,
12054 0x70, 0xfe, 0x14, 0x1c,
12055 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee,
12056 0xfe, 0x07, 0xe6, 0x1d,
12057 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
12058 0xfa, 0xef, 0xfe, 0x42,
12059 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0,
12060 0xfe, 0x36, 0x12, 0xf0,
12061 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
12062 0x3d, 0x75, 0x07, 0x10,
12063 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
12064 0x10, 0x07, 0x7e, 0x45,
12065 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74,
12066 0xfe, 0x01, 0xec, 0x97,
12067 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76,
12068 0x27, 0x01, 0xda, 0xfe,
12069 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
12070 0xfe, 0x48, 0x12, 0x07,
12071 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16,
12072 0xfe, 0x3e, 0x11, 0x07,
12073 0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8,
12074 0x11, 0x07, 0x19, 0xfe,
12075 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
12076 0x01, 0x08, 0x8c, 0x43,
12077 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11,
12078 0x7e, 0x02, 0x29, 0x2b,
12079 0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe,
12080 0xfc, 0x10, 0x09, 0x04,
12081 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
12082 0xc6, 0x10, 0x1e, 0x58,
12083 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c,
12084 0x54, 0x18, 0x55, 0x23,
12085 0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01,
12086 0xa5, 0xc0, 0x38, 0xc1,
12087 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
12088 0x05, 0xfa, 0x4e, 0xfe,
12089 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56,
12090 0x0c, 0x56, 0x18, 0x57,
12091 0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe,
12092 0x00, 0x56, 0xfe, 0xa1,
12093 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
12094 0x58, 0xfe, 0x1f, 0x40,
12095 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56,
12096 0x31, 0x57, 0xfe, 0x44,
12097 0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe,
12098 0x8a, 0x50, 0x05, 0x39,
12099 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
12100 0x12, 0xcd, 0x02, 0x5b,
12101 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44,
12102 0x2f, 0x07, 0x9b, 0x21,
12103 0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79,
12104 0x39, 0x68, 0x3a, 0xfe,
12105 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
12106 0x51, 0xfe, 0x8e, 0x51,
12107 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b,
12108 0x01, 0x08, 0x25, 0x32,
12109 0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b,
12110 0x3b, 0x02, 0x44, 0x01,
12111 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
12112 0x01, 0x08, 0x1f, 0xa2,
12113 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c,
12114 0x00, 0x28, 0x84, 0x49,
12115 0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06,
12116 0x78, 0x3d, 0xfe, 0xda,
12117 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
12118 0x05, 0xc6, 0x28, 0x84,
12119 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8,
12120 0x14, 0xfe, 0x03, 0x17,
12121 0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01,
12122 0xfe, 0xaa, 0x14, 0x02,
12123 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
12124 0x21, 0x44, 0x01, 0xfe,
12125 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87,
12126 0xfe, 0x4a, 0xf4, 0x0b,
12127 0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a,
12128 0x85, 0x02, 0x5b, 0x05,
12129 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
12130 0xd8, 0x14, 0x02, 0x5c,
12131 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1,
12132 0x01, 0x08, 0x23, 0x72,
12133 0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca,
12134 0x12, 0x5e, 0x2b, 0x01,
12135 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
12136 0x1c, 0xfe, 0xff, 0x7f,
12137 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00,
12138 0x57, 0x48, 0x8b, 0x1c,
12139 0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02,
12140 0x00, 0x57, 0x48, 0x8b,
12141 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
12142 0x03, 0x0a, 0x50, 0x01,
12143 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00,
12144 0x54, 0xfe, 0x00, 0xf4,
12145 0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe,
12146 0x03, 0x7c, 0x63, 0x27,
12147 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
12148 0xfe, 0x82, 0x4a, 0xfe,
12149 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe,
12150 0x42, 0x48, 0x5f, 0x60,
12151 0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08,
12152 0x1f, 0xfe, 0xa2, 0x14,
12153 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
12154 0xcc, 0x12, 0x49, 0x04,
12155 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe,
12156 0xe8, 0x13, 0x3b, 0x13,
12157 0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55,
12158 0xa1, 0xff, 0x02, 0x83,
12159 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
12160 0x13, 0x06, 0xfe, 0x56,
12161 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe,
12162 0x64, 0x00, 0x17, 0x93,
12163 0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe,
12164 0xc8, 0x00, 0x8e, 0xe4,
12165 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
12166 0x01, 0xba, 0xfe, 0x4e,
12167 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0,
12168 0xfe, 0x60, 0x14, 0xfe,
12169 0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01,
12170 0xfe, 0x22, 0x13, 0x1c,
12171 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
12172 0xfe, 0x9c, 0x14, 0xb7,
12173 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba,
12174 0xfe, 0x9c, 0x14, 0xb7,
12175 0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06,
12176 0xfe, 0xb4, 0x56, 0xfe,
12177 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
12178 0xe5, 0x15, 0x0b, 0x01,
12179 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89,
12180 0x49, 0x01, 0x08, 0x03,
12181 0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6,
12182 0x15, 0x06, 0x01, 0x08,
12183 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
12184 0x4a, 0x01, 0x08, 0x03,
12185 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc,
12186 0xfe, 0x49, 0xf4, 0x00,
12187 0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01,
12188 0x08, 0x2f, 0x07, 0xfe,
12189 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
12190 0x01, 0x43, 0x1e, 0xcd,
12191 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e,
12192 0xed, 0x88, 0x07, 0x10,
12193 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a,
12194 0x80, 0x01, 0x0e, 0x88,
12195 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
12196 0x88, 0x03, 0x0a, 0x42,
12197 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e,
12198 0xfe, 0x80, 0x80, 0xf2,
12199 0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51,
12200 0x01, 0x82, 0x03, 0x17,
12201 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
12202 0xfe, 0x24, 0x1c, 0xfe,
12203 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0,
12204 0x91, 0x1d, 0x66, 0xfe,
12205 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe,
12206 0xda, 0x10, 0x17, 0x10,
12207 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
12208 0x05, 0xfe, 0x66, 0x01,
12209 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06,
12210 0xfe, 0x3c, 0x50, 0x66,
12211 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe,
12212 0x40, 0x16, 0xfe, 0xb6,
12213 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
12214 0x10, 0x71, 0xfe, 0x83,
12215 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90,
12216 0xfe, 0x62, 0x16, 0xfe,
12217 0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19,
12218 0xfe, 0x98, 0xe7, 0x00,
12219 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
12220 0xfe, 0x30, 0xbc, 0xfe,
12221 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
12222 0xc5, 0x90, 0xfe, 0x9a,
12223 0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe,
12224 0x42, 0x10, 0xfe, 0x02,
12225 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
12226 0xfe, 0x1d, 0xf7, 0x4f,
12227 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f,
12228 0x47, 0xfe, 0x83, 0x58,
12229 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11,
12230 0xfe, 0xdd, 0x00, 0x63,
12231 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
12232 0x06, 0x37, 0x95, 0xa9,
12233 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e,
12234 0x18, 0x1c, 0x1a, 0x5d,
12235 0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe,
12236 0xe1, 0x10, 0x78, 0x2c,
12237 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
12238 0x13, 0x3c, 0x8a, 0x0a,
12239 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
12240 0xe3, 0xfe, 0x00, 0xcc,
12241 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01,
12242 0x0e, 0xf2, 0x01, 0x6f,
12243 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
12244 0xf6, 0xfe, 0xd6, 0xf0,
12245 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe,
12246 0x15, 0x00, 0x59, 0x76,
12247 0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35,
12248 0x11, 0x2d, 0x01, 0x6f,
12249 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
12250 0xc8, 0xfe, 0x48, 0x55,
12251 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a,
12252 0x99, 0x01, 0x0e, 0xf0,
12253 0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73,
12254 0x75, 0x03, 0x0a, 0x42,
12255 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
12256 0x0e, 0x73, 0x75, 0x03,
12257 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00,
12258 0xfe, 0x3a, 0x45, 0x5b,
12259 0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00,
12260 0xfe, 0x02, 0xe6, 0x1b,
12261 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
12262 0xfe, 0x94, 0x00, 0xfe,
12263 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02,
12264 0xe6, 0x2c, 0xfe, 0x4e,
12265 0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69,
12266 0x03, 0x07, 0x7a, 0xfe,
12267 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
12268 0x07, 0x1b, 0xfe, 0x5a,
12269 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d,
12270 0x24, 0x2c, 0xdc, 0x07,
12271 0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d,
12272 0x9f, 0xad, 0x03, 0x14,
12273 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
12274 0x03, 0x25, 0xfe, 0xca,
12275 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a,
12276 0x00, 0x00,
1da177e4
LT
12277};
12278
27c868c2
MW
12279static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
12280static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
1da177e4
LT
12281
12282/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
12283static unsigned char _adv_asc38C0800_buf[] = {
12284 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
12285 0x01, 0x00, 0x48, 0xe4,
12286 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff,
12287 0x1c, 0x0f, 0x00, 0xf6,
12288 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6,
12289 0x09, 0xe7, 0x55, 0xf0,
12290 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
12291 0x18, 0xf4, 0x08, 0x00,
12292 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6,
12293 0x86, 0xf0, 0xb1, 0xf0,
12294 0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c,
12295 0x3c, 0x00, 0xbb, 0x00,
12296 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
12297 0xba, 0x13, 0x18, 0x40,
12298 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01,
12299 0x6e, 0x01, 0x74, 0x01,
12300 0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00,
12301 0xc0, 0x00, 0x01, 0x01,
12302 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
12303 0x08, 0x12, 0x02, 0x4a,
12304 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4,
12305 0x5d, 0xf0, 0x02, 0xfa,
12306 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01,
12307 0x68, 0x01, 0x6a, 0x01,
12308 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
12309 0x06, 0x13, 0x4c, 0x1c,
12310 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00,
12311 0x0f, 0x00, 0x47, 0x00,
12312 0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c,
12313 0x4e, 0x1c, 0x10, 0x44,
12314 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
12315 0x05, 0x00, 0x34, 0x00,
12316 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b,
12317 0x42, 0x0c, 0x12, 0x0f,
12318 0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48,
12319 0x00, 0x4e, 0x42, 0x54,
12320 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
12321 0x59, 0xf0, 0xb8, 0xf0,
12322 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00,
12323 0x19, 0x00, 0x33, 0x00,
12324 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00,
12325 0xe7, 0x00, 0xe2, 0x03,
12326 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
12327 0x12, 0x13, 0x24, 0x14,
12328 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c,
12329 0x36, 0x1c, 0x08, 0x44,
12330 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54,
12331 0x3a, 0x55, 0x83, 0x55,
12332 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
12333 0x0c, 0xf0, 0x04, 0xf8,
12334 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00,
12335 0xa8, 0x00, 0xaa, 0x00,
12336 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01,
12337 0xc4, 0x01, 0xc6, 0x01,
12338 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
12339 0x68, 0x08, 0x69, 0x08,
12340 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10,
12341 0xed, 0x10, 0xf1, 0x10,
12342 0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13,
12343 0x1e, 0x13, 0x46, 0x14,
12344 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
12345 0xca, 0x18, 0xe6, 0x19,
12346 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c,
12347 0xf0, 0x2b, 0x02, 0xfe,
12348 0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6,
12349 0xfe, 0x84, 0x01, 0xff,
12350 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
12351 0x00, 0xfe, 0x57, 0x24,
12352 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09,
12353 0x00, 0x00, 0xff, 0x08,
12354 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
12355 0xff, 0xff, 0xff, 0x11,
12356 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
12357 0xfe, 0x04, 0xf7, 0xd6,
12358 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99,
12359 0x0a, 0x42, 0x2c, 0xfe,
12360 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0,
12361 0xfe, 0xf4, 0x01, 0xfe,
12362 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
12363 0x02, 0xfe, 0xc8, 0x0d,
12364 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
12365 0x1c, 0x03, 0xfe, 0xa6,
12366 0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48,
12367 0xf0, 0xfe, 0x8a, 0x02,
12368 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
12369 0xfe, 0x46, 0xf0, 0xfe,
12370 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
12371 0x48, 0x02, 0xfe, 0x44,
12372 0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a,
12373 0xaa, 0x18, 0x06, 0x14,
12374 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
12375 0x1e, 0x1c, 0xfe, 0xe9,
12376 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce,
12377 0x09, 0x70, 0x01, 0xa8,
12378 0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70,
12379 0x01, 0x87, 0xfe, 0xbd,
12380 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
12381 0x58, 0x1c, 0x18, 0x06,
12382 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23,
12383 0xfe, 0x98, 0x02, 0xfe,
12384 0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2,
12385 0x01, 0xfe, 0x48, 0x10,
12386 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
12387 0x69, 0x10, 0x18, 0x06,
12388 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05,
12389 0xf6, 0xce, 0x01, 0xfe,
12390 0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe,
12391 0x82, 0x16, 0x02, 0x2b,
12392 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
12393 0xfe, 0x41, 0x58, 0x09,
12394 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe,
12395 0x82, 0x16, 0x02, 0x2b,
12396 0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43,
12397 0xfe, 0x77, 0x57, 0xfe,
12398 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
12399 0xfe, 0x40, 0x1c, 0x1c,
12400 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48,
12401 0x03, 0xfe, 0x11, 0xf0,
12402 0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10,
12403 0xfe, 0x11, 0x00, 0x02,
12404 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
12405 0x21, 0x22, 0xa3, 0xb7,
12406 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16,
12407 0x12, 0xd1, 0x1c, 0xd9,
12408 0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12,
12409 0xfe, 0xe4, 0x00, 0x27,
12410 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
12411 0x06, 0xf0, 0xfe, 0xc8,
12412 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03,
12413 0x70, 0x28, 0x17, 0xfe,
12414 0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8,
12415 0xf9, 0x2c, 0x99, 0x19,
12416 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
12417 0x74, 0x01, 0xaf, 0x8c,
12418 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e,
12419 0x8d, 0x51, 0x64, 0x79,
12420 0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b,
12421 0xfe, 0x6a, 0x02, 0x02,
12422 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
12423 0xfe, 0x3c, 0x04, 0x3b,
12424 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02,
12425 0x00, 0x10, 0x01, 0x0b,
12426 0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde,
12427 0xfe, 0x4c, 0x44, 0xfe,
12428 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
12429 0xda, 0x4f, 0x79, 0x2a,
12430 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b,
12431 0xfe, 0x2a, 0x13, 0x32,
12432 0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c,
12433 0x54, 0x6b, 0xda, 0xfe,
12434 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
12435 0x08, 0x13, 0x32, 0x07,
12436 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d,
12437 0x08, 0x05, 0x06, 0x4d,
12438 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24,
12439 0x2d, 0x12, 0xfe, 0xe6,
12440 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
12441 0x02, 0x2b, 0xfe, 0x42,
12442 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
12443 0xfe, 0x87, 0x80, 0xfe,
12444 0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80,
12445 0x07, 0x19, 0xfe, 0x7c,
12446 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
12447 0x17, 0xfe, 0x90, 0x05,
12448 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe,
12449 0xa0, 0x00, 0x28, 0xfe,
12450 0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c,
12451 0x34, 0xfe, 0x89, 0x48,
12452 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
12453 0x12, 0xfe, 0xe3, 0x00,
12454 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
12455 0x70, 0x05, 0x88, 0x25,
12456 0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe,
12457 0x09, 0x48, 0xff, 0x02,
12458 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
12459 0x08, 0x53, 0x05, 0xcb,
12460 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08,
12461 0x05, 0x1b, 0xfe, 0x22,
12462 0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe,
12463 0x0d, 0x00, 0x01, 0x36,
12464 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
12465 0x03, 0x5c, 0x28, 0xfe,
12466 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53,
12467 0x05, 0x1f, 0xfe, 0x02,
12468 0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5,
12469 0x01, 0x4b, 0x12, 0xfe,
12470 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
12471 0x12, 0x03, 0x45, 0x28,
12472 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe,
12473 0x43, 0x48, 0xc4, 0xcc,
12474 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4,
12475 0x6e, 0x41, 0x01, 0xb2,
12476 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
12477 0xfe, 0xcc, 0x15, 0x1d,
12478 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03,
12479 0x45, 0xc1, 0x0c, 0x45,
12480 0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe,
12481 0xe2, 0x00, 0x27, 0xdb,
12482 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
12483 0xfe, 0x06, 0xf0, 0xfe,
12484 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12,
12485 0x16, 0x19, 0x01, 0x0b,
12486 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
12487 0xfe, 0x99, 0xa4, 0x01,
12488 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
12489 0x12, 0x08, 0x05, 0x1a,
12490 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
12491 0x0b, 0x16, 0x00, 0x01,
12492 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02,
12493 0xe2, 0x6c, 0x58, 0xbe,
12494 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
12495 0xfe, 0x09, 0x6f, 0xba,
12496 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27,
12497 0xfe, 0x54, 0x07, 0x1c,
12498 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c,
12499 0x07, 0x02, 0x24, 0x01,
12500 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
12501 0x2c, 0x90, 0xfe, 0xae,
12502 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a,
12503 0x37, 0x22, 0x20, 0x07,
12504 0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a,
12505 0xfe, 0x06, 0x10, 0xfe,
12506 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
12507 0x37, 0x01, 0xb3, 0xb8,
12508 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a,
12509 0x50, 0xfe, 0x44, 0x51,
12510 0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e,
12511 0x14, 0x5f, 0xfe, 0x0c,
12512 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
12513 0x14, 0x3e, 0xfe, 0x4a,
12514 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
12515 0x90, 0x0c, 0x60, 0x14,
12516 0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62,
12517 0xfe, 0x44, 0x90, 0xfe,
12518 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
12519 0x0c, 0x5e, 0x14, 0x5f,
12520 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e,
12521 0x14, 0x3c, 0x21, 0x0c,
12522 0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11,
12523 0x27, 0xdd, 0xfe, 0x9e,
12524 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
12525 0x9a, 0x08, 0xc6, 0xfe,
12526 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08,
12527 0x95, 0x86, 0x02, 0x24,
12528 0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05,
12529 0x06, 0xfe, 0x10, 0x12,
12530 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
12531 0x1c, 0x02, 0xfe, 0x18,
12532 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe,
12533 0x2c, 0x1c, 0xfe, 0xaa,
12534 0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe,
12535 0xde, 0x09, 0xfe, 0xb7,
12536 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
12537 0xfe, 0xf1, 0x18, 0xfe,
12538 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe,
12539 0x14, 0x59, 0xfe, 0x95,
12540 0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0,
12541 0xfe, 0xf0, 0x08, 0xb5,
12542 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
12543 0x0b, 0xb6, 0xfe, 0xbf,
12544 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c,
12545 0x12, 0xc2, 0xfe, 0xd2,
12546 0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e,
12547 0x06, 0x17, 0x85, 0xc5,
12548 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
12549 0x9d, 0x01, 0x36, 0x10,
12550 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe,
12551 0x98, 0x80, 0xfe, 0x19,
12552 0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18,
12553 0xfe, 0x44, 0x54, 0xbe,
12554 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
12555 0x02, 0x4a, 0x08, 0x05,
12556 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e,
12557 0x9c, 0x3c, 0xfe, 0x6c,
12558 0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f,
12559 0x3b, 0x40, 0x03, 0x49,
12560 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
12561 0x8f, 0xfe, 0xe3, 0x54,
12562 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe,
12563 0xda, 0x09, 0xfe, 0x8b,
12564 0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa,
12565 0x0a, 0x3a, 0x49, 0x3b,
12566 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
12567 0xad, 0xfe, 0x01, 0x59,
12568 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a,
12569 0x49, 0x8f, 0xfe, 0xe3,
12570 0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02,
12571 0x4a, 0x3a, 0x49, 0x3b,
12572 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
12573 0x02, 0x4a, 0x08, 0x05,
12574 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62,
12575 0xb7, 0xfe, 0x03, 0xa1,
12576 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
12577 0xfe, 0x86, 0x91, 0x6a,
12578 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
12579 0x61, 0x0c, 0x7f, 0x14,
12580 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62,
12581 0x9b, 0x2e, 0x9c, 0x3c,
12582 0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05,
12583 0xfa, 0x3c, 0x01, 0xef,
12584 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
12585 0xe4, 0x08, 0x05, 0x1f,
12586 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37,
12587 0x03, 0x5e, 0x29, 0x5f,
12588 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe,
12589 0xf4, 0x09, 0x08, 0x05,
12590 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
12591 0x81, 0x50, 0xfe, 0x10,
12592 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe,
12593 0x08, 0x09, 0x12, 0xa6,
12594 0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe,
12595 0x08, 0x09, 0xfe, 0x0c,
12596 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
12597 0x08, 0x05, 0x0a, 0xfe,
12598 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1,
12599 0xf0, 0xe2, 0x15, 0x7e,
12600 0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19,
12601 0x57, 0x3d, 0xfe, 0xed,
12602 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
12603 0x00, 0xff, 0x35, 0xfe,
12604 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18,
12605 0x1e, 0x19, 0x8a, 0x03,
12606 0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65,
12607 0xfe, 0xd1, 0xf0, 0xfe,
12608 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
12609 0x10, 0xfe, 0xce, 0xf0,
12610 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b,
12611 0x10, 0xfe, 0x22, 0x00,
12612 0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00,
12613 0x02, 0x65, 0xfe, 0xd0,
12614 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
12615 0x0b, 0x10, 0x58, 0xfe,
12616 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe,
12617 0x12, 0x00, 0x2c, 0x0f,
12618 0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14,
12619 0x0c, 0xbc, 0x17, 0x34,
12620 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
12621 0x0c, 0x1c, 0x34, 0x94,
12622 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01,
12623 0x4b, 0xfe, 0xdb, 0x10,
12624 0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe,
12625 0x89, 0xf0, 0x24, 0x33,
12626 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
12627 0x33, 0x31, 0xdf, 0xbc,
12628 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49,
12629 0x17, 0xfe, 0x2c, 0x0d,
12630 0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54,
12631 0x12, 0x55, 0xfe, 0x28,
12632 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
12633 0x44, 0xfe, 0x28, 0x00,
12634 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26,
12635 0x0f, 0x64, 0x12, 0x2f,
12636 0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44,
12637 0x0a, 0xfe, 0xb4, 0x10,
12638 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
12639 0xfe, 0x34, 0x46, 0xac,
12640 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a,
12641 0x37, 0x01, 0xf5, 0x01,
12642 0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02,
12643 0xfe, 0x2e, 0x03, 0x08,
12644 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
12645 0x1a, 0xfe, 0x58, 0x12,
12646 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
12647 0xfe, 0x50, 0x0d, 0xfe,
12648 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37,
12649 0xfe, 0xa9, 0x10, 0x10,
12650 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
12651 0xfe, 0x13, 0x00, 0xfe,
12652 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe,
12653 0x24, 0x00, 0x8c, 0xb5,
12654 0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a,
12655 0xfe, 0x9d, 0x41, 0xfe,
12656 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
12657 0xb4, 0x15, 0xfe, 0x31,
12658 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06,
12659 0xec, 0xd0, 0xfc, 0x44,
12660 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47,
12661 0x4b, 0x91, 0xfe, 0x75,
12662 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
12663 0x0e, 0xfe, 0x44, 0x48,
12664 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41,
12665 0xfe, 0x41, 0x58, 0x09,
12666 0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe,
12667 0x2e, 0x03, 0x09, 0x5d,
12668 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
12669 0xce, 0x47, 0xfe, 0xad,
12670 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13,
12671 0x59, 0x13, 0x9f, 0x13,
12672 0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe,
12673 0xe0, 0x0e, 0x0f, 0x06,
12674 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
12675 0x3a, 0x01, 0x56, 0xfe,
12676 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec,
12677 0x20, 0x4f, 0xfe, 0x05,
12678 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe,
12679 0x48, 0xf4, 0x0d, 0xfe,
12680 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
12681 0x15, 0x1a, 0x39, 0xa0,
12682 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff,
12683 0x0c, 0xfe, 0x60, 0x01,
12684 0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25,
12685 0x06, 0x13, 0x2f, 0x12,
12686 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
12687 0x22, 0x9f, 0xb7, 0x13,
12688 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39,
12689 0xa0, 0xb4, 0xfe, 0xd9,
12690 0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04,
12691 0xc3, 0xfe, 0x03, 0xdc,
12692 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
12693 0xfe, 0x00, 0xcc, 0x04,
12694 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13,
12695 0xfe, 0x1c, 0x80, 0x07,
12696 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae,
12697 0xfe, 0x0c, 0x90, 0xfe,
12698 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
12699 0x0a, 0xfe, 0x3c, 0x50,
12700 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4,
12701 0x16, 0x08, 0x05, 0x1b,
12702 0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58,
12703 0xfe, 0x2c, 0x13, 0x01,
12704 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
12705 0x0c, 0xfe, 0x64, 0x01,
12706 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03,
12707 0x80, 0x8d, 0xfe, 0x01,
12708 0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64,
12709 0x22, 0x20, 0xfb, 0x79,
12710 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
12711 0x03, 0xfe, 0xae, 0x00,
12712
12713 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe,
12714 0xb2, 0x00, 0xfe, 0x09,
12715 0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c,
12716 0x45, 0x0f, 0x46, 0x52,
12717 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
12718 0x0f, 0x44, 0x11, 0x0f,
12719 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4,
12720 0x25, 0x11, 0x13, 0x20,
12721 0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14,
12722 0x56, 0xfe, 0xd6, 0xf0,
12723 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
12724 0x18, 0x1c, 0x04, 0x42,
12725 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe,
12726 0xf5, 0x13, 0x04, 0x01,
12727 0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
12728 0x13, 0x32, 0x07, 0x2f,
12729 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
12730 0x41, 0x48, 0xfe, 0x45,
12731 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78,
12732 0x07, 0x11, 0xac, 0x09,
12733 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07,
12734 0x82, 0x4e, 0xfe, 0x14,
12735 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
12736 0xfe, 0x01, 0xec, 0xa2,
12737 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79,
12738 0x2a, 0x01, 0xe3, 0xfe,
12739 0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a,
12740 0xfe, 0x48, 0x12, 0x07,
12741 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
12742 0xfe, 0x32, 0x12, 0x07,
12743 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07,
12744 0x1f, 0xfe, 0x12, 0x12,
12745 0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b,
12746 0x94, 0x4b, 0x04, 0x2d,
12747 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
12748 0x32, 0x07, 0xa6, 0xfe,
12749 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05,
12750 0x5a, 0xfe, 0x72, 0x12,
12751 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62,
12752 0xfe, 0x26, 0x13, 0x03,
12753 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
12754 0x0c, 0x7f, 0x0c, 0x80,
12755 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c,
12756 0x3c, 0xfe, 0x04, 0x55,
12757 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe,
12758 0x91, 0x10, 0x03, 0x3f,
12759 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
12760 0x88, 0x9b, 0x2e, 0x9c,
12761 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
12762 0x56, 0x0c, 0x5e, 0x14,
12763 0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40,
12764 0x03, 0x60, 0x29, 0x61,
12765 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
12766 0x50, 0xfe, 0xc6, 0x50,
12767 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d,
12768 0x29, 0x3e, 0xfe, 0x40,
12769 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72,
12770 0x2d, 0x01, 0x0b, 0x1d,
12771 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
12772 0x72, 0x01, 0xaf, 0x1e,
12773 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe,
12774 0x0a, 0x55, 0x35, 0xfe,
12775 0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51,
12776 0x02, 0x72, 0xfe, 0x19,
12777 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
12778 0x1d, 0xe8, 0x33, 0x31,
12779 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01,
12780 0x0b, 0x1c, 0x34, 0x1d,
12781 0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8,
12782 0x33, 0x31, 0xfe, 0xe8,
12783 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
12784 0x05, 0x1f, 0x35, 0xa9,
12785 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda,
12786 0x14, 0x01, 0xaf, 0x8c,
12787 0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a,
12788 0x03, 0x45, 0x28, 0x35,
12789 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
12790 0x03, 0x5c, 0xc1, 0x0c,
12791 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02,
12792 0x89, 0x01, 0x0b, 0x1c,
12793 0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1,
12794 0xfe, 0x42, 0x58, 0xf1,
12795 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
12796 0xf4, 0x06, 0xea, 0x32,
12797 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d,
12798 0x01, 0x0b, 0x26, 0x89,
12799 0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13,
12800 0x26, 0xfe, 0xd4, 0x13,
12801 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
12802 0x13, 0x1c, 0xfe, 0xd0,
12803 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10,
12804 0x0f, 0x71, 0xff, 0x02,
12805 0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe,
12806 0x00, 0x5c, 0x04, 0x0f,
12807 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
12808 0xfe, 0x00, 0x5c, 0x04,
12809 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff,
12810 0x02, 0x00, 0x57, 0x52,
12811 0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01,
12812 0x87, 0x04, 0xfe, 0x03,
12813 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
12814 0xfe, 0x00, 0x7d, 0xfe,
12815 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e,
12816 0x14, 0x5f, 0x57, 0x3f,
12817 0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83,
12818 0x5a, 0x8d, 0x04, 0x01,
12819 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
12820 0xfe, 0x96, 0x15, 0x33,
12821 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8,
12822 0x0a, 0xfe, 0xc1, 0x59,
12823 0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13,
12824 0x21, 0x69, 0x1a, 0xee,
12825 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
12826 0x30, 0xfe, 0x78, 0x10,
12827 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae,
12828 0x98, 0xfe, 0x30, 0x00,
12829 0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed,
12830 0x98, 0xfe, 0x64, 0x00,
12831 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
12832 0x10, 0x69, 0x06, 0xfe,
12833 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00,
12834 0x18, 0x59, 0x0f, 0x06,
12835 0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe,
12836 0x43, 0xf4, 0x9f, 0xfe,
12837 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
12838 0x9e, 0xfe, 0xf3, 0x10,
12839 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00,
12840 0x17, 0xfe, 0x4d, 0xe4,
12841 0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00,
12842 0x17, 0xfe, 0x4d, 0xe4,
12843 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
12844 0xf4, 0x00, 0xe9, 0x91,
12845 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a,
12846 0x04, 0x16, 0x06, 0x01,
12847 0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01,
12848 0x0b, 0x26, 0xf3, 0x76,
12849 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
12850 0x16, 0x19, 0x01, 0x0b,
12851 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01,
12852 0x0b, 0x26, 0xb1, 0x76,
12853 0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06,
12854 0xfe, 0x48, 0x13, 0xb8,
12855 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
12856 0xec, 0xfe, 0x27, 0x01,
12857 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32,
12858 0x07, 0xfe, 0xe3, 0x00,
12859 0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b,
12860 0x22, 0xd4, 0x07, 0x06,
12861 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
12862 0x07, 0x11, 0xae, 0x09,
12863 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01,
12864 0x0e, 0x8e, 0xfe, 0x80,
12865 0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04,
12866 0x09, 0x48, 0x01, 0x0e,
12867 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
12868 0x80, 0xfe, 0x80, 0x4c,
12869 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c,
12870 0x09, 0x5d, 0x01, 0x87,
12871 0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe,
12872 0x19, 0xde, 0xfe, 0x24,
12873 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
12874 0x17, 0xad, 0x9a, 0x1b,
12875 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde,
12876 0x16, 0xfe, 0xda, 0x10,
12877 0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe,
12878 0x18, 0x58, 0x03, 0xfe,
12879 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
12880 0xf4, 0x06, 0xfe, 0x3c,
12881 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f,
12882 0x97, 0xfe, 0x38, 0x17,
12883 0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c,
12884 0x10, 0x18, 0x11, 0x75,
12885 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
12886 0x2e, 0x97, 0xfe, 0x5a,
12887 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19,
12888 0xfe, 0x98, 0xe7, 0x00,
12889 0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75,
12890 0xfe, 0x30, 0xbc, 0xfe,
12891 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
12892 0xcb, 0x97, 0xfe, 0x92,
12893 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe,
12894 0x42, 0x10, 0xfe, 0x02,
12895 0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe,
12896 0x03, 0xa1, 0xfe, 0x1d,
12897 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
12898 0x9a, 0x5b, 0x41, 0xfe,
12899 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7,
12900 0x11, 0x12, 0xfe, 0xdd,
12901 0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8,
12902 0x17, 0x15, 0x06, 0x39,
12903 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
12904 0xfe, 0x7e, 0x18, 0x1e,
12905 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef,
12906 0x12, 0xfe, 0xe1, 0x10,
12907 0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42,
12908 0x13, 0x42, 0x92, 0x09,
12909 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
12910 0xf0, 0xfe, 0x00, 0xcc,
12911 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01,
12912 0x0e, 0xfe, 0x80, 0x4c,
12913 0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe,
12914 0x24, 0x12, 0xfe, 0x14,
12915 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
12916 0xe7, 0x0a, 0x10, 0xfe,
12917 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92,
12918 0x08, 0x54, 0x1b, 0x37,
12919 0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba,
12920 0x90, 0x3a, 0xce, 0x3b,
12921 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
12922 0x13, 0xa3, 0x04, 0x09,
12923 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49,
12924 0x44, 0x17, 0xfe, 0xe8,
12925 0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09,
12926 0x5d, 0x01, 0xa8, 0x09,
12927 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
12928 0x1c, 0x19, 0x03, 0xfe,
12929 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9,
12930 0x6b, 0xfe, 0x2e, 0x19,
12931 0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4,
12932 0xfe, 0x0b, 0x00, 0x6b,
12933 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
12934 0x08, 0x10, 0x03, 0xfe,
12935 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff,
12936 0x04, 0x68, 0x54, 0xe7,
12937 0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe,
12938 0x1a, 0xf4, 0xfe, 0x00,
12939 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
12940 0x04, 0x07, 0x7e, 0xfe,
12941 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
12942 0x07, 0x1a, 0xfe, 0x5a,
12943 0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66,
12944 0x25, 0x6d, 0xe5, 0x07,
12945 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
12946 0xa9, 0xb8, 0x04, 0x15,
12947 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe,
12948 0x40, 0x5c, 0x04, 0x1c,
12949 0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b,
12950 0xf7, 0xfe, 0x82, 0xf0,
12951 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
1da177e4
LT
12952};
12953
27c868c2
MW
12954static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
12955static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
1da177e4
LT
12956
12957/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
12958static unsigned char _adv_asc38C1600_buf[] = {
12959 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
12960 0x18, 0xe4, 0x01, 0x00,
12961 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00,
12962 0x07, 0x17, 0xc0, 0x5f,
12963 0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7,
12964 0x85, 0xf0, 0x86, 0xf0,
12965 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
12966 0x98, 0x57, 0x01, 0xe6,
12967 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d,
12968 0x38, 0x54, 0x32, 0xf0,
12969 0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4,
12970 0x00, 0xe6, 0xb1, 0xf0,
12971 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
12972 0x06, 0x13, 0x0c, 0x1c,
12973 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12,
12974 0xb9, 0x54, 0x00, 0x80,
12975 0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56,
12976 0x03, 0xe6, 0x01, 0xea,
12977 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
12978 0x04, 0x13, 0xbb, 0x55,
12979 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00,
12980 0xbb, 0x00, 0xc0, 0x00,
12981 0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12,
12982 0x4c, 0x1c, 0x4e, 0x1c,
12983 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
12984 0x24, 0x01, 0x3c, 0x01,
12985 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01,
12986 0x78, 0x01, 0x7c, 0x01,
12987 0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c,
12988 0x6e, 0x1e, 0x02, 0x48,
12989 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
12990 0x03, 0xfc, 0x06, 0x00,
12991 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a,
12992 0x30, 0x1c, 0x38, 0x1c,
12993 0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea,
12994 0x5d, 0xf0, 0xa7, 0xf0,
12995 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
12996 0x33, 0x00, 0x34, 0x00,
12997 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01,
12998 0x79, 0x01, 0x3c, 0x09,
12999 0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13,
13000 0x40, 0x16, 0x50, 0x16,
13001 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
13002 0x05, 0xf0, 0x09, 0xf0,
13003 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00,
13004 0x9c, 0x00, 0xa4, 0x00,
13005 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08,
13006 0xe9, 0x09, 0x5c, 0x0c,
13007 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
13008 0x42, 0x1d, 0x08, 0x44,
13009 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54,
13010 0x83, 0x55, 0x83, 0x59,
13011 0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0,
13012 0x4b, 0xf4, 0x04, 0xf8,
13013 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
13014 0xa8, 0x00, 0xaa, 0x00,
13015 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01,
13016 0x7a, 0x01, 0x82, 0x01,
13017 0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07,
13018 0x68, 0x08, 0x10, 0x0d,
13019 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
13020 0xf3, 0x10, 0x06, 0x12,
13021 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c,
13022 0xf0, 0x35, 0x05, 0xfe,
13023 0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8,
13024 0xfe, 0x88, 0x01, 0xff,
13025 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
13026 0x00, 0xfe, 0x57, 0x24,
13027 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09,
13028 0x00, 0x00, 0xff, 0x08,
13029 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
13030 0xff, 0xff, 0xff, 0x13,
13031 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
13032 0xfe, 0x04, 0xf7, 0xe8,
13033 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d,
13034 0x0d, 0x51, 0x37, 0xfe,
13035 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0,
13036 0xfe, 0xf8, 0x01, 0xfe,
13037 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
13038 0x05, 0xfe, 0x08, 0x0f,
13039 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe,
13040 0x28, 0x1c, 0x03, 0xfe,
13041 0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe,
13042 0x48, 0xf0, 0xfe, 0x90,
13043 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
13044 0x02, 0xfe, 0x46, 0xf0,
13045 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0,
13046 0xfe, 0x4e, 0x02, 0xfe,
13047 0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c,
13048 0x0d, 0xa2, 0x1c, 0x07,
13049 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
13050 0x1c, 0xf5, 0xfe, 0x1e,
13051 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc,
13052 0xde, 0x0a, 0x81, 0x01,
13053 0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a,
13054 0x81, 0x01, 0x5c, 0xfe,
13055 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
13056 0xfe, 0x58, 0x1c, 0x1c,
13057 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02,
13058 0x2b, 0xfe, 0x9e, 0x02,
13059 0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30,
13060 0x00, 0x47, 0xb8, 0x01,
13061 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
13062 0x1a, 0x31, 0xfe, 0x69,
13063 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe,
13064 0x1e, 0x1e, 0x20, 0x2c,
13065 0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a,
13066 0x44, 0x15, 0x56, 0x51,
13067 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
13068 0x01, 0x18, 0x09, 0x00,
13069 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01,
13070 0x18, 0xfe, 0xc8, 0x54,
13071 0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60,
13072 0xfe, 0x02, 0xe8, 0x30,
13073 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
13074 0xfe, 0xe4, 0x01, 0xfe,
13075 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe,
13076 0x26, 0xf0, 0xfe, 0x66,
13077 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe,
13078 0xef, 0x10, 0xfe, 0x9f,
13079 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
13080 0x70, 0x37, 0xfe, 0x48,
13081 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26,
13082 0x21, 0xb9, 0xc7, 0x20,
13083 0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15,
13084 0xe1, 0x2a, 0xeb, 0xfe,
13085 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
13086 0x15, 0xfe, 0xe4, 0x00,
13087 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41,
13088 0xfe, 0x06, 0xf0, 0xfe,
13089 0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29,
13090 0x03, 0x81, 0x1e, 0x1b,
13091 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
13092 0xea, 0xfe, 0x46, 0x1c,
13093 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
13094 0xfe, 0x48, 0x1c, 0x75,
13095 0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a,
13096 0xe1, 0x01, 0x18, 0x77,
13097 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
13098 0x8f, 0xfe, 0x70, 0x02,
13099 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04,
13100 0x16, 0xfe, 0x4a, 0x04,
13101 0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff,
13102 0x02, 0x00, 0x10, 0x01,
13103 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
13104 0xee, 0xfe, 0x4c, 0x44,
13105 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54,
13106 0x7b, 0xec, 0x60, 0x8d,
13107 0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01,
13108 0x0c, 0x06, 0x28, 0xfe,
13109 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
13110 0x13, 0x34, 0xfe, 0x4c,
13111 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54,
13112 0x13, 0x01, 0x0c, 0x06,
13113 0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06,
13114 0x28, 0xf9, 0x1f, 0x7f,
13115 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
13116 0xfe, 0xa4, 0x0e, 0x05,
13117 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe,
13118 0x9c, 0x93, 0x3a, 0x0b,
13119 0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b,
13120 0x7d, 0x1d, 0xfe, 0x46,
13121 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
13122 0xfe, 0x87, 0x83, 0xfe,
13123 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98,
13124 0x13, 0x0f, 0xfe, 0x20,
13125 0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84,
13126 0x12, 0x01, 0x38, 0x06,
13127 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
13128 0x05, 0xd0, 0x54, 0x01,
13129 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe,
13130 0x50, 0x12, 0x5e, 0xff,
13131 0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02,
13132 0x00, 0x10, 0x2f, 0xfe,
13133 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
13134 0x38, 0xfe, 0x4a, 0xf0,
13135 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe,
13136 0x21, 0x00, 0xf1, 0x2e,
13137 0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00,
13138 0x10, 0x2f, 0xfe, 0xd0,
13139 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
13140 0x1c, 0x00, 0x4d, 0x01,
13141 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06,
13142 0x28, 0xfe, 0x24, 0x12,
13143 0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe,
13144 0x0d, 0x00, 0x01, 0x42,
13145 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
13146 0x03, 0xb6, 0x1e, 0xfe,
13147 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17,
13148 0xfe, 0x72, 0x06, 0x0a,
13149 0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56,
13150 0x19, 0x16, 0xfe, 0x68,
13151 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
13152 0x03, 0x9a, 0x1e, 0xfe,
13153 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12,
13154 0x48, 0xfe, 0x92, 0x06,
13155 0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13,
13156 0x58, 0xff, 0x02, 0x00,
13157 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
13158 0xfe, 0xea, 0x06, 0x01,
13159 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16,
13160 0xfe, 0xe0, 0x06, 0x15,
13161 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07,
13162 0x01, 0x84, 0xfe, 0xae,
13163 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
13164 0x1e, 0xfe, 0x1a, 0x12,
13165 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
13166 0x43, 0x48, 0x62, 0x80,
13167 0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24,
13168 0x36, 0xfe, 0x02, 0xf6,
13169 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
13170 0xd0, 0x0d, 0x17, 0xfe,
13171 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20,
13172 0x9e, 0x15, 0x82, 0x01,
13173 0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58,
13174 0x57, 0x10, 0xe6, 0x05,
13175 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
13176 0xfe, 0x9c, 0x32, 0x5f,
13177 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c,
13178 0xfe, 0x0a, 0xf0, 0xfe,
13179 0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08,
13180 0xaf, 0xa0, 0x05, 0x29,
13181 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
13182 0x00, 0x01, 0x08, 0x14,
13183 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08,
13184 0x14, 0x00, 0x05, 0xfe,
13185 0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06,
13186 0x12, 0xfe, 0x30, 0x13,
13187 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
13188 0x01, 0x08, 0x14, 0x00,
13189 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a,
13190 0x78, 0x4f, 0x0f, 0xfe,
13191 0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d,
13192 0x28, 0x48, 0xfe, 0x6c,
13193 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
13194 0x12, 0x53, 0x63, 0x4e,
13195 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe,
13196 0x6c, 0x08, 0xaf, 0xa0,
13197 0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24,
13198 0x05, 0xed, 0xfe, 0x9c,
13199 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
13200 0x1e, 0xfe, 0x99, 0x58,
13201 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a,
13202 0x22, 0x6b, 0x01, 0x0c,
13203 0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e,
13204 0x1e, 0x47, 0x2c, 0x7a,
13205 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
13206 0x01, 0x0c, 0x61, 0x65,
13207 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a,
13208 0x16, 0xfe, 0x08, 0x50,
13209 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10,
13210 0x01, 0xfe, 0xce, 0x1e,
13211 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
13212 0x01, 0xfe, 0xfe, 0x1e,
13213 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a,
13214 0x10, 0x01, 0x0c, 0x06,
13215 0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e,
13216 0x10, 0x6a, 0x22, 0x6b,
13217 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
13218 0xfe, 0x9f, 0x83, 0x33,
13219 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93,
13220 0x3a, 0x0b, 0xfe, 0xc6,
13221 0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d,
13222 0x01, 0xfe, 0xce, 0x1e,
13223 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
13224 0x04, 0xfe, 0xc0, 0x93,
13225 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e,
13226 0x10, 0x4b, 0x22, 0x4c,
13227 0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe,
13228 0x4e, 0x11, 0x2f, 0xfe,
13229 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
13230 0x3c, 0x37, 0x88, 0xf5,
13231 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a,
13232 0xd3, 0xfe, 0x42, 0x0a,
13233 0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0,
13234 0x05, 0x29, 0x01, 0x41,
13235 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
13236 0xfe, 0x14, 0x12, 0x01,
13237 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe,
13238 0x2e, 0x1c, 0x05, 0xfe,
13239 0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41,
13240 0xfe, 0x2c, 0x1c, 0xfe,
13241 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
13242 0x92, 0x10, 0xc4, 0xf6,
13243 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe,
13244 0xe7, 0x10, 0xfe, 0x2b,
13245 0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12,
13246 0xac, 0xfe, 0xd2, 0xf0,
13247 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
13248 0x1b, 0xbf, 0xd4, 0x5b,
13249 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75,
13250 0x5e, 0x32, 0x1f, 0x7f,
13251 0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98,
13252 0x05, 0x70, 0xfe, 0x74,
13253 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
13254 0x0f, 0x4d, 0x01, 0xfe,
13255 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06,
13256 0x0d, 0x2b, 0xfe, 0xe2,
13257 0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24,
13258 0xfe, 0x88, 0x13, 0x21,
13259 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
13260 0x83, 0x83, 0xfe, 0xc9,
13261 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04,
13262 0x91, 0x04, 0xfe, 0x84,
13263 0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93,
13264 0xfe, 0xcb, 0x57, 0x0b,
13265 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
13266 0x6a, 0x3b, 0x6b, 0x10,
13267 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30,
13268 0x20, 0x6e, 0xdb, 0x64,
13269 0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55,
13270 0xfe, 0x04, 0xfa, 0x64,
13271 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
13272 0x10, 0x98, 0x91, 0x6c,
13273 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91,
13274 0x4b, 0x7e, 0x4c, 0x01,
13275 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10,
13276 0x58, 0xfe, 0x91, 0x58,
13277 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
13278 0x1b, 0x40, 0x01, 0x0c,
13279 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f,
13280 0xfe, 0x10, 0x90, 0x04,
13281 0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93,
13282 0x79, 0x0b, 0x0e, 0xfe,
13283 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
13284 0x01, 0x0c, 0x06, 0x0d,
13285 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe,
13286 0x0c, 0x58, 0xfe, 0x8d,
13287 0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99,
13288 0x83, 0x33, 0x0b, 0x0e,
13289 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
13290 0x19, 0xfe, 0x19, 0x41,
13291 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42,
13292 0x19, 0xfe, 0x44, 0x00,
13293 0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda,
13294 0x4c, 0xfe, 0x0c, 0x51,
13295 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
13296 0x76, 0x10, 0xac, 0xfe,
13297 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03,
13298 0xe3, 0x23, 0x07, 0xfe,
13299 0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe,
13300 0xcc, 0x0c, 0x1f, 0x92,
13301 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
13302 0x0c, 0xfe, 0x3e, 0x10,
13303 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70,
13304 0xfe, 0xcb, 0xf0, 0xfe,
13305 0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe,
13306 0xf4, 0x0c, 0x19, 0x94,
13307 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
13308 0xfe, 0xcc, 0xf0, 0xef,
13309 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe,
13310 0x4e, 0x11, 0x2f, 0xfe,
13311 0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b,
13312 0x3c, 0x37, 0x88, 0xf5,
13313 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
13314 0x2f, 0xfe, 0x3e, 0x0d,
13315 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f,
13316 0xd2, 0x9f, 0xd3, 0x9f,
13317 0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4,
13318 0xc5, 0x75, 0xd7, 0x99,
13319 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
13320 0x9c, 0x2f, 0xfe, 0x8c,
13321 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe,
13322 0x42, 0x00, 0x05, 0x70,
13323 0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06,
13324 0x0d, 0xfe, 0x44, 0x13,
13325 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
13326 0xfe, 0xda, 0x0e, 0x0a,
13327 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa,
13328 0x10, 0x01, 0xfe, 0xf4,
13329 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40,
13330 0x15, 0x56, 0x01, 0x85,
13331 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
13332 0xcc, 0x10, 0x01, 0xa7,
13333 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04,
13334 0xfe, 0x99, 0x83, 0xfe,
13335 0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe,
13336 0x43, 0x00, 0xfe, 0xa2,
13337 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
13338 0x00, 0x1d, 0x40, 0x15,
13339 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05,
13340 0xfe, 0x3a, 0x03, 0x01,
13341 0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01,
13342 0x76, 0x06, 0x12, 0xfe,
13343 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
13344 0xfe, 0x9d, 0xf0, 0xfe,
13345 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01,
13346 0x0c, 0x61, 0x12, 0x44,
13347 0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f,
13348 0xfe, 0x2e, 0x10, 0x19,
13349 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
13350 0xfe, 0x41, 0x00, 0xa2,
13351 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b,
13352 0xea, 0x4f, 0xfe, 0x04,
13353 0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05,
13354 0x35, 0xfe, 0x12, 0x1c,
13355 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
13356 0xfe, 0xd4, 0x11, 0x05,
13357 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe,
13358 0xce, 0x45, 0x31, 0x51,
13359 0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03,
13360 0x67, 0xfe, 0x98, 0x56,
13361 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
13362 0x0c, 0x06, 0x28, 0xfe,
13363 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba,
13364 0xfe, 0xfa, 0x14, 0xfe,
13365 0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67,
13366 0xfe, 0xe0, 0x14, 0xfe,
13367 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
13368 0xfe, 0xad, 0x13, 0x05,
13369 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20,
13370 0xe7, 0xfe, 0x08, 0x1c,
13371 0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe,
13372 0x48, 0x55, 0xa5, 0x3b,
13373 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
13374 0xf0, 0x1a, 0x03, 0xfe,
13375 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02,
13376 0xec, 0xe7, 0x53, 0x00,
13377 0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
13378 0x01, 0xfe, 0x62, 0x1b,
13379 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
13380 0xea, 0xe7, 0x53, 0x92,
13381 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03,
13382 0xfe, 0x38, 0x01, 0x23,
13383 0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62,
13384 0x01, 0x01, 0xfe, 0x1e,
13385 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
13386 0x26, 0x02, 0x21, 0x96,
13387 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5,
13388 0xc3, 0xfe, 0xe1, 0x10,
13389 0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf,
13390 0xfe, 0x03, 0xdc, 0xfe,
13391 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
13392 0x00, 0xcc, 0x02, 0xfe,
13393 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13,
13394 0x0f, 0xfe, 0x1c, 0x80,
13395 0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13,
13396 0x0f, 0xfe, 0x1e, 0x80,
13397 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
13398 0x1d, 0x80, 0x04, 0xfe,
13399 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee,
13400 0x1e, 0xac, 0xfe, 0x14,
13401 0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e,
13402 0x1f, 0xfe, 0x30, 0xf4,
13403 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
13404 0x56, 0xfb, 0x01, 0xfe,
13405 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01,
13406 0xfe, 0x00, 0x1d, 0x15,
13407 0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe,
13408 0x22, 0x1b, 0xfe, 0x1e,
13409 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
13410 0x96, 0x90, 0x04, 0xfe,
13411 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66,
13412 0x01, 0x01, 0x0c, 0x06,
13413 0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b,
13414 0x0e, 0x77, 0xfe, 0x01,
13415 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
13416 0x21, 0x2c, 0xfe, 0x00,
13417 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe,
13418 0x06, 0x58, 0x03, 0xfe,
13419 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58,
13420 0x03, 0xfe, 0xb2, 0x00,
13421 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
13422 0x66, 0x10, 0x55, 0x10,
13423 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91,
13424 0x54, 0x2b, 0xfe, 0x88,
13425 0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe,
13426 0x91, 0x54, 0x2b, 0xfe,
13427 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
13428 0x00, 0x40, 0x8d, 0x2c,
13429 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe,
13430 0x12, 0x1c, 0x75, 0xfe,
13431 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c,
13432 0x14, 0xfe, 0x0e, 0x47,
13433 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
13434 0xa7, 0x90, 0x34, 0x60,
13435 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80,
13436 0x09, 0x56, 0xfe, 0x34,
13437 0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48,
13438 0xfe, 0x45, 0x48, 0x01,
13439 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
13440 0x09, 0x1a, 0xa5, 0x0a,
13441 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4,
13442 0xfe, 0x14, 0x56, 0xfe,
13443 0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01,
13444 0xec, 0xb8, 0xfe, 0x9e,
13445 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
13446 0xf4, 0xfe, 0xdd, 0x10,
13447 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48,
13448 0x12, 0x09, 0x0d, 0xfe,
13449 0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4,
13450 0x13, 0x09, 0xfe, 0x23,
13451 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
13452 0x24, 0xfe, 0x12, 0x12,
13453 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08,
13454 0xae, 0x41, 0x02, 0x32,
13455 0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05,
13456 0x35, 0x32, 0x01, 0x43,
13457 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
13458 0x13, 0x01, 0x0c, 0x06,
13459 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe,
13460 0xe5, 0x55, 0xb0, 0xfe,
13461 0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e,
13462 0xfe, 0xb6, 0x0e, 0x10,
13463 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
13464 0x88, 0x20, 0x6e, 0x01,
13465 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5,
13466 0x55, 0xfe, 0x04, 0xfa,
13467 0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d,
13468 0xfe, 0x40, 0x56, 0xfe,
13469 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
13470 0x44, 0x55, 0xfe, 0xe5,
13471 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10,
13472 0x68, 0x22, 0x69, 0x01,
13473 0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b,
13474 0x6b, 0xfe, 0x2c, 0x50,
13475 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
13476 0x50, 0x03, 0x68, 0x3b,
13477 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe,
13478 0x40, 0x50, 0xfe, 0xc2,
13479 0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08,
13480 0x16, 0x3d, 0x27, 0x25,
13481 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
13482 0xa6, 0x23, 0x3f, 0x1b,
13483 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c,
13484 0xfe, 0x0a, 0x55, 0x31,
13485 0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e,
13486 0x51, 0x05, 0x72, 0x01,
13487 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
13488 0x2a, 0x3c, 0x16, 0xc0,
13489 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b,
13490 0xfe, 0x66, 0x15, 0x05,
13491 0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d,
13492 0x2b, 0x3d, 0x01, 0x08,
13493 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
13494 0xb6, 0x1e, 0x83, 0x01,
13495 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46,
13496 0x07, 0x90, 0x3f, 0x01,
13497 0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13,
13498 0x01, 0x43, 0x09, 0x82,
13499 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
13500 0x05, 0x72, 0xfe, 0xc0,
13501 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e,
13502 0x32, 0x01, 0x08, 0x17,
13503 0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16,
13504 0x3d, 0x27, 0x25, 0xbd,
13505 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
13506 0xe8, 0x14, 0x01, 0xa6,
13507 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe,
13508 0x0e, 0x12, 0x01, 0x43,
13509 0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32,
13510 0x01, 0x08, 0x17, 0x73,
13511 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
13512 0x27, 0x25, 0xbd, 0x09,
13513 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe,
13514 0xb6, 0x14, 0x86, 0xa8,
13515 0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09,
13516 0x82, 0x4e, 0x05, 0x72,
13517 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
13518 0xfe, 0xc0, 0x19, 0x05,
13519 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f,
13520 0xcc, 0x01, 0x08, 0x26,
13521 0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe,
13522 0xcc, 0x15, 0x5e, 0x32,
13523 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
13524 0xad, 0x23, 0xfe, 0xff,
13525 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02,
13526 0x00, 0x57, 0x52, 0xad,
13527 0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff,
13528 0x02, 0x00, 0x57, 0x52,
13529 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
13530 0x02, 0x13, 0x58, 0xff,
13531 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01,
13532 0x5c, 0x0a, 0x55, 0x01,
13533 0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a,
13534 0xff, 0x03, 0x00, 0x54,
13535 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
13536 0x7c, 0x3a, 0x0b, 0x0e,
13537 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19,
13538 0xfe, 0x1a, 0xf7, 0x00,
13539 0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c,
13540 0xda, 0x6d, 0x02, 0xfe,
13541 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
13542 0x02, 0x01, 0xc6, 0xfe,
13543 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27,
13544 0x25, 0xbe, 0x01, 0x08,
13545 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59,
13546 0x03, 0x9a, 0x1e, 0xfe,
13547 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
13548 0x48, 0xfe, 0x08, 0x17,
13549 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26,
13550 0x17, 0x4d, 0x13, 0x07,
13551 0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1,
13552 0xff, 0x02, 0x83, 0x55,
13553 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
13554 0x17, 0x1c, 0x63, 0x13,
13555 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64,
13556 0x00, 0xb0, 0xfe, 0x80,
13557 0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10,
13558 0x53, 0x07, 0xfe, 0x60,
13559 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
13560 0x00, 0x1c, 0x95, 0x13,
13561 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3,
13562 0xfe, 0x43, 0xf4, 0x96,
13563 0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43,
13564 0xf4, 0x94, 0xf6, 0x8b,
13565 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
13566 0xda, 0x17, 0x62, 0x49,
13567 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80,
13568 0x71, 0x50, 0x26, 0xfe,
13569 0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3,
13570 0x58, 0x02, 0x50, 0x13,
13571 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
13572 0x25, 0xbe, 0xfe, 0x03,
13573 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9,
13574 0x0a, 0x01, 0x08, 0x16,
13575 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01,
13576 0x01, 0x08, 0x16, 0xa9,
13577 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
13578 0x08, 0x16, 0xa9, 0x27,
13579 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83,
13580 0x01, 0x38, 0x06, 0x24,
13581 0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1,
13582 0x78, 0x03, 0x9a, 0x1e,
13583 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
13584 0xfe, 0x40, 0x5a, 0x23,
13585 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c,
13586 0x80, 0x48, 0xfe, 0xaa,
13587 0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01,
13588 0xfe, 0xac, 0x1d, 0xfe,
13589 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
13590 0x43, 0x48, 0x2d, 0x93,
13591 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4,
13592 0x36, 0xfe, 0x34, 0xf4,
13593 0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe,
13594 0x28, 0x10, 0xfe, 0xc0,
13595 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
13596 0x18, 0x45, 0xfe, 0x1c,
13597 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c,
13598 0x19, 0xfe, 0x04, 0xf4,
13599 0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d,
13600 0x21, 0xfe, 0x7f, 0x01,
13601 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
13602 0x7e, 0x01, 0xfe, 0xc8,
13603 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa,
13604 0x21, 0xfe, 0x81, 0x01,
13605 0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50,
13606 0x13, 0x0d, 0x02, 0x14,
13607 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
13608 0xfe, 0x82, 0x19, 0x14,
13609 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01,
13610 0x08, 0x02, 0x14, 0x07,
13611 0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07,
13612 0x01, 0x08, 0x17, 0xc1,
13613 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
13614 0x08, 0x02, 0x50, 0x02,
13615 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74,
13616 0x14, 0x12, 0x01, 0x08,
13617 0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01,
13618 0x08, 0x17, 0x74, 0xfe,
13619 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
13620 0x74, 0x5f, 0xcc, 0x01,
13621 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4,
13622 0xfe, 0x49, 0xf4, 0x00,
13623 0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff,
13624 0x02, 0x00, 0x10, 0x2f,
13625 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
13626 0x16, 0xfe, 0x64, 0x1a,
13627 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c,
13628 0x61, 0x07, 0x44, 0x02,
13629 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12,
13630 0x13, 0x0a, 0x9d, 0x01,
13631 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
13632 0xfe, 0x80, 0xe7, 0x1a,
13633 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02,
13634 0x0a, 0x5a, 0x01, 0x18,
13635 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe,
13636 0x7e, 0x1e, 0xfe, 0x80,
13637 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
13638 0xfe, 0x80, 0x4c, 0x0a,
13639 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf,
13640 0xfe, 0x19, 0xde, 0xfe,
13641 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe,
13642 0x2a, 0x1c, 0xfa, 0xb3,
13643 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
13644 0xf4, 0x1a, 0xfe, 0xfa,
13645 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24,
13646 0xfe, 0x18, 0x58, 0x03,
13647 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f,
13648 0xfe, 0x30, 0xf4, 0x07,
13649 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
13650 0xf7, 0x24, 0xb1, 0xfe,
13651 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b,
13652 0xfe, 0xba, 0x10, 0x1c,
13653 0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
13654 0x1d, 0xf7, 0x54, 0xb1,
13655 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
13656 0xaf, 0x19, 0xfe, 0x98,
13657 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c,
13658 0x1a, 0x87, 0x8b, 0x0f,
13659 0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58,
13660 0xfe, 0x32, 0x90, 0x04,
13661 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
13662 0x7c, 0x12, 0xfe, 0x0f,
13663 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14,
13664 0x31, 0x02, 0xc9, 0x2b,
13665 0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe,
13666 0x6a, 0xfe, 0x19, 0xfe,
13667 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
13668 0x1b, 0xfe, 0x36, 0x14,
13669 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19,
13670 0xfe, 0x80, 0xe7, 0x1a,
13671 0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a,
13672 0x30, 0xfe, 0x12, 0x45,
13673 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
13674 0x39, 0xf0, 0x75, 0x26,
13675 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03,
13676 0xe3, 0x23, 0x07, 0xfe,
13677 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09,
13678 0x56, 0xfe, 0x3c, 0x13,
13679 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
13680 0x01, 0x18, 0xcb, 0xfe,
13681 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16,
13682 0xfe, 0x00, 0xcc, 0xcb,
13683 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18,
13684 0xfe, 0x80, 0x4c, 0x01,
13685 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
13686 0x12, 0xfe, 0x14, 0x56,
13687 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7,
13688 0x0d, 0x19, 0xfe, 0x15,
13689 0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06,
13690 0x83, 0xfe, 0x18, 0x80,
13691 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
13692 0x90, 0xfe, 0xba, 0x90,
13693 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02,
13694 0x21, 0xb9, 0x88, 0x20,
13695 0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01,
13696 0x18, 0xfe, 0x49, 0x44,
13697 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
13698 0x1a, 0xa4, 0x0a, 0x67,
13699 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4,
13700 0x1d, 0x7b, 0xfe, 0x52,
13701 0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe,
13702 0x4e, 0xe4, 0xdd, 0x7b,
13703 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
13704 0xfe, 0x4e, 0xe4, 0xfe,
13705 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24,
13706 0xfe, 0x08, 0x10, 0x03,
13707 0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04,
13708 0x68, 0x54, 0xfe, 0xf1,
13709 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
13710 0xfe, 0x1a, 0xf4, 0xfe,
13711 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02,
13712 0x09, 0x92, 0xfe, 0x5a,
13713 0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe,
13714 0x5a, 0xf0, 0xfe, 0xc8,
13715 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
13716 0x1a, 0x10, 0x09, 0x0d,
13717 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02,
13718 0x1f, 0x93, 0x01, 0x42,
13719 0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e,
13720 0xfe, 0x14, 0xf0, 0x08,
13721 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
13722 0xfe, 0x82, 0xf0, 0xfe,
13723 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e,
13724 0x02, 0x0f, 0xfe, 0x18,
13725 0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02,
13726 0x80, 0x04, 0xfe, 0x82,
13727 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
13728 0x83, 0x33, 0x0b, 0x0e,
13729 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e,
13730 0x02, 0x0f, 0xfe, 0x04,
13731 0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80,
13732 0x80, 0x04, 0xfe, 0x80,
13733 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
13734 0xfe, 0x99, 0x83, 0xfe,
13735 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86,
13736 0x83, 0xfe, 0xce, 0x47,
13737 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a,
13738 0x0b, 0x0e, 0x02, 0x0f,
13739 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13740 0xfe, 0x08, 0x90, 0x04,
13741 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04,
13742 0xfe, 0x8a, 0x93, 0x79,
13743 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a,
13744 0x0b, 0x0e, 0x02, 0x0f,
13745 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13746 0xfe, 0x3c, 0x90, 0x04,
13747 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80,
13748 0x04, 0xfe, 0x83, 0x83,
13749 0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
1da177e4
LT
13750};
13751
27c868c2
MW
13752static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
13753static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
1da177e4
LT
13754
13755/* a_init.c */
13756/*
13757 * EEPROM Configuration.
13758 *
13759 * All drivers should use this structure to set the default EEPROM
13760 * configuration. The BIOS now uses this structure when it is built.
13761 * Additional structure information can be found in a_condor.h where
13762 * the structure is defined.
13763 *
13764 * The *_Field_IsChar structs are needed to correct for endianness.
13765 * These values are read from the board 16 bits at a time directly
13766 * into the structs. Because some fields are char, the values will be
13767 * in the wrong order. The *_Field_IsChar tells when to flip the
13768 * bytes. Data read and written to PCI memory is automatically swapped
13769 * on big-endian platforms so char fields read as words are actually being
13770 * unswapped on big-endian platforms.
13771 */
27c868c2
MW
13772static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __initdata = {
13773 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
13774 0x0000, /* cfg_msw */
13775 0xFFFF, /* disc_enable */
13776 0xFFFF, /* wdtr_able */
13777 0xFFFF, /* sdtr_able */
13778 0xFFFF, /* start_motor */
13779 0xFFFF, /* tagqng_able */
13780 0xFFFF, /* bios_scan */
13781 0, /* scam_tolerant */
13782 7, /* adapter_scsi_id */
13783 0, /* bios_boot_delay */
13784 3, /* scsi_reset_delay */
13785 0, /* bios_id_lun */
13786 0, /* termination */
13787 0, /* reserved1 */
13788 0xFFE7, /* bios_ctrl */
13789 0xFFFF, /* ultra_able */
13790 0, /* reserved2 */
13791 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
13792 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13793 0, /* dvc_cntl */
13794 0, /* bug_fix */
13795 0, /* serial_number_word1 */
13796 0, /* serial_number_word2 */
13797 0, /* serial_number_word3 */
13798 0, /* check_sum */
13799 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13800 , /* oem_name[16] */
13801 0, /* dvc_err_code */
13802 0, /* adv_err_code */
13803 0, /* adv_err_addr */
13804 0, /* saved_dvc_err_code */
13805 0, /* saved_adv_err_code */
13806 0, /* saved_adv_err_addr */
13807 0 /* num_of_err */
1da177e4
LT
13808};
13809
27c868c2
MW
13810static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __initdata = {
13811 0, /* cfg_lsw */
13812 0, /* cfg_msw */
13813 0, /* -disc_enable */
13814 0, /* wdtr_able */
13815 0, /* sdtr_able */
13816 0, /* start_motor */
13817 0, /* tagqng_able */
13818 0, /* bios_scan */
13819 0, /* scam_tolerant */
13820 1, /* adapter_scsi_id */
13821 1, /* bios_boot_delay */
13822 1, /* scsi_reset_delay */
13823 1, /* bios_id_lun */
13824 1, /* termination */
13825 1, /* reserved1 */
13826 0, /* bios_ctrl */
13827 0, /* ultra_able */
13828 0, /* reserved2 */
13829 1, /* max_host_qng */
13830 1, /* max_dvc_qng */
13831 0, /* dvc_cntl */
13832 0, /* bug_fix */
13833 0, /* serial_number_word1 */
13834 0, /* serial_number_word2 */
13835 0, /* serial_number_word3 */
13836 0, /* check_sum */
13837 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13838 , /* oem_name[16] */
13839 0, /* dvc_err_code */
13840 0, /* adv_err_code */
13841 0, /* adv_err_addr */
13842 0, /* saved_dvc_err_code */
13843 0, /* saved_adv_err_code */
13844 0, /* saved_adv_err_addr */
13845 0 /* num_of_err */
1da177e4
LT
13846};
13847
27c868c2
MW
13848static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __initdata = {
13849 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13850 0x0000, /* 01 cfg_msw */
13851 0xFFFF, /* 02 disc_enable */
13852 0xFFFF, /* 03 wdtr_able */
13853 0x4444, /* 04 sdtr_speed1 */
13854 0xFFFF, /* 05 start_motor */
13855 0xFFFF, /* 06 tagqng_able */
13856 0xFFFF, /* 07 bios_scan */
13857 0, /* 08 scam_tolerant */
13858 7, /* 09 adapter_scsi_id */
13859 0, /* bios_boot_delay */
13860 3, /* 10 scsi_reset_delay */
13861 0, /* bios_id_lun */
13862 0, /* 11 termination_se */
13863 0, /* termination_lvd */
13864 0xFFE7, /* 12 bios_ctrl */
13865 0x4444, /* 13 sdtr_speed2 */
13866 0x4444, /* 14 sdtr_speed3 */
13867 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
13868 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13869 0, /* 16 dvc_cntl */
13870 0x4444, /* 17 sdtr_speed4 */
13871 0, /* 18 serial_number_word1 */
13872 0, /* 19 serial_number_word2 */
13873 0, /* 20 serial_number_word3 */
13874 0, /* 21 check_sum */
13875 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13876 , /* 22-29 oem_name[16] */
13877 0, /* 30 dvc_err_code */
13878 0, /* 31 adv_err_code */
13879 0, /* 32 adv_err_addr */
13880 0, /* 33 saved_dvc_err_code */
13881 0, /* 34 saved_adv_err_code */
13882 0, /* 35 saved_adv_err_addr */
13883 0, /* 36 reserved */
13884 0, /* 37 reserved */
13885 0, /* 38 reserved */
13886 0, /* 39 reserved */
13887 0, /* 40 reserved */
13888 0, /* 41 reserved */
13889 0, /* 42 reserved */
13890 0, /* 43 reserved */
13891 0, /* 44 reserved */
13892 0, /* 45 reserved */
13893 0, /* 46 reserved */
13894 0, /* 47 reserved */
13895 0, /* 48 reserved */
13896 0, /* 49 reserved */
13897 0, /* 50 reserved */
13898 0, /* 51 reserved */
13899 0, /* 52 reserved */
13900 0, /* 53 reserved */
13901 0, /* 54 reserved */
13902 0, /* 55 reserved */
13903 0, /* 56 cisptr_lsw */
13904 0, /* 57 cisprt_msw */
13905 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
13906 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
13907 0, /* 60 reserved */
13908 0, /* 61 reserved */
13909 0, /* 62 reserved */
13910 0 /* 63 reserved */
1da177e4
LT
13911};
13912
27c868c2
MW
13913static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __initdata = {
13914 0, /* 00 cfg_lsw */
13915 0, /* 01 cfg_msw */
13916 0, /* 02 disc_enable */
13917 0, /* 03 wdtr_able */
13918 0, /* 04 sdtr_speed1 */
13919 0, /* 05 start_motor */
13920 0, /* 06 tagqng_able */
13921 0, /* 07 bios_scan */
13922 0, /* 08 scam_tolerant */
13923 1, /* 09 adapter_scsi_id */
13924 1, /* bios_boot_delay */
13925 1, /* 10 scsi_reset_delay */
13926 1, /* bios_id_lun */
13927 1, /* 11 termination_se */
13928 1, /* termination_lvd */
13929 0, /* 12 bios_ctrl */
13930 0, /* 13 sdtr_speed2 */
13931 0, /* 14 sdtr_speed3 */
13932 1, /* 15 max_host_qng */
13933 1, /* max_dvc_qng */
13934 0, /* 16 dvc_cntl */
13935 0, /* 17 sdtr_speed4 */
13936 0, /* 18 serial_number_word1 */
13937 0, /* 19 serial_number_word2 */
13938 0, /* 20 serial_number_word3 */
13939 0, /* 21 check_sum */
13940 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13941 , /* 22-29 oem_name[16] */
13942 0, /* 30 dvc_err_code */
13943 0, /* 31 adv_err_code */
13944 0, /* 32 adv_err_addr */
13945 0, /* 33 saved_dvc_err_code */
13946 0, /* 34 saved_adv_err_code */
13947 0, /* 35 saved_adv_err_addr */
13948 0, /* 36 reserved */
13949 0, /* 37 reserved */
13950 0, /* 38 reserved */
13951 0, /* 39 reserved */
13952 0, /* 40 reserved */
13953 0, /* 41 reserved */
13954 0, /* 42 reserved */
13955 0, /* 43 reserved */
13956 0, /* 44 reserved */
13957 0, /* 45 reserved */
13958 0, /* 46 reserved */
13959 0, /* 47 reserved */
13960 0, /* 48 reserved */
13961 0, /* 49 reserved */
13962 0, /* 50 reserved */
13963 0, /* 51 reserved */
13964 0, /* 52 reserved */
13965 0, /* 53 reserved */
13966 0, /* 54 reserved */
13967 0, /* 55 reserved */
13968 0, /* 56 cisptr_lsw */
13969 0, /* 57 cisprt_msw */
13970 0, /* 58 subsysvid */
13971 0, /* 59 subsysid */
13972 0, /* 60 reserved */
13973 0, /* 61 reserved */
13974 0, /* 62 reserved */
13975 0 /* 63 reserved */
1da177e4
LT
13976};
13977
27c868c2
MW
13978static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __initdata = {
13979 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13980 0x0000, /* 01 cfg_msw */
13981 0xFFFF, /* 02 disc_enable */
13982 0xFFFF, /* 03 wdtr_able */
13983 0x5555, /* 04 sdtr_speed1 */
13984 0xFFFF, /* 05 start_motor */
13985 0xFFFF, /* 06 tagqng_able */
13986 0xFFFF, /* 07 bios_scan */
13987 0, /* 08 scam_tolerant */
13988 7, /* 09 adapter_scsi_id */
13989 0, /* bios_boot_delay */
13990 3, /* 10 scsi_reset_delay */
13991 0, /* bios_id_lun */
13992 0, /* 11 termination_se */
13993 0, /* termination_lvd */
13994 0xFFE7, /* 12 bios_ctrl */
13995 0x5555, /* 13 sdtr_speed2 */
13996 0x5555, /* 14 sdtr_speed3 */
13997 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
13998 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13999 0, /* 16 dvc_cntl */
14000 0x5555, /* 17 sdtr_speed4 */
14001 0, /* 18 serial_number_word1 */
14002 0, /* 19 serial_number_word2 */
14003 0, /* 20 serial_number_word3 */
14004 0, /* 21 check_sum */
14005 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
14006 , /* 22-29 oem_name[16] */
14007 0, /* 30 dvc_err_code */
14008 0, /* 31 adv_err_code */
14009 0, /* 32 adv_err_addr */
14010 0, /* 33 saved_dvc_err_code */
14011 0, /* 34 saved_adv_err_code */
14012 0, /* 35 saved_adv_err_addr */
14013 0, /* 36 reserved */
14014 0, /* 37 reserved */
14015 0, /* 38 reserved */
14016 0, /* 39 reserved */
14017 0, /* 40 reserved */
14018 0, /* 41 reserved */
14019 0, /* 42 reserved */
14020 0, /* 43 reserved */
14021 0, /* 44 reserved */
14022 0, /* 45 reserved */
14023 0, /* 46 reserved */
14024 0, /* 47 reserved */
14025 0, /* 48 reserved */
14026 0, /* 49 reserved */
14027 0, /* 50 reserved */
14028 0, /* 51 reserved */
14029 0, /* 52 reserved */
14030 0, /* 53 reserved */
14031 0, /* 54 reserved */
14032 0, /* 55 reserved */
14033 0, /* 56 cisptr_lsw */
14034 0, /* 57 cisprt_msw */
14035 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
14036 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
14037 0, /* 60 reserved */
14038 0, /* 61 reserved */
14039 0, /* 62 reserved */
14040 0 /* 63 reserved */
1da177e4
LT
14041};
14042
27c868c2
MW
14043static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __initdata = {
14044 0, /* 00 cfg_lsw */
14045 0, /* 01 cfg_msw */
14046 0, /* 02 disc_enable */
14047 0, /* 03 wdtr_able */
14048 0, /* 04 sdtr_speed1 */
14049 0, /* 05 start_motor */
14050 0, /* 06 tagqng_able */
14051 0, /* 07 bios_scan */
14052 0, /* 08 scam_tolerant */
14053 1, /* 09 adapter_scsi_id */
14054 1, /* bios_boot_delay */
14055 1, /* 10 scsi_reset_delay */
14056 1, /* bios_id_lun */
14057 1, /* 11 termination_se */
14058 1, /* termination_lvd */
14059 0, /* 12 bios_ctrl */
14060 0, /* 13 sdtr_speed2 */
14061 0, /* 14 sdtr_speed3 */
14062 1, /* 15 max_host_qng */
14063 1, /* max_dvc_qng */
14064 0, /* 16 dvc_cntl */
14065 0, /* 17 sdtr_speed4 */
14066 0, /* 18 serial_number_word1 */
14067 0, /* 19 serial_number_word2 */
14068 0, /* 20 serial_number_word3 */
14069 0, /* 21 check_sum */
14070 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
14071 , /* 22-29 oem_name[16] */
14072 0, /* 30 dvc_err_code */
14073 0, /* 31 adv_err_code */
14074 0, /* 32 adv_err_addr */
14075 0, /* 33 saved_dvc_err_code */
14076 0, /* 34 saved_adv_err_code */
14077 0, /* 35 saved_adv_err_addr */
14078 0, /* 36 reserved */
14079 0, /* 37 reserved */
14080 0, /* 38 reserved */
14081 0, /* 39 reserved */
14082 0, /* 40 reserved */
14083 0, /* 41 reserved */
14084 0, /* 42 reserved */
14085 0, /* 43 reserved */
14086 0, /* 44 reserved */
14087 0, /* 45 reserved */
14088 0, /* 46 reserved */
14089 0, /* 47 reserved */
14090 0, /* 48 reserved */
14091 0, /* 49 reserved */
14092 0, /* 50 reserved */
14093 0, /* 51 reserved */
14094 0, /* 52 reserved */
14095 0, /* 53 reserved */
14096 0, /* 54 reserved */
14097 0, /* 55 reserved */
14098 0, /* 56 cisptr_lsw */
14099 0, /* 57 cisprt_msw */
14100 0, /* 58 subsysvid */
14101 0, /* 59 subsysid */
14102 0, /* 60 reserved */
14103 0, /* 61 reserved */
14104 0, /* 62 reserved */
14105 0 /* 63 reserved */
1da177e4
LT
14106};
14107
14108/*
14109 * Initialize the ADV_DVC_VAR structure.
14110 *
14111 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14112 *
14113 * For a non-fatal error return a warning code. If there are no warnings
14114 * then 0 is returned.
14115 */
27c868c2 14116static int __init AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
1da177e4 14117{
27c868c2
MW
14118 ushort warn_code;
14119 AdvPortAddr iop_base;
14120 uchar pci_cmd_reg;
14121 int status;
14122
14123 warn_code = 0;
14124 asc_dvc->err_code = 0;
14125 iop_base = asc_dvc->iop_base;
14126
14127 /*
14128 * PCI Command Register
14129 *
14130 * Note: AscPCICmdRegBits_BusMastering definition (0x0007) includes
14131 * I/O Space Control, Memory Space Control and Bus Master Control bits.
14132 */
14133
14134 if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
14135 AscPCIConfigCommandRegister))
14136 & AscPCICmdRegBits_BusMastering)
14137 != AscPCICmdRegBits_BusMastering) {
14138 pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
14139
14140 DvcAdvWritePCIConfigByte(asc_dvc,
14141 AscPCIConfigCommandRegister,
14142 pci_cmd_reg);
14143
14144 if (((DvcAdvReadPCIConfigByte
14145 (asc_dvc, AscPCIConfigCommandRegister))
14146 & AscPCICmdRegBits_BusMastering)
14147 != AscPCICmdRegBits_BusMastering) {
14148 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14149 }
14150 }
1da177e4 14151
27c868c2
MW
14152 /*
14153 * PCI Latency Timer
14154 *
14155 * If the "latency timer" register is 0x20 or above, then we don't need
14156 * to change it. Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
14157 * comes up less than 0x20).
14158 */
14159 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
14160 DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer,
14161 0x20);
14162 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) <
14163 0x20) {
14164 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14165 }
14166 }
1da177e4 14167
27c868c2
MW
14168 /*
14169 * Save the state of the PCI Configuration Command Register
14170 * "Parity Error Response Control" Bit. If the bit is clear (0),
14171 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
14172 * DMA parity errors.
14173 */
14174 asc_dvc->cfg->control_flag = 0;
14175 if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
14176 & AscPCICmdRegBits_ParErrRespCtrl)) == 0) {
14177 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
14178 }
1da177e4 14179
27c868c2
MW
14180 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
14181 ADV_LIB_VERSION_MINOR;
14182 asc_dvc->cfg->chip_version =
14183 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
14184
14185 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
14186 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
14187 (ushort)ADV_CHIP_ID_BYTE);
14188
14189 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
14190 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
14191 (ushort)ADV_CHIP_ID_WORD);
14192
14193 /*
14194 * Reset the chip to start and allow register writes.
14195 */
14196 if (AdvFindSignature(iop_base) == 0) {
14197 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
14198 return ADV_ERROR;
14199 } else {
14200 /*
14201 * The caller must set 'chip_type' to a valid setting.
14202 */
14203 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
14204 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
14205 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
14206 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14207 return ADV_ERROR;
14208 }
1da177e4 14209
27c868c2
MW
14210 /*
14211 * Reset Chip.
14212 */
14213 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14214 ADV_CTRL_REG_CMD_RESET);
14215 DvcSleepMilliSecond(100);
14216 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14217 ADV_CTRL_REG_CMD_WR_IO_REG);
14218
14219 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
14220 if ((status =
14221 AdvInitFrom38C1600EEP(asc_dvc)) == ADV_ERROR) {
14222 return ADV_ERROR;
14223 }
14224 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
14225 if ((status =
14226 AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR) {
14227 return ADV_ERROR;
14228 }
14229 } else {
14230 if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR) {
14231 return ADV_ERROR;
14232 }
14233 }
14234 warn_code |= status;
14235 }
1da177e4 14236
27c868c2 14237 return warn_code;
1da177e4
LT
14238}
14239
14240/*
14241 * Initialize the ASC-3550.
14242 *
14243 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14244 *
14245 * For a non-fatal error return a warning code. If there are no warnings
14246 * then 0 is returned.
14247 *
14248 * Needed after initialization for error recovery.
14249 */
27c868c2 14250static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
1da177e4 14251{
27c868c2
MW
14252 AdvPortAddr iop_base;
14253 ushort warn_code;
14254 ADV_DCNT sum;
14255 int begin_addr;
14256 int end_addr;
14257 ushort code_sum;
14258 int word;
14259 int j;
14260 int adv_asc3550_expanded_size;
14261 ADV_CARR_T *carrp;
14262 ADV_DCNT contig_len;
14263 ADV_SDCNT buf_size;
14264 ADV_PADDR carr_paddr;
14265 int i;
14266 ushort scsi_cfg1;
14267 uchar tid;
14268 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
14269 ushort wdtr_able = 0, sdtr_able, tagqng_able;
14270 uchar max_cmd[ADV_MAX_TID + 1];
14271
14272 /* If there is already an error, don't continue. */
14273 if (asc_dvc->err_code != 0) {
14274 return ADV_ERROR;
14275 }
1da177e4 14276
27c868c2
MW
14277 /*
14278 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
14279 */
14280 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
14281 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14282 return ADV_ERROR;
14283 }
1da177e4 14284
27c868c2
MW
14285 warn_code = 0;
14286 iop_base = asc_dvc->iop_base;
14287
14288 /*
14289 * Save the RISC memory BIOS region before writing the microcode.
14290 * The BIOS may already be loaded and using its RISC LRAM region
14291 * so its region must be saved and restored.
14292 *
14293 * Note: This code makes the assumption, which is currently true,
14294 * that a chip reset does not clear RISC LRAM.
14295 */
14296 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14297 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14298 bios_mem[i]);
14299 }
1da177e4 14300
27c868c2
MW
14301 /*
14302 * Save current per TID negotiated values.
14303 */
14304 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
14305 ushort bios_version, major, minor;
14306
14307 bios_version =
14308 bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
14309 major = (bios_version >> 12) & 0xF;
14310 minor = (bios_version >> 8) & 0xF;
14311 if (major < 3 || (major == 3 && minor == 1)) {
14312 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
14313 AdvReadWordLram(iop_base, 0x120, wdtr_able);
14314 } else {
14315 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14316 }
14317 }
14318 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14319 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14320 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14321 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14322 max_cmd[tid]);
14323 }
1da177e4 14324
27c868c2
MW
14325 /*
14326 * Load the Microcode
14327 *
14328 * Write the microcode image to RISC memory starting at address 0.
14329 */
14330 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14331 /* Assume the following compressed format of the microcode buffer:
14332 *
14333 * 254 word (508 byte) table indexed by byte code followed
14334 * by the following byte codes:
14335 *
14336 * 1-Byte Code:
14337 * 00: Emit word 0 in table.
14338 * 01: Emit word 1 in table.
14339 * .
14340 * FD: Emit word 253 in table.
14341 *
14342 * Multi-Byte Code:
14343 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14344 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14345 */
14346 word = 0;
14347 for (i = 253 * 2; i < _adv_asc3550_size; i++) {
14348 if (_adv_asc3550_buf[i] == 0xff) {
14349 for (j = 0; j < _adv_asc3550_buf[i + 1]; j++) {
14350 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14351 _adv_asc3550_buf
14352 [i +
14353 3] << 8) |
14354 _adv_asc3550_buf
14355 [i + 2]));
14356 word++;
14357 }
14358 i += 3;
14359 } else if (_adv_asc3550_buf[i] == 0xfe) {
14360 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14361 _adv_asc3550_buf[i +
14362 2]
14363 << 8) |
14364 _adv_asc3550_buf[i +
14365 1]));
14366 i += 2;
14367 word++;
14368 } else {
14369 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14370 _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) | _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
14371 word++;
14372 }
14373 }
1da177e4 14374
27c868c2
MW
14375 /*
14376 * Set 'word' for later use to clear the rest of memory and save
14377 * the expanded mcode size.
14378 */
14379 word *= 2;
14380 adv_asc3550_expanded_size = word;
14381
14382 /*
14383 * Clear the rest of ASC-3550 Internal RAM (8KB).
14384 */
14385 for (; word < ADV_3550_MEMSIZE; word += 2) {
14386 AdvWriteWordAutoIncLram(iop_base, 0);
14387 }
1da177e4 14388
27c868c2
MW
14389 /*
14390 * Verify the microcode checksum.
14391 */
14392 sum = 0;
14393 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
1da177e4 14394
27c868c2
MW
14395 for (word = 0; word < adv_asc3550_expanded_size; word += 2) {
14396 sum += AdvReadWordAutoIncLram(iop_base);
14397 }
1da177e4 14398
27c868c2
MW
14399 if (sum != _adv_asc3550_chksum) {
14400 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14401 return ADV_ERROR;
14402 }
1da177e4 14403
27c868c2
MW
14404 /*
14405 * Restore the RISC memory BIOS region.
14406 */
14407 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14408 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14409 bios_mem[i]);
14410 }
1da177e4 14411
27c868c2
MW
14412 /*
14413 * Calculate and write the microcode code checksum to the microcode
14414 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14415 */
14416 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14417 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14418 code_sum = 0;
14419 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14420 for (word = begin_addr; word < end_addr; word += 2) {
14421 code_sum += AdvReadWordAutoIncLram(iop_base);
14422 }
14423 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14424
14425 /*
14426 * Read and save microcode version and date.
14427 */
14428 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
14429 asc_dvc->cfg->mcode_date);
14430 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
14431 asc_dvc->cfg->mcode_version);
14432
14433 /*
14434 * Set the chip type to indicate the ASC3550.
14435 */
14436 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
14437
14438 /*
14439 * If the PCI Configuration Command Register "Parity Error Response
14440 * Control" Bit was clear (0), then set the microcode variable
14441 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14442 * to ignore DMA parity errors.
14443 */
14444 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
14445 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14446 word |= CONTROL_FLAG_IGNORE_PERR;
14447 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14448 }
1da177e4 14449
27c868c2
MW
14450 /*
14451 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
14452 * threshold of 128 bytes. This register is only accessible to the host.
14453 */
14454 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14455 START_CTL_EMFU | READ_CMD_MRM);
14456
14457 /*
14458 * Microcode operating variables for WDTR, SDTR, and command tag
14459 * queuing will be set in AdvInquiryHandling() based on what a
14460 * device reports it is capable of in Inquiry byte 7.
14461 *
14462 * If SCSI Bus Resets have been disabled, then directly set
14463 * SDTR and WDTR from the EEPROM configuration. This will allow
14464 * the BIOS and warm boot to work without a SCSI bus hang on
14465 * the Inquiry caused by host and target mismatched DTR values.
14466 * Without the SCSI Bus Reset, before an Inquiry a device can't
14467 * be assumed to be in Asynchronous, Narrow mode.
14468 */
14469 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
14470 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
14471 asc_dvc->wdtr_able);
14472 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
14473 asc_dvc->sdtr_able);
14474 }
1da177e4 14475
27c868c2
MW
14476 /*
14477 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
14478 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
14479 * bitmask. These values determine the maximum SDTR speed negotiated
14480 * with a device.
14481 *
14482 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14483 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14484 * without determining here whether the device supports SDTR.
14485 *
14486 * 4-bit speed SDTR speed name
14487 * =========== ===============
14488 * 0000b (0x0) SDTR disabled
14489 * 0001b (0x1) 5 Mhz
14490 * 0010b (0x2) 10 Mhz
14491 * 0011b (0x3) 20 Mhz (Ultra)
14492 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
14493 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
14494 * 0110b (0x6) Undefined
14495 * .
14496 * 1111b (0xF) Undefined
14497 */
14498 word = 0;
14499 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14500 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
14501 /* Set Ultra speed for TID 'tid'. */
14502 word |= (0x3 << (4 * (tid % 4)));
14503 } else {
14504 /* Set Fast speed for TID 'tid'. */
14505 word |= (0x2 << (4 * (tid % 4)));
14506 }
14507 if (tid == 3) { /* Check if done with sdtr_speed1. */
14508 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
14509 word = 0;
14510 } else if (tid == 7) { /* Check if done with sdtr_speed2. */
14511 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
14512 word = 0;
14513 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
14514 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
14515 word = 0;
14516 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
14517 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
14518 /* End of loop. */
14519 }
14520 }
1da177e4 14521
27c868c2
MW
14522 /*
14523 * Set microcode operating variable for the disconnect per TID bitmask.
14524 */
14525 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
14526 asc_dvc->cfg->disc_enable);
14527
14528 /*
14529 * Set SCSI_CFG0 Microcode Default Value.
14530 *
14531 * The microcode will set the SCSI_CFG0 register using this value
14532 * after it is started below.
14533 */
14534 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14535 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14536 asc_dvc->chip_scsi_id);
14537
14538 /*
14539 * Determine SCSI_CFG1 Microcode Default Value.
14540 *
14541 * The microcode will set the SCSI_CFG1 register using this value
14542 * after it is started below.
14543 */
14544
14545 /* Read current SCSI_CFG1 Register value. */
14546 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14547
14548 /*
14549 * If all three connectors are in use, return an error.
14550 */
14551 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
14552 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
14553 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
14554 return ADV_ERROR;
14555 }
1da177e4 14556
27c868c2
MW
14557 /*
14558 * If the internal narrow cable is reversed all of the SCSI_CTRL
14559 * register signals will be set. Check for and return an error if
14560 * this condition is found.
14561 */
14562 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
14563 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14564 return ADV_ERROR;
14565 }
1da177e4 14566
27c868c2
MW
14567 /*
14568 * If this is a differential board and a single-ended device
14569 * is attached to one of the connectors, return an error.
14570 */
14571 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
14572 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
14573 return ADV_ERROR;
14574 }
1da177e4 14575
27c868c2
MW
14576 /*
14577 * If automatic termination control is enabled, then set the
14578 * termination value based on a table listed in a_condor.h.
14579 *
14580 * If manual termination was specified with an EEPROM setting
14581 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
14582 * is ready to be 'ored' into SCSI_CFG1.
14583 */
14584 if (asc_dvc->cfg->termination == 0) {
14585 /*
14586 * The software always controls termination by setting TERM_CTL_SEL.
14587 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
14588 */
14589 asc_dvc->cfg->termination |= TERM_CTL_SEL;
14590
14591 switch (scsi_cfg1 & CABLE_DETECT) {
14592 /* TERM_CTL_H: on, TERM_CTL_L: on */
14593 case 0x3:
14594 case 0x7:
14595 case 0xB:
14596 case 0xD:
14597 case 0xE:
14598 case 0xF:
14599 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
14600 break;
14601
14602 /* TERM_CTL_H: on, TERM_CTL_L: off */
14603 case 0x1:
14604 case 0x5:
14605 case 0x9:
14606 case 0xA:
14607 case 0xC:
14608 asc_dvc->cfg->termination |= TERM_CTL_H;
14609 break;
14610
14611 /* TERM_CTL_H: off, TERM_CTL_L: off */
14612 case 0x2:
14613 case 0x6:
14614 break;
14615 }
14616 }
1da177e4 14617
27c868c2
MW
14618 /*
14619 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
14620 */
14621 scsi_cfg1 &= ~TERM_CTL;
14622
14623 /*
14624 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
14625 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
14626 * referenced, because the hardware internally inverts
14627 * the Termination High and Low bits if TERM_POL is set.
14628 */
14629 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
14630
14631 /*
14632 * Set SCSI_CFG1 Microcode Default Value
14633 *
14634 * Set filter value and possibly modified termination control
14635 * bits in the Microcode SCSI_CFG1 Register Value.
14636 *
14637 * The microcode will set the SCSI_CFG1 register using this value
14638 * after it is started below.
14639 */
14640 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
14641 FLTR_DISABLE | scsi_cfg1);
14642
14643 /*
14644 * Set MEM_CFG Microcode Default Value
14645 *
14646 * The microcode will set the MEM_CFG register using this value
14647 * after it is started below.
14648 *
14649 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
14650 * are defined.
14651 *
14652 * ASC-3550 has 8KB internal memory.
14653 */
14654 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
14655 BIOS_EN | RAM_SZ_8KB);
14656
14657 /*
14658 * Set SEL_MASK Microcode Default Value
14659 *
14660 * The microcode will set the SEL_MASK register using this value
14661 * after it is started below.
14662 */
14663 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
14664 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
14665
14666 /*
14667 * Build carrier freelist.
14668 *
14669 * Driver must have already allocated memory and set 'carrier_buf'.
14670 */
14671 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
14672
14673 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
14674 asc_dvc->carr_freelist = NULL;
14675 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
14676 buf_size = ADV_CARRIER_BUFSIZE;
14677 } else {
14678 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
14679 }
1da177e4 14680
27c868c2
MW
14681 do {
14682 /*
14683 * Get physical address of the carrier 'carrp'.
14684 */
14685 contig_len = sizeof(ADV_CARR_T);
14686 carr_paddr =
14687 cpu_to_le32(DvcGetPhyAddr
14688 (asc_dvc, NULL, (uchar *)carrp,
14689 (ADV_SDCNT *)&contig_len,
14690 ADV_IS_CARRIER_FLAG));
1da177e4 14691
27c868c2 14692 buf_size -= sizeof(ADV_CARR_T);
1da177e4 14693
27c868c2
MW
14694 /*
14695 * If the current carrier is not physically contiguous, then
14696 * maybe there was a page crossing. Try the next carrier aligned
14697 * start address.
14698 */
14699 if (contig_len < sizeof(ADV_CARR_T)) {
14700 carrp++;
14701 continue;
14702 }
14703
14704 carrp->carr_pa = carr_paddr;
14705 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
1da177e4 14706
27c868c2
MW
14707 /*
14708 * Insert the carrier at the beginning of the freelist.
14709 */
14710 carrp->next_vpa =
14711 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
14712 asc_dvc->carr_freelist = carrp;
1da177e4 14713
27c868c2
MW
14714 carrp++;
14715 }
14716 while (buf_size > 0);
1da177e4 14717
27c868c2
MW
14718 /*
14719 * Set-up the Host->RISC Initiator Command Queue (ICQ).
14720 */
1da177e4 14721
27c868c2
MW
14722 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
14723 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14724 return ADV_ERROR;
14725 }
14726 asc_dvc->carr_freelist = (ADV_CARR_T *)
14727 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
14728
14729 /*
14730 * The first command issued will be placed in the stopper carrier.
14731 */
14732 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14733
14734 /*
14735 * Set RISC ICQ physical address start value.
14736 */
14737 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
14738
14739 /*
14740 * Set-up the RISC->Host Initiator Response Queue (IRQ).
14741 */
14742 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
14743 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14744 return ADV_ERROR;
14745 }
14746 asc_dvc->carr_freelist = (ADV_CARR_T *)
14747 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
14748
14749 /*
14750 * The first command completed by the RISC will be placed in
14751 * the stopper.
14752 *
14753 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
14754 * completed the RISC will set the ASC_RQ_STOPPER bit.
14755 */
14756 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14757
14758 /*
14759 * Set RISC IRQ physical address start value.
14760 */
14761 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
14762 asc_dvc->carr_pending_cnt = 0;
14763
14764 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
14765 (ADV_INTR_ENABLE_HOST_INTR |
14766 ADV_INTR_ENABLE_GLOBAL_INTR));
14767
14768 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
14769 AdvWriteWordRegister(iop_base, IOPW_PC, word);
14770
14771 /* finally, finally, gentlemen, start your engine */
14772 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
14773
14774 /*
14775 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
14776 * Resets should be performed. The RISC has to be running
14777 * to issue a SCSI Bus Reset.
14778 */
14779 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
14780 /*
14781 * If the BIOS Signature is present in memory, restore the
14782 * BIOS Handshake Configuration Table and do not perform
14783 * a SCSI Bus Reset.
14784 */
14785 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
14786 0x55AA) {
14787 /*
14788 * Restore per TID negotiated values.
14789 */
14790 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14791 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14792 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
14793 tagqng_able);
14794 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14795 AdvWriteByteLram(iop_base,
14796 ASC_MC_NUMBER_OF_MAX_CMD + tid,
14797 max_cmd[tid]);
14798 }
14799 } else {
14800 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
14801 warn_code = ASC_WARN_BUSRESET_ERROR;
14802 }
14803 }
14804 }
1da177e4 14805
27c868c2
MW
14806 return warn_code;
14807}
1da177e4 14808
27c868c2
MW
14809/*
14810 * Initialize the ASC-38C0800.
14811 *
14812 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14813 *
14814 * For a non-fatal error return a warning code. If there are no warnings
14815 * then 0 is returned.
14816 *
14817 * Needed after initialization for error recovery.
14818 */
14819static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
14820{
14821 AdvPortAddr iop_base;
14822 ushort warn_code;
14823 ADV_DCNT sum;
14824 int begin_addr;
14825 int end_addr;
14826 ushort code_sum;
14827 int word;
14828 int j;
14829 int adv_asc38C0800_expanded_size;
14830 ADV_CARR_T *carrp;
14831 ADV_DCNT contig_len;
14832 ADV_SDCNT buf_size;
14833 ADV_PADDR carr_paddr;
14834 int i;
14835 ushort scsi_cfg1;
14836 uchar byte;
14837 uchar tid;
14838 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
14839 ushort wdtr_able, sdtr_able, tagqng_able;
14840 uchar max_cmd[ADV_MAX_TID + 1];
14841
14842 /* If there is already an error, don't continue. */
14843 if (asc_dvc->err_code != 0) {
14844 return ADV_ERROR;
14845 }
1da177e4 14846
27c868c2
MW
14847 /*
14848 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
14849 */
14850 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
14851 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
14852 return ADV_ERROR;
14853 }
1da177e4 14854
27c868c2
MW
14855 warn_code = 0;
14856 iop_base = asc_dvc->iop_base;
14857
14858 /*
14859 * Save the RISC memory BIOS region before writing the microcode.
14860 * The BIOS may already be loaded and using its RISC LRAM region
14861 * so its region must be saved and restored.
14862 *
14863 * Note: This code makes the assumption, which is currently true,
14864 * that a chip reset does not clear RISC LRAM.
14865 */
14866 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14867 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14868 bios_mem[i]);
14869 }
1da177e4 14870
27c868c2
MW
14871 /*
14872 * Save current per TID negotiated values.
14873 */
14874 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14875 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14876 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14877 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14878 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14879 max_cmd[tid]);
14880 }
1da177e4 14881
27c868c2
MW
14882 /*
14883 * RAM BIST (RAM Built-In Self Test)
14884 *
14885 * Address : I/O base + offset 0x38h register (byte).
14886 * Function: Bit 7-6(RW) : RAM mode
14887 * Normal Mode : 0x00
14888 * Pre-test Mode : 0x40
14889 * RAM Test Mode : 0x80
14890 * Bit 5 : unused
14891 * Bit 4(RO) : Done bit
14892 * Bit 3-0(RO) : Status
14893 * Host Error : 0x08
14894 * Int_RAM Error : 0x04
14895 * RISC Error : 0x02
14896 * SCSI Error : 0x01
14897 * No Error : 0x00
14898 *
14899 * Note: RAM BIST code should be put right here, before loading the
14900 * microcode and after saving the RISC memory BIOS region.
14901 */
14902
14903 /*
14904 * LRAM Pre-test
14905 *
14906 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
14907 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
14908 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
14909 * to NORMAL_MODE, return an error too.
14910 */
14911 for (i = 0; i < 2; i++) {
14912 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
14913 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14914 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14915 if ((byte & RAM_TEST_DONE) == 0
14916 || (byte & 0x0F) != PRE_TEST_VALUE) {
14917 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14918 return ADV_ERROR;
14919 }
14920
14921 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14922 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14923 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
14924 != NORMAL_VALUE) {
14925 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14926 return ADV_ERROR;
14927 }
14928 }
1da177e4 14929
27c868c2
MW
14930 /*
14931 * LRAM Test - It takes about 1.5 ms to run through the test.
14932 *
14933 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
14934 * If Done bit not set or Status not 0, save register byte, set the
14935 * err_code, and return an error.
14936 */
14937 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
14938 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
14939
14940 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14941 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
14942 /* Get here if Done bit not set or Status not 0. */
14943 asc_dvc->bist_err_code = byte; /* for BIOS display message */
14944 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
14945 return ADV_ERROR;
14946 }
1da177e4 14947
27c868c2
MW
14948 /* We need to reset back to normal mode after LRAM test passes. */
14949 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14950
14951 /*
14952 * Load the Microcode
14953 *
14954 * Write the microcode image to RISC memory starting at address 0.
14955 *
14956 */
14957 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14958
14959 /* Assume the following compressed format of the microcode buffer:
14960 *
14961 * 254 word (508 byte) table indexed by byte code followed
14962 * by the following byte codes:
14963 *
14964 * 1-Byte Code:
14965 * 00: Emit word 0 in table.
14966 * 01: Emit word 1 in table.
14967 * .
14968 * FD: Emit word 253 in table.
14969 *
14970 * Multi-Byte Code:
14971 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14972 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14973 */
14974 word = 0;
14975 for (i = 253 * 2; i < _adv_asc38C0800_size; i++) {
14976 if (_adv_asc38C0800_buf[i] == 0xff) {
14977 for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++) {
14978 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14979 _adv_asc38C0800_buf
14980 [i +
14981 3] << 8) |
14982 _adv_asc38C0800_buf
14983 [i + 2]));
14984 word++;
14985 }
14986 i += 3;
14987 } else if (_adv_asc38C0800_buf[i] == 0xfe) {
14988 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14989 _adv_asc38C0800_buf
14990 [i +
14991 2] << 8) |
14992 _adv_asc38C0800_buf[i
14993 +
14994 1]));
14995 i += 2;
14996 word++;
14997 } else {
14998 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14999 _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) | _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
15000 word++;
15001 }
15002 }
1da177e4 15003
27c868c2
MW
15004 /*
15005 * Set 'word' for later use to clear the rest of memory and save
15006 * the expanded mcode size.
15007 */
15008 word *= 2;
15009 adv_asc38C0800_expanded_size = word;
15010
15011 /*
15012 * Clear the rest of ASC-38C0800 Internal RAM (16KB).
15013 */
15014 for (; word < ADV_38C0800_MEMSIZE; word += 2) {
15015 AdvWriteWordAutoIncLram(iop_base, 0);
15016 }
1da177e4 15017
27c868c2
MW
15018 /*
15019 * Verify the microcode checksum.
15020 */
15021 sum = 0;
15022 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
1da177e4 15023
27c868c2
MW
15024 for (word = 0; word < adv_asc38C0800_expanded_size; word += 2) {
15025 sum += AdvReadWordAutoIncLram(iop_base);
15026 }
15027 ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
1da177e4 15028
27c868c2
MW
15029 ASC_DBG2(1,
15030 "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
15031 (ulong)sum, (ulong)_adv_asc38C0800_chksum);
1da177e4 15032
27c868c2
MW
15033 if (sum != _adv_asc38C0800_chksum) {
15034 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15035 return ADV_ERROR;
15036 }
1da177e4 15037
27c868c2
MW
15038 /*
15039 * Restore the RISC memory BIOS region.
15040 */
15041 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15042 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15043 bios_mem[i]);
15044 }
1da177e4 15045
27c868c2
MW
15046 /*
15047 * Calculate and write the microcode code checksum to the microcode
15048 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15049 */
15050 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15051 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15052 code_sum = 0;
15053 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15054 for (word = begin_addr; word < end_addr; word += 2) {
15055 code_sum += AdvReadWordAutoIncLram(iop_base);
15056 }
15057 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15058
15059 /*
15060 * Read microcode version and date.
15061 */
15062 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
15063 asc_dvc->cfg->mcode_date);
15064 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
15065 asc_dvc->cfg->mcode_version);
15066
15067 /*
15068 * Set the chip type to indicate the ASC38C0800.
15069 */
15070 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
15071
15072 /*
15073 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15074 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15075 * cable detection and then we are able to read C_DET[3:0].
15076 *
15077 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15078 * Microcode Default Value' section below.
15079 */
15080 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15081 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
15082 scsi_cfg1 | DIS_TERM_DRV);
15083
15084 /*
15085 * If the PCI Configuration Command Register "Parity Error Response
15086 * Control" Bit was clear (0), then set the microcode variable
15087 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15088 * to ignore DMA parity errors.
15089 */
15090 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
15091 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15092 word |= CONTROL_FLAG_IGNORE_PERR;
15093 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15094 }
1da177e4 15095
27c868c2
MW
15096 /*
15097 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
15098 * bits for the default FIFO threshold.
15099 *
15100 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
15101 *
15102 * For DMA Errata #4 set the BC_THRESH_ENB bit.
15103 */
15104 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15105 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
15106 READ_CMD_MRM);
15107
15108 /*
15109 * Microcode operating variables for WDTR, SDTR, and command tag
15110 * queuing will be set in AdvInquiryHandling() based on what a
15111 * device reports it is capable of in Inquiry byte 7.
15112 *
15113 * If SCSI Bus Resets have been disabled, then directly set
15114 * SDTR and WDTR from the EEPROM configuration. This will allow
15115 * the BIOS and warm boot to work without a SCSI bus hang on
15116 * the Inquiry caused by host and target mismatched DTR values.
15117 * Without the SCSI Bus Reset, before an Inquiry a device can't
15118 * be assumed to be in Asynchronous, Narrow mode.
15119 */
15120 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
15121 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
15122 asc_dvc->wdtr_able);
15123 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
15124 asc_dvc->sdtr_able);
15125 }
1da177e4 15126
27c868c2
MW
15127 /*
15128 * Set microcode operating variables for DISC and SDTR_SPEED1,
15129 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15130 * configuration values.
15131 *
15132 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15133 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15134 * without determining here whether the device supports SDTR.
15135 */
15136 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
15137 asc_dvc->cfg->disc_enable);
15138 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15139 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15140 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15141 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15142
15143 /*
15144 * Set SCSI_CFG0 Microcode Default Value.
15145 *
15146 * The microcode will set the SCSI_CFG0 register using this value
15147 * after it is started below.
15148 */
15149 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15150 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15151 asc_dvc->chip_scsi_id);
15152
15153 /*
15154 * Determine SCSI_CFG1 Microcode Default Value.
15155 *
15156 * The microcode will set the SCSI_CFG1 register using this value
15157 * after it is started below.
15158 */
15159
15160 /* Read current SCSI_CFG1 Register value. */
15161 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15162
15163 /*
15164 * If the internal narrow cable is reversed all of the SCSI_CTRL
15165 * register signals will be set. Check for and return an error if
15166 * this condition is found.
15167 */
15168 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
15169 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15170 return ADV_ERROR;
15171 }
1da177e4 15172
27c868c2
MW
15173 /*
15174 * All kind of combinations of devices attached to one of four connectors
15175 * are acceptable except HVD device attached. For example, LVD device can
15176 * be attached to SE connector while SE device attached to LVD connector.
15177 * If LVD device attached to SE connector, it only runs up to Ultra speed.
15178 *
15179 * If an HVD device is attached to one of LVD connectors, return an error.
15180 * However, there is no way to detect HVD device attached to SE connectors.
15181 */
15182 if (scsi_cfg1 & HVD) {
15183 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15184 return ADV_ERROR;
15185 }
1da177e4 15186
27c868c2
MW
15187 /*
15188 * If either SE or LVD automatic termination control is enabled, then
15189 * set the termination value based on a table listed in a_condor.h.
15190 *
15191 * If manual termination was specified with an EEPROM setting then
15192 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
15193 * be 'ored' into SCSI_CFG1.
15194 */
15195 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
15196 /* SE automatic termination control is enabled. */
15197 switch (scsi_cfg1 & C_DET_SE) {
15198 /* TERM_SE_HI: on, TERM_SE_LO: on */
15199 case 0x1:
15200 case 0x2:
15201 case 0x3:
15202 asc_dvc->cfg->termination |= TERM_SE;
15203 break;
15204
15205 /* TERM_SE_HI: on, TERM_SE_LO: off */
15206 case 0x0:
15207 asc_dvc->cfg->termination |= TERM_SE_HI;
15208 break;
15209 }
15210 }
15211
15212 if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
15213 /* LVD automatic termination control is enabled. */
15214 switch (scsi_cfg1 & C_DET_LVD) {
15215 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
15216 case 0x4:
15217 case 0x8:
15218 case 0xC:
15219 asc_dvc->cfg->termination |= TERM_LVD;
15220 break;
15221
15222 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
15223 case 0x0:
15224 break;
15225 }
15226 }
15227
15228 /*
15229 * Clear any set TERM_SE and TERM_LVD bits.
15230 */
15231 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
15232
15233 /*
15234 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
15235 */
15236 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
15237
15238 /*
15239 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
15240 * and set possibly modified termination control bits in the Microcode
15241 * SCSI_CFG1 Register Value.
15242 */
15243 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
15244
15245 /*
15246 * Set SCSI_CFG1 Microcode Default Value
15247 *
15248 * Set possibly modified termination control and reset DIS_TERM_DRV
15249 * bits in the Microcode SCSI_CFG1 Register Value.
15250 *
15251 * The microcode will set the SCSI_CFG1 register using this value
15252 * after it is started below.
15253 */
15254 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15255
15256 /*
15257 * Set MEM_CFG Microcode Default Value
15258 *
15259 * The microcode will set the MEM_CFG register using this value
15260 * after it is started below.
15261 *
15262 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15263 * are defined.
15264 *
15265 * ASC-38C0800 has 16KB internal memory.
15266 */
15267 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15268 BIOS_EN | RAM_SZ_16KB);
15269
15270 /*
15271 * Set SEL_MASK Microcode Default Value
15272 *
15273 * The microcode will set the SEL_MASK register using this value
15274 * after it is started below.
15275 */
15276 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15277 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15278
15279 /*
15280 * Build the carrier freelist.
15281 *
15282 * Driver must have already allocated memory and set 'carrier_buf'.
15283 */
15284 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15285
15286 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15287 asc_dvc->carr_freelist = NULL;
15288 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
15289 buf_size = ADV_CARRIER_BUFSIZE;
15290 } else {
15291 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15292 }
15293
15294 do {
15295 /*
15296 * Get physical address for the carrier 'carrp'.
15297 */
15298 contig_len = sizeof(ADV_CARR_T);
15299 carr_paddr =
15300 cpu_to_le32(DvcGetPhyAddr
15301 (asc_dvc, NULL, (uchar *)carrp,
15302 (ADV_SDCNT *)&contig_len,
15303 ADV_IS_CARRIER_FLAG));
1da177e4 15304
27c868c2
MW
15305 buf_size -= sizeof(ADV_CARR_T);
15306
15307 /*
15308 * If the current carrier is not physically contiguous, then
15309 * maybe there was a page crossing. Try the next carrier aligned
15310 * start address.
15311 */
15312 if (contig_len < sizeof(ADV_CARR_T)) {
15313 carrp++;
15314 continue;
15315 }
15316
15317 carrp->carr_pa = carr_paddr;
15318 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15319
15320 /*
15321 * Insert the carrier at the beginning of the freelist.
15322 */
15323 carrp->next_vpa =
15324 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15325 asc_dvc->carr_freelist = carrp;
15326
15327 carrp++;
15328 }
15329 while (buf_size > 0);
15330
15331 /*
15332 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15333 */
15334
15335 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
15336 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15337 return ADV_ERROR;
15338 }
15339 asc_dvc->carr_freelist = (ADV_CARR_T *)
15340 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15341
15342 /*
15343 * The first command issued will be placed in the stopper carrier.
15344 */
15345 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15346
15347 /*
15348 * Set RISC ICQ physical address start value.
15349 * carr_pa is LE, must be native before write
15350 */
15351 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15352
15353 /*
15354 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15355 */
15356 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
15357 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15358 return ADV_ERROR;
15359 }
15360 asc_dvc->carr_freelist = (ADV_CARR_T *)
15361 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15362
15363 /*
15364 * The first command completed by the RISC will be placed in
15365 * the stopper.
15366 *
15367 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15368 * completed the RISC will set the ASC_RQ_STOPPER bit.
15369 */
15370 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15371
15372 /*
15373 * Set RISC IRQ physical address start value.
15374 *
15375 * carr_pa is LE, must be native before write *
15376 */
15377 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15378 asc_dvc->carr_pending_cnt = 0;
15379
15380 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15381 (ADV_INTR_ENABLE_HOST_INTR |
15382 ADV_INTR_ENABLE_GLOBAL_INTR));
15383
15384 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15385 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15386
15387 /* finally, finally, gentlemen, start your engine */
15388 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15389
15390 /*
15391 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15392 * Resets should be performed. The RISC has to be running
15393 * to issue a SCSI Bus Reset.
15394 */
15395 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
15396 /*
15397 * If the BIOS Signature is present in memory, restore the
15398 * BIOS Handshake Configuration Table and do not perform
15399 * a SCSI Bus Reset.
15400 */
15401 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
15402 0x55AA) {
15403 /*
15404 * Restore per TID negotiated values.
15405 */
15406 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15407 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15408 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
15409 tagqng_able);
15410 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
15411 AdvWriteByteLram(iop_base,
15412 ASC_MC_NUMBER_OF_MAX_CMD + tid,
15413 max_cmd[tid]);
15414 }
15415 } else {
15416 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
15417 warn_code = ASC_WARN_BUSRESET_ERROR;
15418 }
15419 }
15420 }
15421
15422 return warn_code;
1da177e4
LT
15423}
15424
15425/*
27c868c2 15426 * Initialize the ASC-38C1600.
1da177e4 15427 *
27c868c2 15428 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
1da177e4
LT
15429 *
15430 * For a non-fatal error return a warning code. If there are no warnings
15431 * then 0 is returned.
15432 *
15433 * Needed after initialization for error recovery.
15434 */
27c868c2 15435static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
1da177e4 15436{
27c868c2
MW
15437 AdvPortAddr iop_base;
15438 ushort warn_code;
15439 ADV_DCNT sum;
15440 int begin_addr;
15441 int end_addr;
15442 ushort code_sum;
15443 long word;
15444 int j;
15445 int adv_asc38C1600_expanded_size;
15446 ADV_CARR_T *carrp;
15447 ADV_DCNT contig_len;
15448 ADV_SDCNT buf_size;
15449 ADV_PADDR carr_paddr;
15450 int i;
15451 ushort scsi_cfg1;
15452 uchar byte;
15453 uchar tid;
15454 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
15455 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
15456 uchar max_cmd[ASC_MAX_TID + 1];
15457
15458 /* If there is already an error, don't continue. */
15459 if (asc_dvc->err_code != 0) {
15460 return ADV_ERROR;
15461 }
1da177e4 15462
27c868c2
MW
15463 /*
15464 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
15465 */
15466 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
15467 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
15468 return ADV_ERROR;
15469 }
1da177e4 15470
27c868c2
MW
15471 warn_code = 0;
15472 iop_base = asc_dvc->iop_base;
15473
15474 /*
15475 * Save the RISC memory BIOS region before writing the microcode.
15476 * The BIOS may already be loaded and using its RISC LRAM region
15477 * so its region must be saved and restored.
15478 *
15479 * Note: This code makes the assumption, which is currently true,
15480 * that a chip reset does not clear RISC LRAM.
15481 */
15482 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15483 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15484 bios_mem[i]);
15485 }
1da177e4 15486
27c868c2
MW
15487 /*
15488 * Save current per TID negotiated values.
15489 */
15490 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15491 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15492 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15493 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15494 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15495 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15496 max_cmd[tid]);
15497 }
1da177e4 15498
27c868c2
MW
15499 /*
15500 * RAM BIST (Built-In Self Test)
15501 *
15502 * Address : I/O base + offset 0x38h register (byte).
15503 * Function: Bit 7-6(RW) : RAM mode
15504 * Normal Mode : 0x00
15505 * Pre-test Mode : 0x40
15506 * RAM Test Mode : 0x80
15507 * Bit 5 : unused
15508 * Bit 4(RO) : Done bit
15509 * Bit 3-0(RO) : Status
15510 * Host Error : 0x08
15511 * Int_RAM Error : 0x04
15512 * RISC Error : 0x02
15513 * SCSI Error : 0x01
15514 * No Error : 0x00
15515 *
15516 * Note: RAM BIST code should be put right here, before loading the
15517 * microcode and after saving the RISC memory BIOS region.
15518 */
15519
15520 /*
15521 * LRAM Pre-test
15522 *
15523 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15524 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15525 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15526 * to NORMAL_MODE, return an error too.
15527 */
15528 for (i = 0; i < 2; i++) {
15529 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15530 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15531 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15532 if ((byte & RAM_TEST_DONE) == 0
15533 || (byte & 0x0F) != PRE_TEST_VALUE) {
15534 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15535 return ADV_ERROR;
15536 }
15537
15538 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15539 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15540 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15541 != NORMAL_VALUE) {
15542 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15543 return ADV_ERROR;
15544 }
15545 }
1da177e4 15546
27c868c2
MW
15547 /*
15548 * LRAM Test - It takes about 1.5 ms to run through the test.
15549 *
15550 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15551 * If Done bit not set or Status not 0, save register byte, set the
15552 * err_code, and return an error.
15553 */
15554 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15555 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
15556
15557 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15558 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
15559 /* Get here if Done bit not set or Status not 0. */
15560 asc_dvc->bist_err_code = byte; /* for BIOS display message */
15561 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15562 return ADV_ERROR;
15563 }
1da177e4 15564
27c868c2
MW
15565 /* We need to reset back to normal mode after LRAM test passes. */
15566 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15567
15568 /*
15569 * Load the Microcode
15570 *
15571 * Write the microcode image to RISC memory starting at address 0.
15572 *
15573 */
15574 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15575
15576 /*
15577 * Assume the following compressed format of the microcode buffer:
15578 *
15579 * 254 word (508 byte) table indexed by byte code followed
15580 * by the following byte codes:
15581 *
15582 * 1-Byte Code:
15583 * 00: Emit word 0 in table.
15584 * 01: Emit word 1 in table.
15585 * .
15586 * FD: Emit word 253 in table.
15587 *
15588 * Multi-Byte Code:
15589 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15590 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15591 */
15592 word = 0;
15593 for (i = 253 * 2; i < _adv_asc38C1600_size; i++) {
15594 if (_adv_asc38C1600_buf[i] == 0xff) {
15595 for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++) {
15596 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15597 _adv_asc38C1600_buf
15598 [i +
15599 3] << 8) |
15600 _adv_asc38C1600_buf
15601 [i + 2]));
15602 word++;
15603 }
15604 i += 3;
15605 } else if (_adv_asc38C1600_buf[i] == 0xfe) {
15606 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15607 _adv_asc38C1600_buf
15608 [i +
15609 2] << 8) |
15610 _adv_asc38C1600_buf[i
15611 +
15612 1]));
15613 i += 2;
15614 word++;
15615 } else {
15616 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15617 _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) | _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
15618 word++;
15619 }
15620 }
1da177e4 15621
27c868c2
MW
15622 /*
15623 * Set 'word' for later use to clear the rest of memory and save
15624 * the expanded mcode size.
15625 */
15626 word *= 2;
15627 adv_asc38C1600_expanded_size = word;
15628
15629 /*
15630 * Clear the rest of ASC-38C1600 Internal RAM (32KB).
15631 */
15632 for (; word < ADV_38C1600_MEMSIZE; word += 2) {
15633 AdvWriteWordAutoIncLram(iop_base, 0);
15634 }
1da177e4 15635
27c868c2
MW
15636 /*
15637 * Verify the microcode checksum.
15638 */
15639 sum = 0;
15640 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
1da177e4 15641
27c868c2
MW
15642 for (word = 0; word < adv_asc38C1600_expanded_size; word += 2) {
15643 sum += AdvReadWordAutoIncLram(iop_base);
15644 }
1da177e4 15645
27c868c2
MW
15646 if (sum != _adv_asc38C1600_chksum) {
15647 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15648 return ADV_ERROR;
15649 }
1da177e4 15650
27c868c2
MW
15651 /*
15652 * Restore the RISC memory BIOS region.
15653 */
15654 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15655 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15656 bios_mem[i]);
15657 }
1da177e4 15658
27c868c2
MW
15659 /*
15660 * Calculate and write the microcode code checksum to the microcode
15661 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15662 */
15663 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15664 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15665 code_sum = 0;
15666 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15667 for (word = begin_addr; word < end_addr; word += 2) {
15668 code_sum += AdvReadWordAutoIncLram(iop_base);
15669 }
15670 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15671
15672 /*
15673 * Read microcode version and date.
15674 */
15675 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
15676 asc_dvc->cfg->mcode_date);
15677 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
15678 asc_dvc->cfg->mcode_version);
15679
15680 /*
15681 * Set the chip type to indicate the ASC38C1600.
15682 */
15683 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
15684
15685 /*
15686 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15687 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15688 * cable detection and then we are able to read C_DET[3:0].
15689 *
15690 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15691 * Microcode Default Value' section below.
15692 */
15693 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15694 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
15695 scsi_cfg1 | DIS_TERM_DRV);
15696
15697 /*
15698 * If the PCI Configuration Command Register "Parity Error Response
15699 * Control" Bit was clear (0), then set the microcode variable
15700 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15701 * to ignore DMA parity errors.
15702 */
15703 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
15704 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15705 word |= CONTROL_FLAG_IGNORE_PERR;
15706 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15707 }
1da177e4 15708
27c868c2
MW
15709 /*
15710 * If the BIOS control flag AIPP (Asynchronous Information
15711 * Phase Protection) disable bit is not set, then set the firmware
15712 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
15713 * AIPP checking and encoding.
15714 */
15715 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
15716 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15717 word |= CONTROL_FLAG_ENABLE_AIPP;
15718 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15719 }
1da177e4 15720
27c868c2
MW
15721 /*
15722 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
15723 * and START_CTL_TH [3:2].
15724 */
15725 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15726 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
15727
15728 /*
15729 * Microcode operating variables for WDTR, SDTR, and command tag
15730 * queuing will be set in AdvInquiryHandling() based on what a
15731 * device reports it is capable of in Inquiry byte 7.
15732 *
15733 * If SCSI Bus Resets have been disabled, then directly set
15734 * SDTR and WDTR from the EEPROM configuration. This will allow
15735 * the BIOS and warm boot to work without a SCSI bus hang on
15736 * the Inquiry caused by host and target mismatched DTR values.
15737 * Without the SCSI Bus Reset, before an Inquiry a device can't
15738 * be assumed to be in Asynchronous, Narrow mode.
15739 */
15740 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
15741 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
15742 asc_dvc->wdtr_able);
15743 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
15744 asc_dvc->sdtr_able);
15745 }
1da177e4 15746
27c868c2
MW
15747 /*
15748 * Set microcode operating variables for DISC and SDTR_SPEED1,
15749 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15750 * configuration values.
15751 *
15752 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15753 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15754 * without determining here whether the device supports SDTR.
15755 */
15756 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
15757 asc_dvc->cfg->disc_enable);
15758 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15759 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15760 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15761 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15762
15763 /*
15764 * Set SCSI_CFG0 Microcode Default Value.
15765 *
15766 * The microcode will set the SCSI_CFG0 register using this value
15767 * after it is started below.
15768 */
15769 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15770 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15771 asc_dvc->chip_scsi_id);
15772
15773 /*
15774 * Calculate SCSI_CFG1 Microcode Default Value.
15775 *
15776 * The microcode will set the SCSI_CFG1 register using this value
15777 * after it is started below.
15778 *
15779 * Each ASC-38C1600 function has only two cable detect bits.
15780 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
15781 */
15782 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15783
15784 /*
15785 * If the cable is reversed all of the SCSI_CTRL register signals
15786 * will be set. Check for and return an error if this condition is
15787 * found.
15788 */
15789 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
15790 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15791 return ADV_ERROR;
15792 }
1da177e4 15793
27c868c2
MW
15794 /*
15795 * Each ASC-38C1600 function has two connectors. Only an HVD device
15796 * can not be connected to either connector. An LVD device or SE device
15797 * may be connected to either connecor. If an SE device is connected,
15798 * then at most Ultra speed (20 Mhz) can be used on both connectors.
15799 *
15800 * If an HVD device is attached, return an error.
15801 */
15802 if (scsi_cfg1 & HVD) {
15803 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15804 return ADV_ERROR;
15805 }
1da177e4 15806
27c868c2
MW
15807 /*
15808 * Each function in the ASC-38C1600 uses only the SE cable detect and
15809 * termination because there are two connectors for each function. Each
15810 * function may use either LVD or SE mode. Corresponding the SE automatic
15811 * termination control EEPROM bits are used for each function. Each
15812 * function has its own EEPROM. If SE automatic control is enabled for
15813 * the function, then set the termination value based on a table listed
15814 * in a_condor.h.
15815 *
15816 * If manual termination is specified in the EEPROM for the function,
15817 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
15818 * ready to be 'ored' into SCSI_CFG1.
15819 */
15820 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
15821 /* SE automatic termination control is enabled. */
15822 switch (scsi_cfg1 & C_DET_SE) {
15823 /* TERM_SE_HI: on, TERM_SE_LO: on */
15824 case 0x1:
15825 case 0x2:
15826 case 0x3:
15827 asc_dvc->cfg->termination |= TERM_SE;
15828 break;
15829
15830 case 0x0:
15831 if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0) {
15832 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
15833 } else {
15834 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
15835 asc_dvc->cfg->termination |= TERM_SE_HI;
15836 }
15837 break;
15838 }
15839 }
1da177e4 15840
27c868c2
MW
15841 /*
15842 * Clear any set TERM_SE bits.
15843 */
15844 scsi_cfg1 &= ~TERM_SE;
15845
15846 /*
15847 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
15848 */
15849 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
15850
15851 /*
15852 * Clear Big Endian and Terminator Polarity bits and set possibly
15853 * modified termination control bits in the Microcode SCSI_CFG1
15854 * Register Value.
15855 *
15856 * Big Endian bit is not used even on big endian machines.
15857 */
15858 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
15859
15860 /*
15861 * Set SCSI_CFG1 Microcode Default Value
15862 *
15863 * Set possibly modified termination control bits in the Microcode
15864 * SCSI_CFG1 Register Value.
15865 *
15866 * The microcode will set the SCSI_CFG1 register using this value
15867 * after it is started below.
15868 */
15869 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15870
15871 /*
15872 * Set MEM_CFG Microcode Default Value
15873 *
15874 * The microcode will set the MEM_CFG register using this value
15875 * after it is started below.
15876 *
15877 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15878 * are defined.
15879 *
15880 * ASC-38C1600 has 32KB internal memory.
15881 *
15882 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
15883 * out a special 16K Adv Library and Microcode version. After the issue
15884 * resolved, we should turn back to the 32K support. Both a_condor.h and
15885 * mcode.sas files also need to be updated.
15886 *
15887 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15888 * BIOS_EN | RAM_SZ_32KB);
15889 */
15890 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15891 BIOS_EN | RAM_SZ_16KB);
15892
15893 /*
15894 * Set SEL_MASK Microcode Default Value
15895 *
15896 * The microcode will set the SEL_MASK register using this value
15897 * after it is started below.
15898 */
15899 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15900 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15901
15902 /*
15903 * Build the carrier freelist.
15904 *
15905 * Driver must have already allocated memory and set 'carrier_buf'.
15906 */
15907
15908 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15909
15910 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15911 asc_dvc->carr_freelist = NULL;
15912 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
15913 buf_size = ADV_CARRIER_BUFSIZE;
15914 } else {
15915 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15916 }
1da177e4 15917
27c868c2
MW
15918 do {
15919 /*
15920 * Get physical address for the carrier 'carrp'.
15921 */
15922 contig_len = sizeof(ADV_CARR_T);
15923 carr_paddr =
15924 cpu_to_le32(DvcGetPhyAddr
15925 (asc_dvc, NULL, (uchar *)carrp,
15926 (ADV_SDCNT *)&contig_len,
15927 ADV_IS_CARRIER_FLAG));
1da177e4 15928
27c868c2 15929 buf_size -= sizeof(ADV_CARR_T);
1da177e4 15930
27c868c2
MW
15931 /*
15932 * If the current carrier is not physically contiguous, then
15933 * maybe there was a page crossing. Try the next carrier aligned
15934 * start address.
15935 */
15936 if (contig_len < sizeof(ADV_CARR_T)) {
15937 carrp++;
15938 continue;
15939 }
15940
15941 carrp->carr_pa = carr_paddr;
15942 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
1da177e4 15943
27c868c2
MW
15944 /*
15945 * Insert the carrier at the beginning of the freelist.
15946 */
15947 carrp->next_vpa =
15948 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15949 asc_dvc->carr_freelist = carrp;
1da177e4 15950
27c868c2
MW
15951 carrp++;
15952 }
15953 while (buf_size > 0);
15954
15955 /*
15956 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15957 */
15958 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
15959 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15960 return ADV_ERROR;
15961 }
15962 asc_dvc->carr_freelist = (ADV_CARR_T *)
15963 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15964
15965 /*
15966 * The first command issued will be placed in the stopper carrier.
15967 */
15968 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15969
15970 /*
15971 * Set RISC ICQ physical address start value. Initialize the
15972 * COMMA register to the same value otherwise the RISC will
15973 * prematurely detect a command is available.
15974 */
15975 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15976 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
15977 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
15978
15979 /*
15980 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15981 */
15982 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
15983 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15984 return ADV_ERROR;
15985 }
15986 asc_dvc->carr_freelist = (ADV_CARR_T *)
15987 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15988
15989 /*
15990 * The first command completed by the RISC will be placed in
15991 * the stopper.
15992 *
15993 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15994 * completed the RISC will set the ASC_RQ_STOPPER bit.
15995 */
15996 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15997
15998 /*
15999 * Set RISC IRQ physical address start value.
16000 */
16001 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
16002 asc_dvc->carr_pending_cnt = 0;
16003
16004 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
16005 (ADV_INTR_ENABLE_HOST_INTR |
16006 ADV_INTR_ENABLE_GLOBAL_INTR));
16007 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
16008 AdvWriteWordRegister(iop_base, IOPW_PC, word);
16009
16010 /* finally, finally, gentlemen, start your engine */
16011 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
16012
16013 /*
16014 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
16015 * Resets should be performed. The RISC has to be running
16016 * to issue a SCSI Bus Reset.
16017 */
16018 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
16019 /*
16020 * If the BIOS Signature is present in memory, restore the
16021 * per TID microcode operating variables.
16022 */
16023 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
16024 0x55AA) {
16025 /*
16026 * Restore per TID negotiated values.
16027 */
16028 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16029 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16030 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16031 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
16032 tagqng_able);
16033 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
16034 AdvWriteByteLram(iop_base,
16035 ASC_MC_NUMBER_OF_MAX_CMD + tid,
16036 max_cmd[tid]);
16037 }
16038 } else {
16039 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
16040 warn_code = ASC_WARN_BUSRESET_ERROR;
16041 }
16042 }
16043 }
1da177e4 16044
27c868c2
MW
16045 return warn_code;
16046}
1da177e4 16047
27c868c2
MW
16048/*
16049 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16050 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16051 * all of this is done.
16052 *
16053 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16054 *
16055 * For a non-fatal error return a warning code. If there are no warnings
16056 * then 0 is returned.
16057 *
16058 * Note: Chip is stopped on entry.
16059 */
16060static int __init AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
16061{
16062 AdvPortAddr iop_base;
16063 ushort warn_code;
16064 ADVEEP_3550_CONFIG eep_config;
16065 int i;
1da177e4 16066
27c868c2 16067 iop_base = asc_dvc->iop_base;
1da177e4 16068
27c868c2 16069 warn_code = 0;
1da177e4 16070
27c868c2
MW
16071 /*
16072 * Read the board's EEPROM configuration.
16073 *
16074 * Set default values if a bad checksum is found.
16075 */
16076 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
16077 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 16078
27c868c2
MW
16079 /*
16080 * Set EEPROM default values.
16081 */
16082 for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++) {
16083 *((uchar *)&eep_config + i) =
16084 *((uchar *)&Default_3550_EEPROM_Config + i);
16085 }
1da177e4 16086
27c868c2
MW
16087 /*
16088 * Assume the 6 byte board serial number that was read
16089 * from EEPROM is correct even if the EEPROM checksum
16090 * failed.
16091 */
16092 eep_config.serial_number_word3 =
16093 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 16094
27c868c2
MW
16095 eep_config.serial_number_word2 =
16096 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
1da177e4 16097
27c868c2
MW
16098 eep_config.serial_number_word1 =
16099 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 16100
27c868c2
MW
16101 AdvSet3550EEPConfig(iop_base, &eep_config);
16102 }
16103 /*
16104 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16105 * EEPROM configuration that was read.
16106 *
16107 * This is the mapping of EEPROM fields to Adv Library fields.
16108 */
16109 asc_dvc->wdtr_able = eep_config.wdtr_able;
16110 asc_dvc->sdtr_able = eep_config.sdtr_able;
16111 asc_dvc->ultra_able = eep_config.ultra_able;
16112 asc_dvc->tagqng_able = eep_config.tagqng_able;
16113 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16114 asc_dvc->max_host_qng = eep_config.max_host_qng;
16115 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16116 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16117 asc_dvc->start_motor = eep_config.start_motor;
16118 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16119 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16120 asc_dvc->no_scam = eep_config.scam_tolerant;
16121 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16122 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16123 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16124
16125 /*
16126 * Set the host maximum queuing (max. 253, min. 16) and the per device
16127 * maximum queuing (max. 63, min. 4).
16128 */
16129 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
16130 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16131 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
16132 /* If the value is zero, assume it is uninitialized. */
16133 if (eep_config.max_host_qng == 0) {
16134 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16135 } else {
16136 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16137 }
16138 }
1da177e4 16139
27c868c2
MW
16140 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
16141 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16142 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
16143 /* If the value is zero, assume it is uninitialized. */
16144 if (eep_config.max_dvc_qng == 0) {
16145 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16146 } else {
16147 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16148 }
16149 }
1da177e4 16150
27c868c2
MW
16151 /*
16152 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16153 * set 'max_dvc_qng' to 'max_host_qng'.
16154 */
16155 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
16156 eep_config.max_dvc_qng = eep_config.max_host_qng;
16157 }
1da177e4 16158
27c868c2
MW
16159 /*
16160 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16161 * values based on possibly adjusted EEPROM values.
16162 */
16163 asc_dvc->max_host_qng = eep_config.max_host_qng;
16164 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16165
16166 /*
16167 * If the EEPROM 'termination' field is set to automatic (0), then set
16168 * the ADV_DVC_CFG 'termination' field to automatic also.
16169 *
16170 * If the termination is specified with a non-zero 'termination'
16171 * value check that a legal value is set and set the ADV_DVC_CFG
16172 * 'termination' field appropriately.
16173 */
16174 if (eep_config.termination == 0) {
16175 asc_dvc->cfg->termination = 0; /* auto termination */
16176 } else {
16177 /* Enable manual control with low off / high off. */
16178 if (eep_config.termination == 1) {
16179 asc_dvc->cfg->termination = TERM_CTL_SEL;
16180
16181 /* Enable manual control with low off / high on. */
16182 } else if (eep_config.termination == 2) {
16183 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
16184
16185 /* Enable manual control with low on / high on. */
16186 } else if (eep_config.termination == 3) {
16187 asc_dvc->cfg->termination =
16188 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
16189 } else {
16190 /*
16191 * The EEPROM 'termination' field contains a bad value. Use
16192 * automatic termination instead.
16193 */
16194 asc_dvc->cfg->termination = 0;
16195 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16196 }
16197 }
1da177e4 16198
27c868c2
MW
16199 return warn_code;
16200}
1da177e4 16201
27c868c2
MW
16202/*
16203 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16204 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16205 * all of this is done.
16206 *
16207 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16208 *
16209 * For a non-fatal error return a warning code. If there are no warnings
16210 * then 0 is returned.
16211 *
16212 * Note: Chip is stopped on entry.
16213 */
16214static int __init AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
16215{
16216 AdvPortAddr iop_base;
16217 ushort warn_code;
16218 ADVEEP_38C0800_CONFIG eep_config;
16219 int i;
16220 uchar tid, termination;
16221 ushort sdtr_speed = 0;
16222
16223 iop_base = asc_dvc->iop_base;
16224
16225 warn_code = 0;
16226
16227 /*
16228 * Read the board's EEPROM configuration.
16229 *
16230 * Set default values if a bad checksum is found.
16231 */
16232 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
16233 eep_config.check_sum) {
16234 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 16235
27c868c2
MW
16236 /*
16237 * Set EEPROM default values.
16238 */
16239 for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++) {
16240 *((uchar *)&eep_config + i) =
16241 *((uchar *)&Default_38C0800_EEPROM_Config + i);
16242 }
1da177e4 16243
27c868c2
MW
16244 /*
16245 * Assume the 6 byte board serial number that was read
16246 * from EEPROM is correct even if the EEPROM checksum
16247 * failed.
16248 */
16249 eep_config.serial_number_word3 =
16250 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 16251
27c868c2
MW
16252 eep_config.serial_number_word2 =
16253 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
1da177e4 16254
27c868c2
MW
16255 eep_config.serial_number_word1 =
16256 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 16257
27c868c2
MW
16258 AdvSet38C0800EEPConfig(iop_base, &eep_config);
16259 }
16260 /*
16261 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
16262 * EEPROM configuration that was read.
16263 *
16264 * This is the mapping of EEPROM fields to Adv Library fields.
16265 */
16266 asc_dvc->wdtr_able = eep_config.wdtr_able;
16267 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16268 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16269 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16270 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16271 asc_dvc->tagqng_able = eep_config.tagqng_able;
16272 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16273 asc_dvc->max_host_qng = eep_config.max_host_qng;
16274 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16275 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16276 asc_dvc->start_motor = eep_config.start_motor;
16277 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16278 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16279 asc_dvc->no_scam = eep_config.scam_tolerant;
16280 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16281 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16282 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16283
16284 /*
16285 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16286 * are set, then set an 'sdtr_able' bit for it.
16287 */
16288 asc_dvc->sdtr_able = 0;
16289 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
16290 if (tid == 0) {
16291 sdtr_speed = asc_dvc->sdtr_speed1;
16292 } else if (tid == 4) {
16293 sdtr_speed = asc_dvc->sdtr_speed2;
16294 } else if (tid == 8) {
16295 sdtr_speed = asc_dvc->sdtr_speed3;
16296 } else if (tid == 12) {
16297 sdtr_speed = asc_dvc->sdtr_speed4;
16298 }
16299 if (sdtr_speed & ADV_MAX_TID) {
16300 asc_dvc->sdtr_able |= (1 << tid);
16301 }
16302 sdtr_speed >>= 4;
16303 }
1da177e4 16304
27c868c2
MW
16305 /*
16306 * Set the host maximum queuing (max. 253, min. 16) and the per device
16307 * maximum queuing (max. 63, min. 4).
16308 */
16309 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
16310 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16311 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
16312 /* If the value is zero, assume it is uninitialized. */
16313 if (eep_config.max_host_qng == 0) {
16314 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16315 } else {
16316 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16317 }
16318 }
1da177e4 16319
27c868c2
MW
16320 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
16321 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16322 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
16323 /* If the value is zero, assume it is uninitialized. */
16324 if (eep_config.max_dvc_qng == 0) {
16325 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16326 } else {
16327 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16328 }
16329 }
1da177e4 16330
27c868c2
MW
16331 /*
16332 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16333 * set 'max_dvc_qng' to 'max_host_qng'.
16334 */
16335 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
16336 eep_config.max_dvc_qng = eep_config.max_host_qng;
16337 }
1da177e4 16338
27c868c2
MW
16339 /*
16340 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16341 * values based on possibly adjusted EEPROM values.
16342 */
16343 asc_dvc->max_host_qng = eep_config.max_host_qng;
16344 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16345
16346 /*
16347 * If the EEPROM 'termination' field is set to automatic (0), then set
16348 * the ADV_DVC_CFG 'termination' field to automatic also.
16349 *
16350 * If the termination is specified with a non-zero 'termination'
16351 * value check that a legal value is set and set the ADV_DVC_CFG
16352 * 'termination' field appropriately.
16353 */
16354 if (eep_config.termination_se == 0) {
16355 termination = 0; /* auto termination for SE */
16356 } else {
16357 /* Enable manual control with low off / high off. */
16358 if (eep_config.termination_se == 1) {
16359 termination = 0;
16360
16361 /* Enable manual control with low off / high on. */
16362 } else if (eep_config.termination_se == 2) {
16363 termination = TERM_SE_HI;
16364
16365 /* Enable manual control with low on / high on. */
16366 } else if (eep_config.termination_se == 3) {
16367 termination = TERM_SE;
16368 } else {
16369 /*
16370 * The EEPROM 'termination_se' field contains a bad value.
16371 * Use automatic termination instead.
16372 */
16373 termination = 0;
16374 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16375 }
16376 }
1da177e4 16377
27c868c2
MW
16378 if (eep_config.termination_lvd == 0) {
16379 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
16380 } else {
16381 /* Enable manual control with low off / high off. */
16382 if (eep_config.termination_lvd == 1) {
16383 asc_dvc->cfg->termination = termination;
16384
16385 /* Enable manual control with low off / high on. */
16386 } else if (eep_config.termination_lvd == 2) {
16387 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16388
16389 /* Enable manual control with low on / high on. */
16390 } else if (eep_config.termination_lvd == 3) {
16391 asc_dvc->cfg->termination = termination | TERM_LVD;
16392 } else {
16393 /*
16394 * The EEPROM 'termination_lvd' field contains a bad value.
16395 * Use automatic termination instead.
16396 */
16397 asc_dvc->cfg->termination = termination;
16398 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16399 }
16400 }
1da177e4 16401
27c868c2 16402 return warn_code;
1da177e4
LT
16403}
16404
16405/*
27c868c2
MW
16406 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
16407 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
16408 * all of this is done.
1da177e4
LT
16409 *
16410 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
16411 *
16412 * For a non-fatal error return a warning code. If there are no warnings
16413 * then 0 is returned.
16414 *
27c868c2 16415 * Note: Chip is stopped on entry.
1da177e4 16416 */
27c868c2 16417static int __init AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
1da177e4 16418{
27c868c2
MW
16419 AdvPortAddr iop_base;
16420 ushort warn_code;
16421 ADVEEP_38C1600_CONFIG eep_config;
16422 int i;
16423 uchar tid, termination;
16424 ushort sdtr_speed = 0;
16425
16426 iop_base = asc_dvc->iop_base;
16427
16428 warn_code = 0;
16429
16430 /*
16431 * Read the board's EEPROM configuration.
16432 *
16433 * Set default values if a bad checksum is found.
16434 */
16435 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
16436 eep_config.check_sum) {
16437 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 16438
27c868c2
MW
16439 /*
16440 * Set EEPROM default values.
16441 */
16442 for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++) {
16443 if (i == 1
16444 && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) !=
16445 0) {
16446 /*
16447 * Set Function 1 EEPROM Word 0 MSB
16448 *
16449 * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11)
16450 * EEPROM bits.
16451 *
16452 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and
16453 * old Mac system booting problem. The Expansion ROM must
16454 * be disabled in Function 1 for these systems.
16455 *
16456 */
16457 *((uchar *)&eep_config + i) =
16458 ((*
16459 ((uchar *)&Default_38C1600_EEPROM_Config
16460 +
16461 i)) &
16462 (~
16463 (((ADV_EEPROM_BIOS_ENABLE |
16464 ADV_EEPROM_INTAB) >> 8) & 0xFF)));
16465
16466 /*
16467 * Set the INTAB (bit 11) if the GPIO 0 input indicates
16468 * the Function 1 interrupt line is wired to INTA.
16469 *
16470 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
16471 * 1 - Function 1 interrupt line wired to INT A.
16472 * 0 - Function 1 interrupt line wired to INT B.
16473 *
16474 * Note: Adapter boards always have Function 0 wired to INTA.
16475 * Put all 5 GPIO bits in input mode and then read
16476 * their input values.
16477 */
16478 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL,
16479 0);
16480 if (AdvReadByteRegister
16481 (iop_base, IOPB_GPIO_DATA) & 0x01) {
16482 /* Function 1 interrupt wired to INTA; Set EEPROM bit. */
16483 *((uchar *)&eep_config + i) |=
16484 ((ADV_EEPROM_INTAB >> 8) & 0xFF);
16485 }
16486 } else {
16487 *((uchar *)&eep_config + i) =
16488 *((uchar *)&Default_38C1600_EEPROM_Config
16489 + i);
16490 }
16491 }
1da177e4 16492
27c868c2
MW
16493 /*
16494 * Assume the 6 byte board serial number that was read
16495 * from EEPROM is correct even if the EEPROM checksum
16496 * failed.
16497 */
16498 eep_config.serial_number_word3 =
16499 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 16500
27c868c2
MW
16501 eep_config.serial_number_word2 =
16502 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
1da177e4 16503
27c868c2
MW
16504 eep_config.serial_number_word1 =
16505 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 16506
27c868c2
MW
16507 AdvSet38C1600EEPConfig(iop_base, &eep_config);
16508 }
1da177e4 16509
27c868c2
MW
16510 /*
16511 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16512 * EEPROM configuration that was read.
16513 *
16514 * This is the mapping of EEPROM fields to Adv Library fields.
16515 */
16516 asc_dvc->wdtr_able = eep_config.wdtr_able;
16517 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16518 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16519 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16520 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16521 asc_dvc->ppr_able = 0;
16522 asc_dvc->tagqng_able = eep_config.tagqng_able;
16523 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16524 asc_dvc->max_host_qng = eep_config.max_host_qng;
16525 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16526 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
16527 asc_dvc->start_motor = eep_config.start_motor;
16528 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16529 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16530 asc_dvc->no_scam = eep_config.scam_tolerant;
16531
16532 /*
16533 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16534 * are set, then set an 'sdtr_able' bit for it.
16535 */
16536 asc_dvc->sdtr_able = 0;
16537 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
16538 if (tid == 0) {
16539 sdtr_speed = asc_dvc->sdtr_speed1;
16540 } else if (tid == 4) {
16541 sdtr_speed = asc_dvc->sdtr_speed2;
16542 } else if (tid == 8) {
16543 sdtr_speed = asc_dvc->sdtr_speed3;
16544 } else if (tid == 12) {
16545 sdtr_speed = asc_dvc->sdtr_speed4;
16546 }
16547 if (sdtr_speed & ASC_MAX_TID) {
16548 asc_dvc->sdtr_able |= (1 << tid);
16549 }
16550 sdtr_speed >>= 4;
16551 }
1da177e4 16552
27c868c2
MW
16553 /*
16554 * Set the host maximum queuing (max. 253, min. 16) and the per device
16555 * maximum queuing (max. 63, min. 4).
16556 */
16557 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
16558 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16559 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
16560 /* If the value is zero, assume it is uninitialized. */
16561 if (eep_config.max_host_qng == 0) {
16562 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16563 } else {
16564 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16565 }
16566 }
1da177e4 16567
27c868c2
MW
16568 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
16569 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16570 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
16571 /* If the value is zero, assume it is uninitialized. */
16572 if (eep_config.max_dvc_qng == 0) {
16573 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16574 } else {
16575 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16576 }
16577 }
1da177e4 16578
27c868c2
MW
16579 /*
16580 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16581 * set 'max_dvc_qng' to 'max_host_qng'.
16582 */
16583 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
16584 eep_config.max_dvc_qng = eep_config.max_host_qng;
16585 }
1da177e4 16586
27c868c2
MW
16587 /*
16588 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
16589 * values based on possibly adjusted EEPROM values.
16590 */
16591 asc_dvc->max_host_qng = eep_config.max_host_qng;
16592 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16593
16594 /*
16595 * If the EEPROM 'termination' field is set to automatic (0), then set
16596 * the ASC_DVC_CFG 'termination' field to automatic also.
16597 *
16598 * If the termination is specified with a non-zero 'termination'
16599 * value check that a legal value is set and set the ASC_DVC_CFG
16600 * 'termination' field appropriately.
16601 */
16602 if (eep_config.termination_se == 0) {
16603 termination = 0; /* auto termination for SE */
16604 } else {
16605 /* Enable manual control with low off / high off. */
16606 if (eep_config.termination_se == 1) {
16607 termination = 0;
16608
16609 /* Enable manual control with low off / high on. */
16610 } else if (eep_config.termination_se == 2) {
16611 termination = TERM_SE_HI;
16612
16613 /* Enable manual control with low on / high on. */
16614 } else if (eep_config.termination_se == 3) {
16615 termination = TERM_SE;
16616 } else {
16617 /*
16618 * The EEPROM 'termination_se' field contains a bad value.
16619 * Use automatic termination instead.
16620 */
16621 termination = 0;
16622 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16623 }
16624 }
1da177e4 16625
27c868c2
MW
16626 if (eep_config.termination_lvd == 0) {
16627 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
16628 } else {
16629 /* Enable manual control with low off / high off. */
16630 if (eep_config.termination_lvd == 1) {
16631 asc_dvc->cfg->termination = termination;
16632
16633 /* Enable manual control with low off / high on. */
16634 } else if (eep_config.termination_lvd == 2) {
16635 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16636
16637 /* Enable manual control with low on / high on. */
16638 } else if (eep_config.termination_lvd == 3) {
16639 asc_dvc->cfg->termination = termination | TERM_LVD;
16640 } else {
16641 /*
16642 * The EEPROM 'termination_lvd' field contains a bad value.
16643 * Use automatic termination instead.
16644 */
16645 asc_dvc->cfg->termination = termination;
16646 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16647 }
16648 }
1da177e4 16649
27c868c2 16650 return warn_code;
1da177e4
LT
16651}
16652
16653/*
16654 * Read EEPROM configuration into the specified buffer.
16655 *
16656 * Return a checksum based on the EEPROM configuration read.
16657 */
27c868c2 16658static ushort __init
1da177e4
LT
16659AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16660{
27c868c2
MW
16661 ushort wval, chksum;
16662 ushort *wbuf;
16663 int eep_addr;
16664 ushort *charfields;
16665
16666 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16667 wbuf = (ushort *)cfg_buf;
16668 chksum = 0;
16669
16670 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16671 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16672 wval = AdvReadEEPWord(iop_base, eep_addr);
16673 chksum += wval; /* Checksum is calculated from word values. */
16674 if (*charfields++) {
16675 *wbuf = le16_to_cpu(wval);
16676 } else {
16677 *wbuf = wval;
16678 }
16679 }
16680 /* Read checksum word. */
16681 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16682 wbuf++;
16683 charfields++;
16684
16685 /* Read rest of EEPROM not covered by the checksum. */
16686 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16687 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16688 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16689 if (*charfields++) {
16690 *wbuf = le16_to_cpu(*wbuf);
16691 }
16692 }
16693 return chksum;
1da177e4
LT
16694}
16695
16696/*
16697 * Read EEPROM configuration into the specified buffer.
16698 *
16699 * Return a checksum based on the EEPROM configuration read.
16700 */
27c868c2
MW
16701static ushort __init
16702AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
1da177e4 16703{
27c868c2
MW
16704 ushort wval, chksum;
16705 ushort *wbuf;
16706 int eep_addr;
16707 ushort *charfields;
16708
16709 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16710 wbuf = (ushort *)cfg_buf;
16711 chksum = 0;
16712
16713 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16714 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16715 wval = AdvReadEEPWord(iop_base, eep_addr);
16716 chksum += wval; /* Checksum is calculated from word values. */
16717 if (*charfields++) {
16718 *wbuf = le16_to_cpu(wval);
16719 } else {
16720 *wbuf = wval;
16721 }
16722 }
16723 /* Read checksum word. */
16724 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16725 wbuf++;
16726 charfields++;
16727
16728 /* Read rest of EEPROM not covered by the checksum. */
16729 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16730 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16731 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16732 if (*charfields++) {
16733 *wbuf = le16_to_cpu(*wbuf);
16734 }
16735 }
16736 return chksum;
1da177e4
LT
16737}
16738
16739/*
16740 * Read EEPROM configuration into the specified buffer.
16741 *
16742 * Return a checksum based on the EEPROM configuration read.
16743 */
27c868c2
MW
16744static ushort __init
16745AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
1da177e4 16746{
27c868c2
MW
16747 ushort wval, chksum;
16748 ushort *wbuf;
16749 int eep_addr;
16750 ushort *charfields;
16751
16752 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16753 wbuf = (ushort *)cfg_buf;
16754 chksum = 0;
16755
16756 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16757 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16758 wval = AdvReadEEPWord(iop_base, eep_addr);
16759 chksum += wval; /* Checksum is calculated from word values. */
16760 if (*charfields++) {
16761 *wbuf = le16_to_cpu(wval);
16762 } else {
16763 *wbuf = wval;
16764 }
16765 }
16766 /* Read checksum word. */
16767 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16768 wbuf++;
16769 charfields++;
16770
16771 /* Read rest of EEPROM not covered by the checksum. */
16772 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16773 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16774 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16775 if (*charfields++) {
16776 *wbuf = le16_to_cpu(*wbuf);
16777 }
16778 }
16779 return chksum;
1da177e4
LT
16780}
16781
16782/*
16783 * Read the EEPROM from specified location
16784 */
27c868c2 16785static ushort __init AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
1da177e4 16786{
27c868c2
MW
16787 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16788 ASC_EEP_CMD_READ | eep_word_addr);
16789 AdvWaitEEPCmd(iop_base);
16790 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
1da177e4
LT
16791}
16792
16793/*
16794 * Wait for EEPROM command to complete
16795 */
27c868c2 16796static void __init AdvWaitEEPCmd(AdvPortAddr iop_base)
1da177e4 16797{
27c868c2
MW
16798 int eep_delay_ms;
16799
16800 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
16801 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
16802 ASC_EEP_CMD_DONE) {
16803 break;
16804 }
16805 DvcSleepMilliSecond(1);
16806 }
16807 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
16808 0) {
16809 ASC_ASSERT(0);
16810 }
16811 return;
1da177e4
LT
16812}
16813
16814/*
16815 * Write the EEPROM from 'cfg_buf'.
16816 */
c836043e 16817void __init
1da177e4
LT
16818AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16819{
27c868c2
MW
16820 ushort *wbuf;
16821 ushort addr, chksum;
16822 ushort *charfields;
16823
16824 wbuf = (ushort *)cfg_buf;
16825 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16826 chksum = 0;
16827
16828 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16829 AdvWaitEEPCmd(iop_base);
16830
16831 /*
16832 * Write EEPROM from word 0 to word 20.
16833 */
16834 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16835 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16836 ushort word;
16837
16838 if (*charfields++) {
16839 word = cpu_to_le16(*wbuf);
16840 } else {
16841 word = *wbuf;
16842 }
16843 chksum += *wbuf; /* Checksum is calculated from word values. */
16844 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16845 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16846 ASC_EEP_CMD_WRITE | addr);
16847 AdvWaitEEPCmd(iop_base);
16848 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16849 }
1da177e4 16850
27c868c2
MW
16851 /*
16852 * Write EEPROM checksum at word 21.
16853 */
16854 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16855 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16856 AdvWaitEEPCmd(iop_base);
16857 wbuf++;
16858 charfields++;
16859
16860 /*
16861 * Write EEPROM OEM name at words 22 to 29.
16862 */
16863 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16864 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16865 ushort word;
16866
16867 if (*charfields++) {
16868 word = cpu_to_le16(*wbuf);
16869 } else {
16870 word = *wbuf;
16871 }
16872 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16873 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16874 ASC_EEP_CMD_WRITE | addr);
16875 AdvWaitEEPCmd(iop_base);
16876 }
16877 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16878 AdvWaitEEPCmd(iop_base);
16879 return;
1da177e4
LT
16880}
16881
16882/*
16883 * Write the EEPROM from 'cfg_buf'.
16884 */
c836043e 16885void __init
27c868c2 16886AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
1da177e4 16887{
27c868c2
MW
16888 ushort *wbuf;
16889 ushort *charfields;
16890 ushort addr, chksum;
16891
16892 wbuf = (ushort *)cfg_buf;
16893 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16894 chksum = 0;
16895
16896 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16897 AdvWaitEEPCmd(iop_base);
16898
16899 /*
16900 * Write EEPROM from word 0 to word 20.
16901 */
16902 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16903 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16904 ushort word;
16905
16906 if (*charfields++) {
16907 word = cpu_to_le16(*wbuf);
16908 } else {
16909 word = *wbuf;
16910 }
16911 chksum += *wbuf; /* Checksum is calculated from word values. */
16912 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16913 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16914 ASC_EEP_CMD_WRITE | addr);
16915 AdvWaitEEPCmd(iop_base);
16916 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16917 }
1da177e4 16918
27c868c2
MW
16919 /*
16920 * Write EEPROM checksum at word 21.
16921 */
16922 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16923 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16924 AdvWaitEEPCmd(iop_base);
16925 wbuf++;
16926 charfields++;
16927
16928 /*
16929 * Write EEPROM OEM name at words 22 to 29.
16930 */
16931 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16932 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16933 ushort word;
16934
16935 if (*charfields++) {
16936 word = cpu_to_le16(*wbuf);
16937 } else {
16938 word = *wbuf;
16939 }
16940 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16941 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16942 ASC_EEP_CMD_WRITE | addr);
16943 AdvWaitEEPCmd(iop_base);
16944 }
16945 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16946 AdvWaitEEPCmd(iop_base);
16947 return;
1da177e4
LT
16948}
16949
16950/*
16951 * Write the EEPROM from 'cfg_buf'.
16952 */
c836043e 16953void __init
27c868c2 16954AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
1da177e4 16955{
27c868c2
MW
16956 ushort *wbuf;
16957 ushort *charfields;
16958 ushort addr, chksum;
16959
16960 wbuf = (ushort *)cfg_buf;
16961 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16962 chksum = 0;
16963
16964 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16965 AdvWaitEEPCmd(iop_base);
16966
16967 /*
16968 * Write EEPROM from word 0 to word 20.
16969 */
16970 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16971 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16972 ushort word;
16973
16974 if (*charfields++) {
16975 word = cpu_to_le16(*wbuf);
16976 } else {
16977 word = *wbuf;
16978 }
16979 chksum += *wbuf; /* Checksum is calculated from word values. */
16980 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16981 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16982 ASC_EEP_CMD_WRITE | addr);
16983 AdvWaitEEPCmd(iop_base);
16984 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16985 }
1da177e4 16986
27c868c2
MW
16987 /*
16988 * Write EEPROM checksum at word 21.
16989 */
16990 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16991 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16992 AdvWaitEEPCmd(iop_base);
16993 wbuf++;
16994 charfields++;
16995
16996 /*
16997 * Write EEPROM OEM name at words 22 to 29.
16998 */
16999 for (addr = ADV_EEP_DVC_CTL_BEGIN;
17000 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
17001 ushort word;
17002
17003 if (*charfields++) {
17004 word = cpu_to_le16(*wbuf);
17005 } else {
17006 word = *wbuf;
17007 }
17008 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17009 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
17010 ASC_EEP_CMD_WRITE | addr);
17011 AdvWaitEEPCmd(iop_base);
17012 }
17013 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17014 AdvWaitEEPCmd(iop_base);
17015 return;
1da177e4
LT
17016}
17017
17018/* a_advlib.c */
17019/*
17020 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
17021 *
17022 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
17023 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
17024 * RISC to notify it a new command is ready to be executed.
17025 *
17026 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
17027 * set to SCSI_MAX_RETRY.
17028 *
17029 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
17030 * for DMA addresses or math operations are byte swapped to little-endian
17031 * order.
17032 *
17033 * Return:
17034 * ADV_SUCCESS(1) - The request was successfully queued.
17035 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
17036 * request completes.
17037 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
17038 * host IC error.
17039 */
27c868c2 17040static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
1da177e4 17041{
27c868c2
MW
17042 ulong last_int_level;
17043 AdvPortAddr iop_base;
17044 ADV_DCNT req_size;
17045 ADV_PADDR req_paddr;
17046 ADV_CARR_T *new_carrp;
17047
17048 ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
17049
17050 /*
17051 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
17052 */
17053 if (scsiq->target_id > ADV_MAX_TID) {
17054 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
17055 scsiq->done_status = QD_WITH_ERROR;
17056 return ADV_ERROR;
17057 }
1da177e4 17058
27c868c2 17059 iop_base = asc_dvc->iop_base;
1da177e4 17060
27c868c2 17061 last_int_level = DvcEnterCritical();
1da177e4 17062
27c868c2
MW
17063 /*
17064 * Allocate a carrier ensuring at least one carrier always
17065 * remains on the freelist and initialize fields.
17066 */
17067 if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
17068 DvcLeaveCritical(last_int_level);
17069 return ADV_BUSY;
17070 }
17071 asc_dvc->carr_freelist = (ADV_CARR_T *)
17072 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
17073 asc_dvc->carr_pending_cnt++;
17074
17075 /*
17076 * Set the carrier to be a stopper by setting 'next_vpa'
17077 * to the stopper value. The current stopper will be changed
17078 * below to point to the new stopper.
17079 */
17080 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
17081
17082 /*
17083 * Clear the ADV_SCSI_REQ_Q done flag.
17084 */
17085 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
17086
17087 req_size = sizeof(ADV_SCSI_REQ_Q);
17088 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
17089 (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
17090
17091 ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
17092 ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
17093
17094 /* Wait for assertion before making little-endian */
17095 req_paddr = cpu_to_le32(req_paddr);
17096
17097 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
17098 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
17099 scsiq->scsiq_rptr = req_paddr;
17100
17101 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
17102 /*
17103 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
17104 * order during initialization.
17105 */
17106 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
17107
17108 /*
17109 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
17110 * the microcode. The newly allocated stopper will become the new
17111 * stopper.
17112 */
17113 asc_dvc->icq_sp->areq_vpa = req_paddr;
17114
17115 /*
17116 * Set the 'next_vpa' pointer for the old stopper to be the
17117 * physical address of the new stopper. The RISC can only
17118 * follow physical addresses.
17119 */
17120 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
17121
17122 /*
17123 * Set the host adapter stopper pointer to point to the new carrier.
17124 */
17125 asc_dvc->icq_sp = new_carrp;
17126
17127 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17128 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
17129 /*
17130 * Tickle the RISC to tell it to read its Command Queue Head pointer.
17131 */
17132 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
17133 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
17134 /*
17135 * Clear the tickle value. In the ASC-3550 the RISC flag
17136 * command 'clr_tickle_a' does not work unless the host
17137 * value is cleared.
17138 */
17139 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
17140 ADV_TICKLE_NOP);
17141 }
17142 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17143 /*
17144 * Notify the RISC a carrier is ready by writing the physical
17145 * address of the new carrier stopper to the COMMA register.
17146 */
17147 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
17148 le32_to_cpu(new_carrp->carr_pa));
17149 }
1da177e4 17150
27c868c2 17151 DvcLeaveCritical(last_int_level);
1da177e4 17152
27c868c2 17153 return ADV_SUCCESS;
1da177e4
LT
17154}
17155
17156/*
17157 * Reset SCSI Bus and purge all outstanding requests.
17158 *
17159 * Return Value:
17160 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
17161 * ADV_FALSE(0) - Microcode command failed.
17162 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
17163 * may be hung which requires driver recovery.
17164 */
27c868c2 17165static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
1da177e4 17166{
27c868c2
MW
17167 int status;
17168
17169 /*
17170 * Send the SCSI Bus Reset idle start idle command which asserts
17171 * the SCSI Bus Reset signal.
17172 */
17173 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
17174 if (status != ADV_TRUE) {
17175 return status;
17176 }
1da177e4 17177
27c868c2
MW
17178 /*
17179 * Delay for the specified SCSI Bus Reset hold time.
17180 *
17181 * The hold time delay is done on the host because the RISC has no
17182 * microsecond accurate timer.
17183 */
17184 DvcDelayMicroSecond(asc_dvc, (ushort)ASC_SCSI_RESET_HOLD_TIME_US);
17185
17186 /*
17187 * Send the SCSI Bus Reset end idle command which de-asserts
17188 * the SCSI Bus Reset signal and purges any pending requests.
17189 */
17190 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
17191 if (status != ADV_TRUE) {
17192 return status;
17193 }
17194
17195 DvcSleepMilliSecond((ADV_DCNT)asc_dvc->scsi_reset_wait * 1000);
1da177e4 17196
27c868c2 17197 return status;
1da177e4
LT
17198}
17199
17200/*
17201 * Reset chip and SCSI Bus.
17202 *
17203 * Return Value:
17204 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
17205 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
17206 */
27c868c2 17207static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
1da177e4 17208{
27c868c2
MW
17209 int status;
17210 ushort wdtr_able, sdtr_able, tagqng_able;
17211 ushort ppr_able = 0;
17212 uchar tid, max_cmd[ADV_MAX_TID + 1];
17213 AdvPortAddr iop_base;
17214 ushort bios_sig;
17215
17216 iop_base = asc_dvc->iop_base;
17217
17218 /*
17219 * Save current per TID negotiated values.
17220 */
17221 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17222 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17223 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17224 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17225 }
17226 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17227 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
17228 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17229 max_cmd[tid]);
17230 }
1da177e4 17231
27c868c2
MW
17232 /*
17233 * Force the AdvInitAsc3550/38C0800Driver() function to
17234 * perform a SCSI Bus Reset by clearing the BIOS signature word.
17235 * The initialization functions assumes a SCSI Bus Reset is not
17236 * needed if the BIOS signature word is present.
17237 */
17238 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17239 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
17240
17241 /*
17242 * Stop chip and reset it.
17243 */
17244 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
17245 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
17246 DvcSleepMilliSecond(100);
17247 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
17248 ADV_CTRL_REG_CMD_WR_IO_REG);
17249
17250 /*
17251 * Reset Adv Library error code, if any, and try
17252 * re-initializing the chip.
17253 */
17254 asc_dvc->err_code = 0;
17255 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17256 status = AdvInitAsc38C1600Driver(asc_dvc);
17257 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
17258 status = AdvInitAsc38C0800Driver(asc_dvc);
17259 } else {
17260 status = AdvInitAsc3550Driver(asc_dvc);
17261 }
1da177e4 17262
27c868c2
MW
17263 /* Translate initialization return value to status value. */
17264 if (status == 0) {
17265 status = ADV_TRUE;
17266 } else {
17267 status = ADV_FALSE;
17268 }
1da177e4 17269
27c868c2
MW
17270 /*
17271 * Restore the BIOS signature word.
17272 */
17273 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17274
17275 /*
17276 * Restore per TID negotiated values.
17277 */
17278 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17279 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17280 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17281 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17282 }
17283 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17284 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
17285 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17286 max_cmd[tid]);
17287 }
1da177e4 17288
27c868c2 17289 return status;
1da177e4
LT
17290}
17291
17292/*
17293 * Adv Library Interrupt Service Routine
17294 *
17295 * This function is called by a driver's interrupt service routine.
17296 * The function disables and re-enables interrupts.
17297 *
17298 * When a microcode idle command is completed, the ADV_DVC_VAR
17299 * 'idle_cmd_done' field is set to ADV_TRUE.
17300 *
17301 * Note: AdvISR() can be called when interrupts are disabled or even
17302 * when there is no hardware interrupt condition present. It will
17303 * always check for completed idle commands and microcode requests.
17304 * This is an important feature that shouldn't be changed because it
17305 * allows commands to be completed from polling mode loops.
17306 *
17307 * Return:
17308 * ADV_TRUE(1) - interrupt was pending
17309 * ADV_FALSE(0) - no interrupt was pending
17310 */
27c868c2 17311static int AdvISR(ADV_DVC_VAR *asc_dvc)
1da177e4 17312{
27c868c2
MW
17313 AdvPortAddr iop_base;
17314 uchar int_stat;
17315 ushort target_bit;
17316 ADV_CARR_T *free_carrp;
17317 ADV_VADDR irq_next_vpa;
17318 int flags;
17319 ADV_SCSI_REQ_Q *scsiq;
1da177e4 17320
27c868c2 17321 flags = DvcEnterCritical();
1da177e4 17322
27c868c2
MW
17323 iop_base = asc_dvc->iop_base;
17324
17325 /* Reading the register clears the interrupt. */
17326 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
17327
17328 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
17329 ADV_INTR_STATUS_INTRC)) == 0) {
17330 DvcLeaveCritical(flags);
17331 return ADV_FALSE;
17332 }
17333
17334 /*
17335 * Notify the driver of an asynchronous microcode condition by
17336 * calling the ADV_DVC_VAR.async_callback function. The function
17337 * is passed the microcode ASC_MC_INTRB_CODE byte value.
17338 */
17339 if (int_stat & ADV_INTR_STATUS_INTRB) {
17340 uchar intrb_code;
17341
17342 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
17343
17344 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17345 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
17346 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
17347 asc_dvc->carr_pending_cnt != 0) {
17348 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
17349 ADV_TICKLE_A);
17350 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
17351 AdvWriteByteRegister(iop_base,
17352 IOPB_TICKLE,
17353 ADV_TICKLE_NOP);
17354 }
17355 }
17356 }
17357
17358 if (asc_dvc->async_callback != 0) {
17359 (*asc_dvc->async_callback) (asc_dvc, intrb_code);
17360 }
17361 }
17362
17363 /*
17364 * Check if the IRQ stopper carrier contains a completed request.
17365 */
17366 while (((irq_next_vpa =
17367 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
17368 /*
17369 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
17370 * The RISC will have set 'areq_vpa' to a virtual address.
17371 *
17372 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
17373 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
17374 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
17375 * in AdvExeScsiQueue().
17376 */
17377 scsiq = (ADV_SCSI_REQ_Q *)
17378 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
17379
17380 /*
17381 * Request finished with good status and the queue was not
17382 * DMAed to host memory by the firmware. Set all status fields
17383 * to indicate good status.
17384 */
17385 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
17386 scsiq->done_status = QD_NO_ERROR;
17387 scsiq->host_status = scsiq->scsi_status = 0;
17388 scsiq->data_cnt = 0L;
17389 }
17390
17391 /*
17392 * Advance the stopper pointer to the next carrier
17393 * ignoring the lower four bits. Free the previous
17394 * stopper carrier.
17395 */
17396 free_carrp = asc_dvc->irq_sp;
17397 asc_dvc->irq_sp = (ADV_CARR_T *)
17398 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
17399
17400 free_carrp->next_vpa =
17401 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
17402 asc_dvc->carr_freelist = free_carrp;
17403 asc_dvc->carr_pending_cnt--;
17404
17405 ASC_ASSERT(scsiq != NULL);
17406 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
17407
17408 /*
17409 * Clear request microcode control flag.
17410 */
17411 scsiq->cntl = 0;
17412
17413 /*
17414 * If the command that completed was a SCSI INQUIRY and
17415 * LUN 0 was sent the command, then process the INQUIRY
17416 * command information for the device.
17417 *
17418 * Note: If data returned were either VPD or CmdDt data,
17419 * don't process the INQUIRY command information for
17420 * the device, otherwise may erroneously set *_able bits.
17421 */
17422 if (scsiq->done_status == QD_NO_ERROR &&
17423 scsiq->cdb[0] == INQUIRY &&
17424 scsiq->target_lun == 0 &&
17425 (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
17426 == ADV_INQ_RTN_STD_INQUIRY_DATA) {
17427 AdvInquiryHandling(asc_dvc, scsiq);
17428 }
17429
17430 /*
17431 * Notify the driver of the completed request by passing
17432 * the ADV_SCSI_REQ_Q pointer to its callback function.
17433 */
17434 scsiq->a_flag |= ADV_SCSIQ_DONE;
17435 (*asc_dvc->isr_callback) (asc_dvc, scsiq);
17436 /*
17437 * Note: After the driver callback function is called, 'scsiq'
17438 * can no longer be referenced.
17439 *
17440 * Fall through and continue processing other completed
17441 * requests...
17442 */
17443
17444 /*
17445 * Disable interrupts again in case the driver inadvertently
17446 * enabled interrupts in its callback function.
17447 *
17448 * The DvcEnterCritical() return value is ignored, because
17449 * the 'flags' saved when AdvISR() was first entered will be
17450 * used to restore the interrupt flag on exit.
17451 */
17452 (void)DvcEnterCritical();
17453 }
17454 DvcLeaveCritical(flags);
17455 return ADV_TRUE;
1da177e4
LT
17456}
17457
17458/*
17459 * Send an idle command to the chip and wait for completion.
17460 *
17461 * Command completion is polled for once per microsecond.
17462 *
17463 * The function can be called from anywhere including an interrupt handler.
17464 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
17465 * functions to prevent reentrancy.
17466 *
17467 * Return Values:
17468 * ADV_TRUE - command completed successfully
17469 * ADV_FALSE - command failed
17470 * ADV_ERROR - command timed out
17471 */
27c868c2 17472static int
1da177e4 17473AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
27c868c2 17474 ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
1da177e4 17475{
27c868c2
MW
17476 ulong last_int_level;
17477 int result;
17478 ADV_DCNT i, j;
17479 AdvPortAddr iop_base;
17480
17481 last_int_level = DvcEnterCritical();
17482
17483 iop_base = asc_dvc->iop_base;
17484
17485 /*
17486 * Clear the idle command status which is set by the microcode
17487 * to a non-zero value to indicate when the command is completed.
17488 * The non-zero result is one of the IDLE_CMD_STATUS_* values
17489 * defined in a_advlib.h.
17490 */
17491 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
17492
17493 /*
17494 * Write the idle command value after the idle command parameter
17495 * has been written to avoid a race condition. If the order is not
17496 * followed, the microcode may process the idle command before the
17497 * parameters have been written to LRAM.
17498 */
17499 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
17500 cpu_to_le32(idle_cmd_parameter));
17501 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
17502
17503 /*
17504 * Tickle the RISC to tell it to process the idle command.
17505 */
17506 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
17507 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
17508 /*
17509 * Clear the tickle value. In the ASC-3550 the RISC flag
17510 * command 'clr_tickle_b' does not work unless the host
17511 * value is cleared.
17512 */
17513 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17514 }
1da177e4 17515
27c868c2
MW
17516 /* Wait for up to 100 millisecond for the idle command to timeout. */
17517 for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
17518 /* Poll once each microsecond for command completion. */
17519 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
17520 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
17521 result);
17522 if (result != 0) {
17523 DvcLeaveCritical(last_int_level);
17524 return result;
17525 }
17526 DvcDelayMicroSecond(asc_dvc, (ushort)1);
17527 }
17528 }
1da177e4 17529
27c868c2
MW
17530 ASC_ASSERT(0); /* The idle command should never timeout. */
17531 DvcLeaveCritical(last_int_level);
17532 return ADV_ERROR;
1da177e4
LT
17533}
17534
17535/*
17536 * Inquiry Information Byte 7 Handling
17537 *
17538 * Handle SCSI Inquiry Command information for a device by setting
17539 * microcode operating variables that affect WDTR, SDTR, and Tag
17540 * Queuing.
17541 */
27c868c2 17542static void AdvInquiryHandling(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
1da177e4 17543{
27c868c2
MW
17544 AdvPortAddr iop_base;
17545 uchar tid;
17546 ADV_SCSI_INQUIRY *inq;
17547 ushort tidmask;
17548 ushort cfg_word;
17549
17550 /*
17551 * AdvInquiryHandling() requires up to INQUIRY information Byte 7
17552 * to be available.
17553 *
17554 * If less than 8 bytes of INQUIRY information were requested or less
17555 * than 8 bytes were transferred, then return. cdb[4] is the request
17556 * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
17557 * microcode to the transfer residual count.
17558 */
17559
17560 if (scsiq->cdb[4] < 8 ||
17561 (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8) {
17562 return;
17563 }
1da177e4 17564
27c868c2
MW
17565 iop_base = asc_dvc->iop_base;
17566 tid = scsiq->target_id;
17567
17568 inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr;
1da177e4 17569
27c868c2
MW
17570 /*
17571 * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
17572 */
17573 if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2) {
17574 return;
17575 } else {
17576 /*
17577 * INQUIRY Byte 7 Handling
17578 *
17579 * Use a device's INQUIRY byte 7 to determine whether it
17580 * supports WDTR, SDTR, and Tag Queuing. If the feature
17581 * is enabled in the EEPROM and the device supports the
17582 * feature, then enable it in the microcode.
17583 */
1da177e4 17584
27c868c2 17585 tidmask = ADV_TID_TO_TIDMASK(tid);
1da177e4 17586
27c868c2
MW
17587 /*
17588 * Wide Transfers
17589 *
17590 * If the EEPROM enabled WDTR for the device and the device
17591 * supports wide bus (16 bit) transfers, then turn on the
17592 * device's 'wdtr_able' bit and write the new value to the
17593 * microcode.
17594 */
17595 if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq)) {
17596 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
17597 if ((cfg_word & tidmask) == 0) {
17598 cfg_word |= tidmask;
17599 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
17600 cfg_word);
17601
17602 /*
17603 * Clear the microcode "SDTR negotiation" and "WDTR
17604 * negotiation" done indicators for the target to cause
17605 * it to negotiate with the new setting set above.
17606 * WDTR when accepted causes the target to enter
17607 * asynchronous mode, so SDTR must be negotiated.
17608 */
17609 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE,
17610 cfg_word);
17611 cfg_word &= ~tidmask;
17612 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE,
17613 cfg_word);
17614 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE,
17615 cfg_word);
17616 cfg_word &= ~tidmask;
17617 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE,
17618 cfg_word);
17619 }
17620 }
17621
17622 /*
17623 * Synchronous Transfers
17624 *
17625 * If the EEPROM enabled SDTR for the device and the device
17626 * supports synchronous transfers, then turn on the device's
17627 * 'sdtr_able' bit. Write the new value to the microcode.
17628 */
17629 if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq)) {
17630 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
17631 if ((cfg_word & tidmask) == 0) {
17632 cfg_word |= tidmask;
17633 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
17634 cfg_word);
17635
17636 /*
17637 * Clear the microcode "SDTR negotiation" done indicator
17638 * for the target to cause it to negotiate with the new
17639 * setting set above.
17640 */
17641 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE,
17642 cfg_word);
17643 cfg_word &= ~tidmask;
17644 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE,
17645 cfg_word);
17646 }
17647 }
17648 /*
17649 * If the Inquiry data included enough space for the SPI-3
17650 * Clocking field, then check if DT mode is supported.
17651 */
17652 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 &&
17653 (scsiq->cdb[4] >= 57 ||
17654 (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57)) {
17655 /*
17656 * PPR (Parallel Protocol Request) Capable
17657 *
17658 * If the device supports DT mode, then it must be PPR capable.
17659 * The PPR message will be used in place of the SDTR and WDTR
17660 * messages to negotiate synchronous speed and offset, transfer
17661 * width, and protocol options.
17662 */
17663 if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY) {
17664 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE,
17665 asc_dvc->ppr_able);
17666 asc_dvc->ppr_able |= tidmask;
17667 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE,
17668 asc_dvc->ppr_able);
17669 }
17670 }
17671
17672 /*
17673 * If the EEPROM enabled Tag Queuing for the device and the
17674 * device supports Tag Queueing, then turn on the device's
17675 * 'tagqng_enable' bit in the microcode and set the microcode
17676 * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
17677 * value.
17678 *
17679 * Tag Queuing is disabled for the BIOS which runs in polled
17680 * mode and would see no benefit from Tag Queuing. Also by
17681 * disabling Tag Queuing in the BIOS devices with Tag Queuing
17682 * bugs will at least work with the BIOS.
17683 */
17684 if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq)) {
17685 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
17686 cfg_word |= tidmask;
17687 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
17688 cfg_word);
17689
17690 AdvWriteByteLram(iop_base,
17691 ASC_MC_NUMBER_OF_MAX_CMD + tid,
17692 asc_dvc->max_dvc_qng);
17693 }
17694 }
1da177e4 17695}
27c868c2 17696
b2c16f58
MW
17697static int __devinit
17698advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
17699{
17700 int req_cnt = 0;
17701 adv_req_t *reqp = NULL;
17702 int sg_cnt = 0;
17703 adv_sgblk_t *sgp;
17704 int warn_code, err_code;
17705
17706 /*
17707 * Allocate buffer carrier structures. The total size
17708 * is about 4 KB, so allocate all at once.
17709 */
17710 boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
17711 ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp);
17712
17713 if (!boardp->carrp)
17714 goto kmalloc_failed;
17715
17716 /*
17717 * Allocate up to 'max_host_qng' request structures for the Wide
17718 * board. The total size is about 16 KB, so allocate all at once.
17719 * If the allocation fails decrement and try again.
17720 */
17721 for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
17722 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
17723
17724 ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, "
17725 "bytes %lu\n", reqp, req_cnt,
17726 (ulong)sizeof(adv_req_t) * req_cnt);
17727
17728 if (reqp)
17729 break;
17730 }
17731
17732 if (!reqp)
17733 goto kmalloc_failed;
17734
17735 boardp->orig_reqp = reqp;
17736
17737 /*
17738 * Allocate up to ADV_TOT_SG_BLOCK request structures for
17739 * the Wide board. Each structure is about 136 bytes.
17740 */
17741 boardp->adv_sgblkp = NULL;
17742 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
17743 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
17744
17745 if (!sgp)
17746 break;
17747
17748 sgp->next_sgblkp = boardp->adv_sgblkp;
17749 boardp->adv_sgblkp = sgp;
17750
17751 }
17752
17753 ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n",
17754 sg_cnt, sizeof(adv_sgblk_t),
17755 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
17756
17757 if (!boardp->adv_sgblkp)
17758 goto kmalloc_failed;
17759
17760 adv_dvc_varp->carrier_buf = boardp->carrp;
17761
17762 /*
17763 * Point 'adv_reqp' to the request structures and
17764 * link them together.
17765 */
17766 req_cnt--;
17767 reqp[req_cnt].next_reqp = NULL;
17768 for (; req_cnt > 0; req_cnt--) {
17769 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
17770 }
17771 boardp->adv_reqp = &reqp[0];
17772
17773 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17774 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n");
17775 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
17776 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17777 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()"
17778 "\n");
17779 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
17780 } else {
17781 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()"
17782 "\n");
17783 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
17784 }
17785 err_code = adv_dvc_varp->err_code;
17786
17787 if (warn_code || err_code) {
17788 ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
17789 " error 0x%x\n", boardp->id, warn_code, err_code);
17790 }
17791
17792 goto exit;
17793
17794 kmalloc_failed:
17795 ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
17796 "failed\n", boardp->id);
17797 err_code = ADV_ERROR;
17798 exit:
17799 return err_code;
17800}
17801
17802static void advansys_wide_free_mem(asc_board_t *boardp)
17803{
17804 kfree(boardp->carrp);
17805 boardp->carrp = NULL;
17806 kfree(boardp->orig_reqp);
17807 boardp->orig_reqp = boardp->adv_reqp = NULL;
17808 while (boardp->adv_sgblkp) {
17809 adv_sgblk_t *sgp = boardp->adv_sgblkp;
17810 boardp->adv_sgblkp = sgp->next_sgblkp;
17811 kfree(sgp);
17812 }
17813}
17814
27c868c2
MW
17815static struct Scsi_Host *__devinit
17816advansys_board_found(int iop, struct device *dev, int bus_type)
17817{
17818 struct Scsi_Host *shost;
17819 struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL;
17820 asc_board_t *boardp;
17821 ASC_DVC_VAR *asc_dvc_varp = NULL;
17822 ADV_DVC_VAR *adv_dvc_varp = NULL;
074c8fe4 17823 int share_irq;
27c868c2
MW
17824 int iolen = 0;
17825 ADV_PADDR pci_memory_address;
17826 int warn_code, err_code;
17827 int ret;
17828
17829 /*
17830 * Adapter found.
17831 *
17832 * Register the adapter, get its configuration, and
17833 * initialize it.
17834 */
8dfb5379
MW
17835 ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n");
17836 shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t));
27c868c2
MW
17837
17838 if (!shost)
17839 return NULL;
17840
17841 /* Save a pointer to the Scsi_Host of each board found. */
17842 asc_host[asc_board_count++] = shost;
17843
17844 /* Initialize private per board data */
17845 boardp = ASC_BOARDP(shost);
17846 memset(boardp, 0, sizeof(asc_board_t));
17847 boardp->id = asc_board_count - 1;
17848
17849 /* Initialize spinlock. */
17850 spin_lock_init(&boardp->lock);
17851
17852 /*
17853 * Handle both narrow and wide boards.
17854 *
17855 * If a Wide board was detected, set the board structure
17856 * wide board flag. Set-up the board structure based on
17857 * the board type.
17858 */
17859#ifdef CONFIG_PCI
17860 if (bus_type == ASC_IS_PCI &&
17861 (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
17862 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
17863 pdev->device == PCI_DEVICE_ID_38C1600_REV1)) {
17864 boardp->flags |= ASC_IS_WIDE_BOARD;
17865 }
17866#endif /* CONFIG_PCI */
17867
17868 if (ASC_NARROW_BOARD(boardp)) {
17869 ASC_DBG(1, "advansys_board_found: narrow board\n");
17870 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
17871 asc_dvc_varp->bus_type = bus_type;
17872 asc_dvc_varp->drv_ptr = boardp;
17873 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
17874 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
17875 asc_dvc_varp->iop_base = iop;
17876 asc_dvc_varp->isr_callback = asc_isr_callback;
17877 } else {
17878 ASC_DBG(1, "advansys_board_found: wide board\n");
17879 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
17880 adv_dvc_varp->drv_ptr = boardp;
17881 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
17882 adv_dvc_varp->isr_callback = adv_isr_callback;
17883 adv_dvc_varp->async_callback = adv_async_callback;
17884#ifdef CONFIG_PCI
17885 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
17886 ASC_DBG(1, "advansys_board_found: ASC-3550\n");
17887 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
17888 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
17889 ASC_DBG(1, "advansys_board_found: ASC-38C0800\n");
17890 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
17891 } else {
17892 ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
17893 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
17894 }
17895#endif /* CONFIG_PCI */
17896
17897 /*
17898 * Map the board's registers into virtual memory for
17899 * PCI slave access. Only memory accesses are used to
17900 * access the board's registers.
17901 *
17902 * Note: The PCI register base address is not always
17903 * page aligned, but the address passed to ioremap()
17904 * must be page aligned. It is guaranteed that the
17905 * PCI register base address will not cross a page
17906 * boundary.
17907 */
17908 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17909 iolen = ADV_3550_IOLEN;
17910 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17911 iolen = ADV_38C0800_IOLEN;
17912 } else {
17913 iolen = ADV_38C1600_IOLEN;
17914 }
17915#ifdef CONFIG_PCI
17916 pci_memory_address = pci_resource_start(pdev, 1);
17917 ASC_DBG1(1,
17918 "advansys_board_found: pci_memory_address: 0x%lx\n",
17919 (ulong)pci_memory_address);
17920 if ((boardp->ioremap_addr =
17921 ioremap(pci_memory_address & PAGE_MASK, PAGE_SIZE)) == 0) {
17922 ASC_PRINT3
17923 ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
17924 boardp->id, pci_memory_address, iolen);
b2c16f58 17925 goto err_shost;
27c868c2
MW
17926 }
17927 ASC_DBG1(1,
17928 "advansys_board_found: ioremap_addr: 0x%lx\n",
17929 (ulong)boardp->ioremap_addr);
17930 adv_dvc_varp->iop_base = (AdvPortAddr)
17931 (boardp->ioremap_addr +
17932 (pci_memory_address - (pci_memory_address & PAGE_MASK)));
17933 ASC_DBG1(1,
17934 "advansys_board_found: iop_base: 0x%lx\n",
17935 adv_dvc_varp->iop_base);
17936#endif /* CONFIG_PCI */
17937
17938 /*
17939 * Even though it isn't used to access wide boards, other
17940 * than for the debug line below, save I/O Port address so
17941 * that it can be reported.
17942 */
17943 boardp->ioport = iop;
17944
17945 ASC_DBG2(1,
17946 "advansys_board_found: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
17947 (ushort)inp(iop + 1), (ushort)inpw(iop));
17948 }
17949
17950#ifdef CONFIG_PROC_FS
17951 /*
17952 * Allocate buffer for printing information from
17953 * /proc/scsi/advansys/[0...].
17954 */
b2c16f58
MW
17955 boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
17956 if (!boardp->prtbuf) {
17957 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
17958 "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
17959 goto err_unmap;
27c868c2
MW
17960 }
17961#endif /* CONFIG_PROC_FS */
17962
17963 if (ASC_NARROW_BOARD(boardp)) {
17964 asc_dvc_varp->cfg->dev = dev;
17965 /*
17966 * Set the board bus type and PCI IRQ before
17967 * calling AscInitGetConfig().
17968 */
17969 switch (asc_dvc_varp->bus_type) {
17970#ifdef CONFIG_ISA
17971 case ASC_IS_ISA:
17972 shost->unchecked_isa_dma = TRUE;
074c8fe4 17973 share_irq = 0;
27c868c2
MW
17974 break;
17975 case ASC_IS_VL:
17976 shost->unchecked_isa_dma = FALSE;
074c8fe4 17977 share_irq = 0;
27c868c2
MW
17978 break;
17979 case ASC_IS_EISA:
17980 shost->unchecked_isa_dma = FALSE;
074c8fe4 17981 share_irq = IRQF_SHARED;
27c868c2
MW
17982 break;
17983#endif /* CONFIG_ISA */
17984#ifdef CONFIG_PCI
17985 case ASC_IS_PCI:
17986 shost->irq = asc_dvc_varp->irq_no = pdev->irq;
17987 asc_dvc_varp->cfg->pci_slot_info =
17988 ASC_PCI_MKID(pdev->bus->number,
17989 PCI_SLOT(pdev->devfn),
17990 PCI_FUNC(pdev->devfn));
17991 shost->unchecked_isa_dma = FALSE;
074c8fe4 17992 share_irq = IRQF_SHARED;
27c868c2
MW
17993 break;
17994#endif /* CONFIG_PCI */
17995 default:
17996 ASC_PRINT2
17997 ("advansys_board_found: board %d: unknown adapter type: %d\n",
17998 boardp->id, asc_dvc_varp->bus_type);
17999 shost->unchecked_isa_dma = TRUE;
074c8fe4 18000 share_irq = 0;
27c868c2
MW
18001 break;
18002 }
18003 } else {
18004 adv_dvc_varp->cfg->dev = dev;
18005 /*
18006 * For Wide boards set PCI information before calling
18007 * AdvInitGetConfig().
18008 */
18009#ifdef CONFIG_PCI
18010 shost->irq = adv_dvc_varp->irq_no = pdev->irq;
18011 adv_dvc_varp->cfg->pci_slot_info =
18012 ASC_PCI_MKID(pdev->bus->number,
18013 PCI_SLOT(pdev->devfn),
18014 PCI_FUNC(pdev->devfn));
18015 shost->unchecked_isa_dma = FALSE;
074c8fe4 18016 share_irq = IRQF_SHARED;
27c868c2
MW
18017#endif /* CONFIG_PCI */
18018 }
18019
18020 /*
18021 * Read the board configuration.
18022 */
18023 if (ASC_NARROW_BOARD(boardp)) {
18024 /*
18025 * NOTE: AscInitGetConfig() may change the board's
18026 * bus_type value. The bus_type value should no
18027 * longer be used. If the bus_type field must be
18028 * referenced only use the bit-wise AND operator "&".
18029 */
18030 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
18031 switch (ret = AscInitGetConfig(asc_dvc_varp)) {
18032 case 0: /* No error */
18033 break;
18034 case ASC_WARN_IO_PORT_ROTATE:
18035 ASC_PRINT1
18036 ("AscInitGetConfig: board %d: I/O port address modified\n",
18037 boardp->id);
18038 break;
18039 case ASC_WARN_AUTO_CONFIG:
18040 ASC_PRINT1
18041 ("AscInitGetConfig: board %d: I/O port increment switch enabled\n",
18042 boardp->id);
18043 break;
18044 case ASC_WARN_EEPROM_CHKSUM:
18045 ASC_PRINT1
18046 ("AscInitGetConfig: board %d: EEPROM checksum error\n",
18047 boardp->id);
18048 break;
18049 case ASC_WARN_IRQ_MODIFIED:
18050 ASC_PRINT1
18051 ("AscInitGetConfig: board %d: IRQ modified\n",
18052 boardp->id);
18053 break;
18054 case ASC_WARN_CMD_QNG_CONFLICT:
18055 ASC_PRINT1
18056 ("AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
18057 boardp->id);
18058 break;
18059 default:
18060 ASC_PRINT2
18061 ("AscInitGetConfig: board %d: unknown warning: 0x%x\n",
18062 boardp->id, ret);
18063 break;
18064 }
18065 if ((err_code = asc_dvc_varp->err_code) != 0) {
18066 ASC_PRINT3
18067 ("AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
18068 boardp->id,
18069 asc_dvc_varp->init_state, asc_dvc_varp->err_code);
18070 }
18071 } else {
18072 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
18073 if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
18074 ASC_PRINT2
18075 ("AdvInitGetConfig: board %d: warning: 0x%x\n",
18076 boardp->id, ret);
18077 }
18078 if ((err_code = adv_dvc_varp->err_code) != 0) {
18079 ASC_PRINT2
18080 ("AdvInitGetConfig: board %d error: err_code 0x%x\n",
18081 boardp->id, adv_dvc_varp->err_code);
18082 }
18083 }
18084
b2c16f58
MW
18085 if (err_code != 0)
18086 goto err_free_proc;
27c868c2
MW
18087
18088 /*
18089 * Save the EEPROM configuration so that it can be displayed
18090 * from /proc/scsi/advansys/[0...].
18091 */
18092 if (ASC_NARROW_BOARD(boardp)) {
18093
18094 ASCEEP_CONFIG *ep;
18095
18096 /*
18097 * Set the adapter's target id bit in the 'init_tidmask' field.
18098 */
18099 boardp->init_tidmask |=
18100 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
18101
18102 /*
18103 * Save EEPROM settings for the board.
18104 */
18105 ep = &boardp->eep_config.asc_eep;
18106
18107 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
18108 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
18109 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
18110 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
18111 ep->start_motor = asc_dvc_varp->start_motor;
18112 ep->cntl = asc_dvc_varp->dvc_cntl;
18113 ep->no_scam = asc_dvc_varp->no_scam;
18114 ep->max_total_qng = asc_dvc_varp->max_total_qng;
18115 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
18116 /* 'max_tag_qng' is set to the same value for every device. */
18117 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
18118 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
18119 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
18120 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
18121 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
18122 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
18123 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
18124
18125 /*
18126 * Modify board configuration.
18127 */
18128 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
18129 switch (ret = AscInitSetConfig(asc_dvc_varp)) {
18130 case 0: /* No error. */
18131 break;
18132 case ASC_WARN_IO_PORT_ROTATE:
18133 ASC_PRINT1
18134 ("AscInitSetConfig: board %d: I/O port address modified\n",
18135 boardp->id);
18136 break;
18137 case ASC_WARN_AUTO_CONFIG:
18138 ASC_PRINT1
18139 ("AscInitSetConfig: board %d: I/O port increment switch enabled\n",
18140 boardp->id);
18141 break;
18142 case ASC_WARN_EEPROM_CHKSUM:
18143 ASC_PRINT1
18144 ("AscInitSetConfig: board %d: EEPROM checksum error\n",
18145 boardp->id);
18146 break;
18147 case ASC_WARN_IRQ_MODIFIED:
18148 ASC_PRINT1
18149 ("AscInitSetConfig: board %d: IRQ modified\n",
18150 boardp->id);
18151 break;
18152 case ASC_WARN_CMD_QNG_CONFLICT:
18153 ASC_PRINT1
18154 ("AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
18155 boardp->id);
18156 break;
18157 default:
18158 ASC_PRINT2
18159 ("AscInitSetConfig: board %d: unknown warning: 0x%x\n",
18160 boardp->id, ret);
18161 break;
18162 }
18163 if (asc_dvc_varp->err_code != 0) {
18164 ASC_PRINT3
18165 ("AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
18166 boardp->id,
18167 asc_dvc_varp->init_state, asc_dvc_varp->err_code);
b2c16f58 18168 goto err_free_proc;
27c868c2
MW
18169 }
18170
18171 /*
18172 * Finish initializing the 'Scsi_Host' structure.
18173 */
18174 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
18175 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
18176 shost->irq = asc_dvc_varp->irq_no;
18177 }
18178 } else {
18179 ADVEEP_3550_CONFIG *ep_3550;
18180 ADVEEP_38C0800_CONFIG *ep_38C0800;
18181 ADVEEP_38C1600_CONFIG *ep_38C1600;
18182
18183 /*
18184 * Save Wide EEP Configuration Information.
18185 */
18186 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
18187 ep_3550 = &boardp->eep_config.adv_3550_eep;
18188
18189 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
18190 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
18191 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
18192 ep_3550->termination = adv_dvc_varp->cfg->termination;
18193 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
18194 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
18195 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
18196 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
18197 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
18198 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
18199 ep_3550->start_motor = adv_dvc_varp->start_motor;
18200 ep_3550->scsi_reset_delay =
18201 adv_dvc_varp->scsi_reset_wait;
18202 ep_3550->serial_number_word1 =
18203 adv_dvc_varp->cfg->serial1;
18204 ep_3550->serial_number_word2 =
18205 adv_dvc_varp->cfg->serial2;
18206 ep_3550->serial_number_word3 =
18207 adv_dvc_varp->cfg->serial3;
18208 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
18209 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
18210
18211 ep_38C0800->adapter_scsi_id =
18212 adv_dvc_varp->chip_scsi_id;
18213 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
18214 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
18215 ep_38C0800->termination_lvd =
18216 adv_dvc_varp->cfg->termination;
18217 ep_38C0800->disc_enable =
18218 adv_dvc_varp->cfg->disc_enable;
18219 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
18220 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
18221 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
18222 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
18223 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
18224 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
18225 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
18226 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
18227 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
18228 ep_38C0800->scsi_reset_delay =
18229 adv_dvc_varp->scsi_reset_wait;
18230 ep_38C0800->serial_number_word1 =
18231 adv_dvc_varp->cfg->serial1;
18232 ep_38C0800->serial_number_word2 =
18233 adv_dvc_varp->cfg->serial2;
18234 ep_38C0800->serial_number_word3 =
18235 adv_dvc_varp->cfg->serial3;
18236 } else {
18237 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
18238
18239 ep_38C1600->adapter_scsi_id =
18240 adv_dvc_varp->chip_scsi_id;
18241 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
18242 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
18243 ep_38C1600->termination_lvd =
18244 adv_dvc_varp->cfg->termination;
18245 ep_38C1600->disc_enable =
18246 adv_dvc_varp->cfg->disc_enable;
18247 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
18248 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
18249 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
18250 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
18251 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
18252 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
18253 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
18254 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
18255 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
18256 ep_38C1600->scsi_reset_delay =
18257 adv_dvc_varp->scsi_reset_wait;
18258 ep_38C1600->serial_number_word1 =
18259 adv_dvc_varp->cfg->serial1;
18260 ep_38C1600->serial_number_word2 =
18261 adv_dvc_varp->cfg->serial2;
18262 ep_38C1600->serial_number_word3 =
18263 adv_dvc_varp->cfg->serial3;
18264 }
18265
18266 /*
18267 * Set the adapter's target id bit in the 'init_tidmask' field.
18268 */
18269 boardp->init_tidmask |=
18270 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
18271
18272 /*
18273 * Finish initializing the 'Scsi_Host' structure.
18274 */
18275 shost->irq = adv_dvc_varp->irq_no;
18276 }
18277
18278 /*
18279 * Channels are numbered beginning with 0. For AdvanSys one host
18280 * structure supports one channel. Multi-channel boards have a
18281 * separate host structure for each channel.
18282 */
18283 shost->max_channel = 0;
18284 if (ASC_NARROW_BOARD(boardp)) {
18285 shost->max_id = ASC_MAX_TID + 1;
18286 shost->max_lun = ASC_MAX_LUN + 1;
18287
18288 shost->io_port = asc_dvc_varp->iop_base;
18289 boardp->asc_n_io_port = ASC_IOADR_GAP;
18290 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
18291
18292 /* Set maximum number of queues the adapter can handle. */
18293 shost->can_queue = asc_dvc_varp->max_total_qng;
18294 } else {
18295 shost->max_id = ADV_MAX_TID + 1;
18296 shost->max_lun = ADV_MAX_LUN + 1;
18297
18298 /*
18299 * Save the I/O Port address and length even though
18300 * I/O ports are not used to access Wide boards.
18301 * Instead the Wide boards are accessed with
18302 * PCI Memory Mapped I/O.
18303 */
18304 shost->io_port = iop;
18305 boardp->asc_n_io_port = iolen;
18306
18307 shost->this_id = adv_dvc_varp->chip_scsi_id;
18308
18309 /* Set maximum number of queues the adapter can handle. */
18310 shost->can_queue = adv_dvc_varp->max_host_qng;
18311 }
18312
18313 /*
18314 * 'n_io_port' currently is one byte.
18315 *
18316 * Set a value to 'n_io_port', but never referenced it because
18317 * it may be truncated.
18318 */
18319 shost->n_io_port = boardp->asc_n_io_port <= 255 ?
18320 boardp->asc_n_io_port : 255;
18321
18322 /*
18323 * Following v1.3.89, 'cmd_per_lun' is no longer needed
18324 * and should be set to zero.
18325 *
18326 * But because of a bug introduced in v1.3.89 if the driver is
18327 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
18328 * SCSI function 'allocate_device' will panic. To allow the driver
18329 * to work as a module in these kernels set 'cmd_per_lun' to 1.
18330 *
18331 * Note: This is wrong. cmd_per_lun should be set to the depth
18332 * you want on untagged devices always.
18333 #ifdef MODULE
18334 */
18335 shost->cmd_per_lun = 1;
18336/* #else
18337 shost->cmd_per_lun = 0;
18338#endif */
18339
18340 /*
18341 * Set the maximum number of scatter-gather elements the
18342 * adapter can handle.
18343 */
18344 if (ASC_NARROW_BOARD(boardp)) {
18345 /*
18346 * Allow two commands with 'sg_tablesize' scatter-gather
18347 * elements to be executed simultaneously. This value is
18348 * the theoretical hardware limit. It may be decreased
18349 * below.
18350 */
18351 shost->sg_tablesize =
18352 (((asc_dvc_varp->max_total_qng - 2) / 2) *
18353 ASC_SG_LIST_PER_Q) + 1;
18354 } else {
18355 shost->sg_tablesize = ADV_MAX_SG_LIST;
18356 }
18357
18358 /*
18359 * The value of 'sg_tablesize' can not exceed the SCSI
18360 * mid-level driver definition of SG_ALL. SG_ALL also
18361 * must not be exceeded, because it is used to define the
18362 * size of the scatter-gather table in 'struct asc_sg_head'.
18363 */
18364 if (shost->sg_tablesize > SG_ALL) {
18365 shost->sg_tablesize = SG_ALL;
18366 }
18367
18368 ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize);
18369
18370 /* BIOS start address. */
18371 if (ASC_NARROW_BOARD(boardp)) {
b2c16f58
MW
18372 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
18373 asc_dvc_varp->bus_type);
27c868c2
MW
18374 } else {
18375 /*
18376 * Fill-in BIOS board variables. The Wide BIOS saves
18377 * information in LRAM that is used by the driver.
18378 */
18379 AdvReadWordLram(adv_dvc_varp->iop_base,
18380 BIOS_SIGNATURE, boardp->bios_signature);
18381 AdvReadWordLram(adv_dvc_varp->iop_base,
18382 BIOS_VERSION, boardp->bios_version);
18383 AdvReadWordLram(adv_dvc_varp->iop_base,
18384 BIOS_CODESEG, boardp->bios_codeseg);
18385 AdvReadWordLram(adv_dvc_varp->iop_base,
18386 BIOS_CODELEN, boardp->bios_codelen);
18387
18388 ASC_DBG2(1,
18389 "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n",
18390 boardp->bios_signature, boardp->bios_version);
18391
18392 ASC_DBG2(1,
18393 "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n",
18394 boardp->bios_codeseg, boardp->bios_codelen);
18395
18396 /*
18397 * If the BIOS saved a valid signature, then fill in
18398 * the BIOS code segment base address.
18399 */
18400 if (boardp->bios_signature == 0x55AA) {
18401 /*
18402 * Convert x86 realmode code segment to a linear
18403 * address by shifting left 4.
18404 */
18405 shost->base = ((ulong)boardp->bios_codeseg << 4);
18406 } else {
18407 shost->base = 0;
18408 }
18409 }
18410
18411 /*
18412 * Register Board Resources - I/O Port, DMA, IRQ
18413 */
18414
18415 /*
18416 * Register I/O port range.
18417 *
18418 * For Wide boards the I/O ports are not used to access
18419 * the board, but request the region anyway.
18420 *
18421 * 'shost->n_io_port' is not referenced, because it may be truncated.
18422 */
18423 ASC_DBG2(2,
18424 "advansys_board_found: request_region port 0x%lx, len 0x%x\n",
18425 (ulong)shost->io_port, boardp->asc_n_io_port);
18426 if (request_region(shost->io_port, boardp->asc_n_io_port,
18427 "advansys") == NULL) {
18428 ASC_PRINT3
18429 ("advansys_board_found: board %d: request_region() failed, port 0x%lx, len 0x%x\n",
18430 boardp->id, (ulong)shost->io_port, boardp->asc_n_io_port);
b2c16f58 18431 goto err_free_proc;
27c868c2
MW
18432 }
18433
18434 /* Register DMA Channel for Narrow boards. */
18435 shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
18436#ifdef CONFIG_ISA
18437 if (ASC_NARROW_BOARD(boardp)) {
18438 /* Register DMA channel for ISA bus. */
18439 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
18440 shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
b2c16f58
MW
18441 ret = request_dma(shost->dma_channel, "advansys");
18442 if (ret) {
27c868c2
MW
18443 ASC_PRINT3
18444 ("advansys_board_found: board %d: request_dma() %d failed %d\n",
18445 boardp->id, shost->dma_channel, ret);
b2c16f58 18446 goto err_free_region;
27c868c2
MW
18447 }
18448 AscEnableIsaDma(shost->dma_channel);
18449 }
18450 }
18451#endif /* CONFIG_ISA */
18452
18453 /* Register IRQ Number. */
18454 ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq);
074c8fe4
MW
18455
18456 ret = request_irq(shost->irq, advansys_interrupt, share_irq,
18457 "advansys", shost);
18458
18459 if (ret) {
27c868c2
MW
18460 if (ret == -EBUSY) {
18461 ASC_PRINT2
18462 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
18463 boardp->id, shost->irq);
18464 } else if (ret == -EINVAL) {
18465 ASC_PRINT2
18466 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
18467 boardp->id, shost->irq);
18468 } else {
18469 ASC_PRINT3
18470 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
18471 boardp->id, shost->irq, ret);
18472 }
b2c16f58 18473 goto err_free_dma;
27c868c2
MW
18474 }
18475
18476 /*
18477 * Initialize board RISC chip and enable interrupts.
18478 */
18479 if (ASC_NARROW_BOARD(boardp)) {
18480 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
18481 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
18482 err_code = asc_dvc_varp->err_code;
18483
18484 if (warn_code || err_code) {
18485 ASC_PRINT4
18486 ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
18487 boardp->id,
18488 asc_dvc_varp->init_state, warn_code, err_code);
18489 }
18490 } else {
b2c16f58 18491 err_code = advansys_wide_init_chip(boardp, adv_dvc_varp);
27c868c2
MW
18492 }
18493
b2c16f58
MW
18494 if (err_code != 0)
18495 goto err_free_wide_mem;
18496
27c868c2
MW
18497 ASC_DBG_PRT_SCSI_HOST(2, shost);
18498
8dfb5379
MW
18499 ret = scsi_add_host(shost, dev);
18500 if (ret)
18501 goto err_free_wide_mem;
18502
18503 scsi_scan_host(shost);
27c868c2 18504 return shost;
b2c16f58
MW
18505
18506 err_free_wide_mem:
18507 advansys_wide_free_mem(boardp);
18508 free_irq(shost->irq, shost);
18509 err_free_dma:
18510 if (shost->dma_channel != NO_ISA_DMA)
18511 free_dma(shost->dma_channel);
18512 err_free_region:
18513 release_region(shost->io_port, boardp->asc_n_io_port);
18514 err_free_proc:
18515 kfree(boardp->prtbuf);
18516 err_unmap:
18517 if (boardp->ioremap_addr)
18518 iounmap(boardp->ioremap_addr);
18519 err_shost:
8dfb5379 18520 scsi_host_put(shost);
b2c16f58
MW
18521 asc_board_count--;
18522 return NULL;
27c868c2
MW
18523}
18524
18525/*
18526 * advansys_detect()
18527 *
18528 * Detect function for AdvanSys adapters.
18529 *
18530 * Argument is a pointer to the host driver's scsi_hosts entry.
18531 *
18532 * Return number of adapters found.
18533 *
18534 * Note: Because this function is called during system initialization
18535 * it must not call SCSI mid-level functions including scsi_malloc()
18536 * and scsi_free().
18537 */
8dfb5379 18538static int __init advansys_detect(void)
27c868c2 18539{
27c868c2
MW
18540 int iop;
18541 int bus;
18542 int ioport = 0;
18543 struct device *dev = NULL;
18544#ifdef CONFIG_PCI
18545 int pci_init_search = 0;
18546 struct pci_dev *pci_devicep[ASC_NUM_BOARD_SUPPORTED];
18547 int pci_card_cnt_max = 0;
18548 int pci_card_cnt = 0;
18549 struct pci_dev *pdev = NULL;
18550 int pci_device_id_cnt = 0;
18551 unsigned int pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
18552 PCI_DEVICE_ID_ASP_1200A,
18553 PCI_DEVICE_ID_ASP_ABP940,
18554 PCI_DEVICE_ID_ASP_ABP940U,
18555 PCI_DEVICE_ID_ASP_ABP940UW,
18556 PCI_DEVICE_ID_38C0800_REV1,
18557 PCI_DEVICE_ID_38C1600_REV1
18558 };
18559#endif /* CONFIG_PCI */
18560
27c868c2
MW
18561 ASC_DBG(1, "advansys_detect: begin\n");
18562
18563 asc_board_count = 0;
18564
18565 /*
18566 * If I/O port probing has been modified, then verify and
18567 * clean-up the 'asc_ioport' list.
18568 */
18569 if (asc_iopflag == ASC_TRUE) {
18570 for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
18571 ASC_DBG2(1, "advansys_detect: asc_ioport[%d] 0x%x\n",
18572 ioport, asc_ioport[ioport]);
18573 if (asc_ioport[ioport] != 0) {
18574 for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX;
18575 iop++) {
18576 if (_asc_def_iop_base[iop] ==
18577 asc_ioport[ioport]) {
18578 break;
18579 }
18580 }
18581 if (iop == ASC_IOADR_TABLE_MAX_IX) {
18582 printk
18583 ("AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
18584 asc_ioport[ioport]);
18585 asc_ioport[ioport] = 0;
18586 }
18587 }
18588 }
18589 ioport = 0;
18590 }
18591
18592 for (bus = 0; bus < ASC_NUM_BUS; bus++) {
18593
18594 ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
18595 bus, asc_bus_name[bus]);
18596 iop = 0;
18597
18598 while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) {
18599
18600 ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
18601 asc_board_count);
18602
18603 switch (asc_bus[bus]) {
18604 case ASC_IS_ISA:
18605 case ASC_IS_VL:
18606#ifdef CONFIG_ISA
18607 if (asc_iopflag == ASC_FALSE) {
18608 iop =
18609 AscSearchIOPortAddr(iop,
18610 asc_bus[bus]);
18611 } else {
18612 /*
18613 * ISA and VL I/O port scanning has either been
18614 * eliminated or limited to selected ports on
18615 * the LILO command line, /etc/lilo.conf, or
18616 * by setting variables when the module was loaded.
18617 */
18618 ASC_DBG(1,
18619 "advansys_detect: I/O port scanning modified\n");
18620 ioport_try_again:
18621 iop = 0;
18622 for (; ioport < ASC_NUM_IOPORT_PROBE;
18623 ioport++) {
18624 if ((iop =
18625 asc_ioport[ioport]) != 0) {
18626 break;
18627 }
18628 }
18629 if (iop) {
18630 ASC_DBG1(1,
18631 "advansys_detect: probing I/O port 0x%x...\n",
18632 iop);
18633 if (!request_region
18634 (iop, ASC_IOADR_GAP,
18635 "advansys")) {
18636 printk
18637 ("AdvanSys SCSI: specified I/O Port 0x%X is busy\n",
18638 iop);
18639 /* Don't try this I/O port twice. */
18640 asc_ioport[ioport] = 0;
18641 goto ioport_try_again;
18642 } else if (AscFindSignature(iop)
18643 == ASC_FALSE) {
18644 printk
18645 ("AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n",
18646 iop);
18647 /* Don't try this I/O port twice. */
18648 release_region(iop,
18649 ASC_IOADR_GAP);
18650 asc_ioport[ioport] = 0;
18651 goto ioport_try_again;
18652 } else {
18653 /*
18654 * If this isn't an ISA board, then it must be
18655 * a VL board. If currently looking an ISA
18656 * board is being looked for then try for
18657 * another ISA board in 'asc_ioport'.
18658 */
18659 if (asc_bus[bus] ==
18660 ASC_IS_ISA
18661 &&
18662 (AscGetChipVersion
18663 (iop,
18664 ASC_IS_ISA) &
18665 ASC_CHIP_VER_ISA_BIT)
18666 == 0) {
18667 /*
18668 * Don't clear 'asc_ioport[ioport]'. Try
18669 * this board again for VL. Increment
18670 * 'ioport' past this board.
18671 */
18672 ioport++;
18673 release_region
18674 (iop,
18675 ASC_IOADR_GAP);
18676 goto ioport_try_again;
18677 }
18678 }
18679 /*
18680 * This board appears good, don't try the I/O port
18681 * again by clearing its value. Increment 'ioport'
18682 * for the next iteration.
18683 */
18684 asc_ioport[ioport++] = 0;
18685 }
18686 }
18687#endif /* CONFIG_ISA */
18688 break;
18689
18690 case ASC_IS_EISA:
18691#ifdef CONFIG_ISA
18692 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
18693#endif /* CONFIG_ISA */
18694 break;
18695
18696 case ASC_IS_PCI:
18697#ifdef CONFIG_PCI
18698 if (pci_init_search == 0) {
18699 int i, j;
18700
18701 pci_init_search = 1;
18702
18703 /* Find all PCI cards. */
18704 while (pci_device_id_cnt <
18705 ASC_PCI_DEVICE_ID_CNT) {
18706 if ((pdev =
18707 pci_find_device
18708 (PCI_VENDOR_ID_ASP,
18709 pci_device_id
18710 [pci_device_id_cnt],
18711 pdev)) == NULL) {
18712 pci_device_id_cnt++;
18713 } else {
18714 if (pci_enable_device
18715 (pdev) == 0) {
18716 pci_devicep
18717 [pci_card_cnt_max++]
18718 = pdev;
18719 }
18720 }
18721 }
18722
18723 /*
18724 * Sort PCI cards in ascending order by PCI Bus, Slot,
18725 * and Device Number.
18726 */
18727 for (i = 0; i < pci_card_cnt_max - 1;
18728 i++) {
18729 for (j = i + 1;
18730 j < pci_card_cnt_max;
18731 j++) {
18732 if ((pci_devicep[j]->
18733 bus->number <
18734 pci_devicep[i]->
18735 bus->number)
18736 ||
18737 ((pci_devicep[j]->
18738 bus->number ==
18739 pci_devicep[i]->
18740 bus->number)
18741 &&
18742 (pci_devicep[j]->
18743 devfn <
18744 pci_devicep[i]->
18745 devfn))) {
18746 pdev =
18747 pci_devicep
18748 [i];
18749 pci_devicep[i] =
18750 pci_devicep
18751 [j];
18752 pci_devicep[j] =
18753 pdev;
18754 }
18755 }
18756 }
18757
18758 pci_card_cnt = 0;
18759 } else {
18760 pci_card_cnt++;
18761 }
18762
18763 if (pci_card_cnt == pci_card_cnt_max) {
18764 iop = 0;
18765 } else {
18766 pdev = pci_devicep[pci_card_cnt];
18767
18768 ASC_DBG2(2,
18769 "advansys_detect: devfn %d, bus number %d\n",
18770 pdev->devfn,
18771 pdev->bus->number);
18772 iop = pci_resource_start(pdev, 0);
18773 ASC_DBG2(1,
18774 "advansys_detect: vendorID %X, deviceID %X\n",
18775 pdev->vendor,
18776 pdev->device);
18777 ASC_DBG2(2,
18778 "advansys_detect: iop %X, irqLine %d\n",
18779 iop, pdev->irq);
18780 }
18781 if (pdev)
18782 dev = &pdev->dev;
18783
18784#endif /* CONFIG_PCI */
18785 break;
18786
18787 default:
18788 ASC_PRINT1
18789 ("advansys_detect: unknown bus type: %d\n",
18790 asc_bus[bus]);
18791 break;
18792 }
18793 ASC_DBG1(1, "advansys_detect: iop 0x%x\n", iop);
18794
18795 /*
18796 * Adapter not found, try next bus type.
18797 */
18798 if (iop == 0) {
18799 break;
18800 }
18801
18802 advansys_board_found(iop, dev, asc_bus[bus]);
18803 }
18804 }
18805
18806 ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n",
18807 asc_board_count);
18808 return asc_board_count;
18809}
18810
18811/*
18812 * advansys_release()
18813 *
18814 * Release resources allocated for a single AdvanSys adapter.
18815 */
18816static int advansys_release(struct Scsi_Host *shost)
18817{
18818 asc_board_t *boardp;
18819
18820 ASC_DBG(1, "advansys_release: begin\n");
8dfb5379 18821 scsi_remove_host(shost);
27c868c2 18822 boardp = ASC_BOARDP(shost);
074c8fe4 18823 free_irq(shost->irq, shost);
27c868c2
MW
18824 if (shost->dma_channel != NO_ISA_DMA) {
18825 ASC_DBG(1, "advansys_release: free_dma()\n");
18826 free_dma(shost->dma_channel);
18827 }
18828 release_region(shost->io_port, boardp->asc_n_io_port);
18829 if (ASC_WIDE_BOARD(boardp)) {
27c868c2 18830 iounmap(boardp->ioremap_addr);
b2c16f58 18831 advansys_wide_free_mem(boardp);
27c868c2 18832 }
27c868c2 18833 kfree(boardp->prtbuf);
8dfb5379 18834 scsi_host_put(shost);
27c868c2
MW
18835 ASC_DBG(1, "advansys_release: end\n");
18836 return 0;
18837}
18838
d8dafd8c 18839#ifdef CONFIG_PCI
2672ea86
DJ
18840/* PCI Devices supported by this driver */
18841static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
27c868c2
MW
18842 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
18843 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18844 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
18845 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18846 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
18847 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18848 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
18849 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18850 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
18851 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18852 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
18853 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18854 {}
2672ea86 18855};
27c868c2 18856
2672ea86 18857MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
d8dafd8c 18858#endif /* CONFIG_PCI */
8c6af9e1 18859
8dfb5379
MW
18860static int __init advansys_init(void)
18861{
18862 int count;
18863 count = advansys_detect();
18864 if (count == 0)
18865 return -ENODEV;
18866
18867 return 0;
18868}
18869
18870static void __exit advansys_exit(void)
18871{
18872 int i;
18873
18874 for (i = 0; i < asc_board_count; i++)
18875 advansys_release(asc_host[i]);
18876}
18877
18878module_init(advansys_init);
18879module_exit(advansys_exit);
18880
8c6af9e1 18881MODULE_LICENSE("GPL");