[SCSI] advansys: Remove library-style callback routines
[deliverable/linux.git] / drivers / scsi / advansys.c
CommitLineData
8c6af9e1 1#define ASC_VERSION "3.4" /* AdvanSys Driver Version */
1da177e4
LT
2
3/*
4 * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
5 *
6 * Copyright (c) 1995-2000 Advanced System Products, Inc.
7 * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
8c6af9e1 8 * Copyright (c) 2007 Matthew Wilcox <matthew@wil.cx>
1da177e4
LT
9 * All Rights Reserved.
10 *
8c6af9e1
MW
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17/*
1da177e4
LT
18 * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
19 * changed its name to ConnectCom Solutions, Inc.
8c6af9e1 20 * On June 18, 2001 Initio Corp. acquired ConnectCom's SCSI assets
1da177e4
LT
21 */
22
23/*
24
25 Documentation for the AdvanSys Driver
26
27 A. Linux Kernels Supported by this Driver
28 B. Adapters Supported by this Driver
29 C. Linux source files modified by AdvanSys Driver
30 D. Source Comments
31 E. Driver Compile Time Options and Debugging
32 F. Driver LILO Option
33 G. Tests to run before releasing new driver
34 H. Release History
35 I. Known Problems/Fix List
36 J. Credits (Chronological Order)
37
38 A. Linux Kernels Supported by this Driver
39
40 This driver has been tested in the following Linux kernels: v2.2.18
41 v2.4.0. The driver is supported on v2.2 and v2.4 kernels and on x86,
42 alpha, and PowerPC platforms.
43
44 B. Adapters Supported by this Driver
45
46 AdvanSys (Advanced System Products, Inc.) manufactures the following
47 RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow
48 (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI
49 buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit
50 transfer) SCSI Host Adapters for the PCI bus.
51
52 The CDB counts below indicate the number of SCSI CDB (Command
53 Descriptor Block) requests that can be stored in the RISC chip
54 cache and board LRAM. A CDB is a single SCSI command. The driver
55 detect routine will display the number of CDBs available for each
56 adapter detected. The number of CDBs used by the driver can be
57 lowered in the BIOS by changing the 'Host Queue Size' adapter setting.
58
59 Laptop Products:
60 ABP-480 - Bus-Master CardBus (16 CDB) (2.4 kernel and greater)
61
62 Connectivity Products:
63 ABP510/5150 - Bus-Master ISA (240 CDB)
64 ABP5140 - Bus-Master ISA PnP (16 CDB)
65 ABP5142 - Bus-Master ISA PnP with floppy (16 CDB)
66 ABP902/3902 - Bus-Master PCI (16 CDB)
67 ABP3905 - Bus-Master PCI (16 CDB)
68 ABP915 - Bus-Master PCI (16 CDB)
69 ABP920 - Bus-Master PCI (16 CDB)
70 ABP3922 - Bus-Master PCI (16 CDB)
71 ABP3925 - Bus-Master PCI (16 CDB)
72 ABP930 - Bus-Master PCI (16 CDB)
73 ABP930U - Bus-Master PCI Ultra (16 CDB)
74 ABP930UA - Bus-Master PCI Ultra (16 CDB)
75 ABP960 - Bus-Master PCI MAC/PC (16 CDB)
76 ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
77
78 Single Channel Products:
79 ABP542 - Bus-Master ISA with floppy (240 CDB)
80 ABP742 - Bus-Master EISA (240 CDB)
81 ABP842 - Bus-Master VL (240 CDB)
82 ABP940 - Bus-Master PCI (240 CDB)
83 ABP940U - Bus-Master PCI Ultra (240 CDB)
84 ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB)
85 ABP970 - Bus-Master PCI MAC/PC (240 CDB)
86 ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
87 ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB)
88 ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB)
89 ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB)
90 ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB)
91
92 Multi-Channel Products:
93 ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
94 ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
95 ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
96 ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel)
97 ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
98 ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
99 ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.)
100 ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB)
101 ABP3950U3W - Bus-Master PCI Dual LVD2/Ultra3-Wide (253 CDB)
102
103 C. Linux source files modified by AdvanSys Driver
104
105 This section for historical purposes documents the changes
106 originally made to the Linux kernel source to add the advansys
107 driver. As Linux has changed some of these files have also
108 been modified.
109
110 1. linux/arch/i386/config.in:
111
112 bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
113
114 2. linux/drivers/scsi/hosts.c:
115
116 #ifdef CONFIG_SCSI_ADVANSYS
117 #include "advansys.h"
118 #endif
119
d0be4a7d 120 and after "static struct scsi_host_template builtin_scsi_hosts[] =":
1da177e4
LT
121
122 #ifdef CONFIG_SCSI_ADVANSYS
123 ADVANSYS,
124 #endif
125
126 3. linux/drivers/scsi/Makefile:
127
128 ifdef CONFIG_SCSI_ADVANSYS
129 SCSI_SRCS := $(SCSI_SRCS) advansys.c
130 SCSI_OBJS := $(SCSI_OBJS) advansys.o
131 else
132 SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
133 endif
134
135 4. linux/init/main.c:
136
137 extern void advansys_setup(char *str, int *ints);
138
139 and add the following lines to the bootsetups[] array.
140
141 #ifdef CONFIG_SCSI_ADVANSYS
142 { "advansys=", advansys_setup },
143 #endif
144
145 D. Source Comments
146
147 1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
148
149 2. This driver should be maintained in multiple files. But to make
150 it easier to include with Linux and to follow Linux conventions,
151 the whole driver is maintained in the source files advansys.h and
152 advansys.c. In this file logical sections of the driver begin with
153 a comment that contains '---'. The following are the logical sections
154 of the driver below.
155
156 --- Linux Version
157 --- Linux Include File
158 --- Driver Options
159 --- Debugging Header
160 --- Asc Library Constants and Macros
161 --- Adv Library Constants and Macros
162 --- Driver Constants and Macros
163 --- Driver Structures
164 --- Driver Data
165 --- Driver Function Prototypes
d0be4a7d 166 --- Linux 'struct scsi_host_template' and advansys_setup() Functions
1da177e4
LT
167 --- Loadable Driver Support
168 --- Miscellaneous Driver Functions
169 --- Functions Required by the Asc Library
170 --- Functions Required by the Adv Library
171 --- Tracing and Debugging Functions
172 --- Asc Library Functions
173 --- Adv Library Functions
174
175 3. The string 'XXX' is used to flag code that needs to be re-written
176 or that contains a problem that needs to be addressed.
177
178 4. I have stripped comments from and reformatted the source for the
179 Asc Library and Adv Library to reduce the size of this file. This
180 source can be found under the following headings. The Asc Library
181 is used to support Narrow Boards. The Adv Library is used to
182 support Wide Boards.
183
184 --- Asc Library Constants and Macros
185 --- Adv Library Constants and Macros
186 --- Asc Library Functions
187 --- Adv Library Functions
188
189 E. Driver Compile Time Options and Debugging
190
191 In this source file the following constants can be defined. They are
192 defined in the source below. Both of these options are enabled by
193 default.
194
195 1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled)
196
197 Enabling this option adds assertion logic statements to the
198 driver. If an assertion fails a message will be displayed to
199 the console, but the system will continue to operate. Any
200 assertions encountered should be reported to the person
201 responsible for the driver. Assertion statements may proactively
202 detect problems with the driver and facilitate fixing these
203 problems. Enabling assertions will add a small overhead to the
204 execution of the driver.
205
206 2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled)
207
208 Enabling this option adds tracing functions to the driver and
209 the ability to set a driver tracing level at boot time. This
210 option will also export symbols not required outside the driver to
211 the kernel name space. This option is very useful for debugging
212 the driver, but it will add to the size of the driver execution
213 image and add overhead to the execution of the driver.
214
215 The amount of debugging output can be controlled with the global
216 variable 'asc_dbglvl'. The higher the number the more output. By
217 default the debug level is 0.
218
219 If the driver is loaded at boot time and the LILO Driver Option
220 is included in the system, the debug level can be changed by
221 specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
222 first three hex digits of the pseudo I/O Port must be set to
223 'deb' and the fourth hex digit specifies the debug level: 0 - F.
224 The following command line will look for an adapter at 0x330
225 and set the debug level to 2.
226
227 linux advansys=0x330,0,0,0,0xdeb2
228
229 If the driver is built as a loadable module this variable can be
230 defined when the driver is loaded. The following insmod command
231 will set the debug level to one.
232
233 insmod advansys.o asc_dbglvl=1
234
235 Debugging Message Levels:
236 0: Errors Only
237 1: High-Level Tracing
238 2-N: Verbose Tracing
239
240 To enable debug output to console, please make sure that:
241
242 a. System and kernel logging is enabled (syslogd, klogd running).
243 b. Kernel messages are routed to console output. Check
244 /etc/syslog.conf for an entry similar to this:
245
246 kern.* /dev/console
247
248 c. klogd is started with the appropriate -c parameter
249 (e.g. klogd -c 8)
250
251 This will cause printk() messages to be be displayed on the
252 current console. Refer to the klogd(8) and syslogd(8) man pages
253 for details.
254
255 Alternatively you can enable printk() to console with this
256 program. However, this is not the 'official' way to do this.
257 Debug output is logged in /var/log/messages.
258
259 main()
260 {
261 syscall(103, 7, 0, 0);
262 }
263
264 Increasing LOG_BUF_LEN in kernel/printk.c to something like
265 40960 allows more debug messages to be buffered in the kernel
266 and written to the console or log file.
267
268 3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0)
269
270 Enabling this option adds statistics collection and display
271 through /proc to the driver. The information is useful for
272 monitoring driver and device performance. It will add to the
273 size of the driver execution image and add minor overhead to
274 the execution of the driver.
275
276 Statistics are maintained on a per adapter basis. Driver entry
277 point call counts and transfer size counts are maintained.
278 Statistics are only available for kernels greater than or equal
279 to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured.
280
281 AdvanSys SCSI adapter files have the following path name format:
282
c304ec94 283 /proc/scsi/advansys/{0,1,2,3,...}
1da177e4
LT
284
285 This information can be displayed with cat. For example:
286
287 cat /proc/scsi/advansys/0
288
289 When ADVANSYS_STATS is not defined the AdvanSys /proc files only
290 contain adapter and device configuration information.
291
292 F. Driver LILO Option
293
294 If init/main.c is modified as described in the 'Directions for Adding
295 the AdvanSys Driver to Linux' section (B.4.) above, the driver will
296 recognize the 'advansys' LILO command line and /etc/lilo.conf option.
297 This option can be used to either disable I/O port scanning or to limit
298 scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
299 PCI boards will still be searched for and detected. This option only
300 affects searching for ISA and VL boards.
301
302 Examples:
303 1. Eliminate I/O port scanning:
304 boot: linux advansys=
305 or
306 boot: linux advansys=0x0
307 2. Limit I/O port scanning to one I/O port:
308 boot: linux advansys=0x110
309 3. Limit I/O port scanning to four I/O ports:
310 boot: linux advansys=0x110,0x210,0x230,0x330
311
312 For a loadable module the same effect can be achieved by setting
313 the 'asc_iopflag' variable and 'asc_ioport' array when loading
314 the driver, e.g.
315
316 insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
317
318 If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1)
319 I/O Port may be added to specify the driver debug level. Refer to
320 the 'Driver Compile Time Options and Debugging' section above for
321 more information.
322
323 G. Tests to run before releasing new driver
324
325 1. In the supported kernels verify there are no warning or compile
326 errors when the kernel is built as both a driver and as a module
327 and with the following options:
328
329 ADVANSYS_DEBUG - enabled and disabled
330 CONFIG_SMP - enabled and disabled
331 CONFIG_PROC_FS - enabled and disabled
332
333 2. Run tests on an x86, alpha, and PowerPC with at least one narrow
334 card and one wide card attached to a hard disk and CD-ROM drive:
335 fdisk, mkfs, fsck, bonnie, copy/compare test from the
336 CD-ROM to the hard drive.
337
338 H. Release History
339
340 BETA-1.0 (12/23/95):
341 First Release
342
343 BETA-1.1 (12/28/95):
344 1. Prevent advansys_detect() from being called twice.
345 2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
346
347 1.2 (1/12/96):
348 1. Prevent re-entrancy in the interrupt handler which
349 resulted in the driver hanging Linux.
350 2. Fix problem that prevented ABP-940 cards from being
351 recognized on some PCI motherboards.
352 3. Add support for the ABP-5140 PnP ISA card.
353 4. Fix check condition return status.
354 5. Add conditionally compiled code for Linux v1.3.X.
355
356 1.3 (2/23/96):
357 1. Fix problem in advansys_biosparam() that resulted in the
358 wrong drive geometry being returned for drives > 1GB with
359 extended translation enabled.
360 2. Add additional tracing during device initialization.
361 3. Change code that only applies to ISA PnP adapter.
362 4. Eliminate 'make dep' warning.
363 5. Try to fix problem with handling resets by increasing their
364 timeout value.
365
366 1.4 (5/8/96):
367 1. Change definitions to eliminate conflicts with other subsystems.
368 2. Add versioning code for the shared interrupt changes.
369 3. Eliminate problem in asc_rmqueue() with iterating after removing
370 a request.
371 4. Remove reset request loop problem from the "Known Problems or
372 Issues" section. This problem was isolated and fixed in the
373 mid-level SCSI driver.
374
375 1.5 (8/8/96):
376 1. Add support for ABP-940U (PCI Ultra) adapter.
1d6f359a 377 2. Add support for IRQ sharing by setting the IRQF_SHARED flag for
1da177e4
LT
378 request_irq and supplying a dev_id pointer to both request_irq()
379 and free_irq().
380 3. In AscSearchIOPortAddr11() restore a call to check_region() which
381 should be used before I/O port probing.
382 4. Fix bug in asc_prt_hex() which resulted in the displaying
383 the wrong data.
384 5. Incorporate miscellaneous Asc Library bug fixes and new microcode.
385 6. Change driver versioning to be specific to each Linux sub-level.
386 7. Change statistics gathering to be per adapter instead of global
387 to the driver.
388 8. Add more information and statistics to the adapter /proc file:
389 /proc/scsi/advansys[0...].
390 9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list.
391 This problem has been addressed with the SCSI mid-level changes
392 made in v1.3.89. The advansys_select_queue_depths() function
393 was added for the v1.3.89 changes.
394
395 1.6 (9/10/96):
396 1. Incorporate miscellaneous Asc Library bug fixes and new microcode.
397
398 1.7 (9/25/96):
399 1. Enable clustering and optimize the setting of the maximum number
400 of scatter gather elements for any particular board. Clustering
401 increases CPU utilization, but results in a relatively larger
402 increase in I/O throughput.
403 2. Improve the performance of the request queuing functions by
404 adding a last pointer to the queue structure.
405 3. Correct problems with reset and abort request handling that
406 could have hung or crashed Linux.
407 4. Add more information to the adapter /proc file:
408 /proc/scsi/advansys[0...].
409 5. Remove the request timeout issue form the driver issues list.
410 6. Miscellaneous documentation additions and changes.
411
412 1.8 (10/4/96):
413 1. Make changes to handle the new v2.1.0 kernel memory mapping
414 in which a kernel virtual address may not be equivalent to its
415 bus or DMA memory address.
416 2. Change abort and reset request handling to make it yet even
417 more robust.
418 3. Try to mitigate request starvation by sending ordered requests
419 to heavily loaded, tag queuing enabled devices.
420 4. Maintain statistics on request response time.
421 5. Add request response time statistics and other information to
422 the adapter /proc file: /proc/scsi/advansys[0...].
423
424 1.9 (10/21/96):
425 1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to
426 make use of mid-level SCSI driver device queue depth flow
427 control mechanism. This will eliminate aborts caused by a
428 device being unable to keep up with requests and eliminate
429 repeat busy or QUEUE FULL status returned by a device.
430 2. Incorporate miscellaneous Asc Library bug fixes.
431 3. To allow the driver to work in kernels with broken module
432 support set 'cmd_per_lun' if the driver is compiled as a
433 module. This change affects kernels v1.3.89 to present.
434 4. Remove PCI BIOS address from the driver banner. The PCI BIOS
435 is relocated by the motherboard BIOS and its new address can
436 not be determined by the driver.
437 5. Add mid-level SCSI queue depth information to the adapter
438 /proc file: /proc/scsi/advansys[0...].
439
440 2.0 (11/14/96):
441 1. Change allocation of global structures used for device
442 initialization to guarantee they are in DMA-able memory.
443 Previously when the driver was loaded as a module these
444 structures might not have been in DMA-able memory, causing
445 device initialization to fail.
446
447 2.1 (12/30/96):
448 1. In advansys_reset(), if the request is a synchronous reset
449 request, even if the request serial number has changed, then
450 complete the request.
451 2. Add Asc Library bug fixes including new microcode.
452 3. Clear inquiry buffer before using it.
453 4. Correct ifdef typo.
454
455 2.2 (1/15/97):
456 1. Add Asc Library bug fixes including new microcode.
457 2. Add synchronous data transfer rate information to the
458 adapter /proc file: /proc/scsi/advansys[0...].
459 3. Change ADVANSYS_DEBUG to be disabled by default. This
460 will reduce the size of the driver image, eliminate execution
461 overhead, and remove unneeded symbols from the kernel symbol
462 space that were previously added by the driver.
463 4. Add new compile-time option ADVANSYS_ASSERT for assertion
464 code that used to be defined within ADVANSYS_DEBUG. This
465 option is enabled by default.
466
467 2.8 (5/26/97):
468 1. Change version number to 2.8 to synchronize the Linux driver
469 version numbering with other AdvanSys drivers.
470 2. Reformat source files without tabs to present the same view
471 of the file to everyone regardless of the editor tab setting
472 being used.
473 3. Add Asc Library bug fixes.
474
475 3.1A (1/8/98):
476 1. Change version number to 3.1 to indicate that support for
477 Ultra-Wide adapters (ABP-940UW) is included in this release.
478 2. Add Asc Library (Narrow Board) bug fixes.
479 3. Report an underrun condition with the host status byte set
480 to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which
481 causes the underrun condition to be ignored. When Linux defines
482 its own DID_UNDERRUN the constant defined in this file can be
483 removed.
484 4. Add patch to AscWaitTixISRDone().
485 5. Add support for up to 16 different AdvanSys host adapter SCSI
486 channels in one system. This allows four cards with four channels
487 to be used in one system.
488
489 3.1B (1/9/98):
490 1. Handle that PCI register base addresses are not always page
491 aligned even though ioremap() requires that the address argument
492 be page aligned.
493
494 3.1C (1/10/98):
495 1. Update latest BIOS version checked for from the /proc file.
496 2. Don't set microcode SDTR variable at initialization. Instead
497 wait until device capabilities have been detected from an Inquiry
498 command.
499
500 3.1D (1/21/98):
501 1. Improve performance when the driver is compiled as module by
502 allowing up to 64 scatter-gather elements instead of 8.
503
504 3.1E (5/1/98):
505 1. Set time delay in AscWaitTixISRDone() to 1000 ms.
506 2. Include SMP locking changes.
507 3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS
508 access functions.
509 4. Update board serial number printing.
1d6f359a 510 5. Try allocating an IRQ both with and without the IRQF_DISABLED
1da177e4 511 flag set to allow IRQ sharing with drivers that do not set
1d6f359a 512 the IRQF_DISABLED flag. Also display a more descriptive error
1da177e4
LT
513 message if request_irq() fails.
514 6. Update to latest Asc and Adv Libraries.
515
516 3.2A (7/22/99):
517 1. Update Adv Library to 4.16 which includes support for
518 the ASC38C0800 (Ultra2/LVD) IC.
519
520 3.2B (8/23/99):
521 1. Correct PCI compile time option for v2.1.93 and greater
522 kernels, advansys_info() string, and debug compile time
523 option.
524 2. Correct DvcSleepMilliSecond() for v2.1.0 and greater
525 kernels. This caused an LVD detection/BIST problem problem
526 among other things.
527 3. Sort PCI cards by PCI Bus, Slot, Function ascending order
528 to be consistent with the BIOS.
529 4. Update to Asc Library S121 and Adv Library 5.2.
530
531 3.2C (8/24/99):
532 1. Correct PCI card detection bug introduced in 3.2B that
533 prevented PCI cards from being detected in kernels older
534 than v2.1.93.
535
536 3.2D (8/26/99):
537 1. Correct /proc device synchronous speed information display.
538 Also when re-negotiation is pending for a target device
539 note this condition with an * and footnote.
540 2. Correct initialization problem with Ultra-Wide cards that
541 have a pre-3.2 BIOS. A microcode variable changed locations
542 in 3.2 and greater BIOSes which caused WDTR to be attempted
543 erroneously with drives that don't support WDTR.
544
545 3.2E (8/30/99):
546 1. Fix compile error caused by v2.3.13 PCI structure change.
547 2. Remove field from ASCEEP_CONFIG that resulted in an EEPROM
548 checksum error for ISA cards.
549 3. Remove ASC_QUEUE_FLOW_CONTROL conditional code. The mid-level
550 SCSI changes that it depended on were never included in Linux.
551
552 3.2F (9/3/99):
553 1. Handle new initial function code added in v2.3.16 for all
554 driver versions.
555
556 3.2G (9/8/99):
557 1. Fix PCI board detection in v2.3.13 and greater kernels.
558 2. Fix comiple errors in v2.3.X with debugging enabled.
559
560 3.2H (9/13/99):
561 1. Add 64-bit address, long support for Alpha and UltraSPARC.
562 The driver has been verified to work on an Alpha system.
563 2. Add partial byte order handling support for Power PC and
564 other big-endian platforms. This support has not yet been
565 completed or verified.
566 3. For wide boards replace block zeroing of request and
567 scatter-gather structures with individual field initialization
568 to improve performance.
569 4. Correct and clarify ROM BIOS version detection.
570
571 3.2I (10/8/99):
572 1. Update to Adv Library 5.4.
573 2. Add v2.3.19 underrun reporting to asc_isr_callback() and
574 adv_isr_callback(). Remove DID_UNDERRUN constant and other
575 no longer needed code that previously documented the lack
576 of underrun handling.
577
578 3.2J (10/14/99):
579 1. Eliminate compile errors for v2.0 and earlier kernels.
580
581 3.2K (11/15/99):
582 1. Correct debug compile error in asc_prt_adv_scsi_req_q().
583 2. Update Adv Library to 5.5.
584 3. Add ifdef handling for /proc changes added in v2.3.28.
585 4. Increase Wide board scatter-gather list maximum length to
586 255 when the driver is compiled into the kernel.
587
588 3.2L (11/18/99):
589 1. Fix bug in adv_get_sglist() that caused an assertion failure
590 at line 7475. The reqp->sgblkp pointer must be initialized
591 to NULL in adv_get_sglist().
592
593 3.2M (11/29/99):
594 1. Really fix bug in adv_get_sglist().
595 2. Incorporate v2.3.29 changes into driver.
596
597 3.2N (4/1/00):
598 1. Add CONFIG_ISA ifdef code.
599 2. Include advansys_interrupts_enabled name change patch.
600 3. For >= v2.3.28 use new SCSI error handling with new function
601 advansys_eh_bus_reset(). Don't include an abort function
602 because of base library limitations.
603 4. For >= v2.3.28 use per board lock instead of io_request_lock.
604 5. For >= v2.3.28 eliminate advansys_command() and
605 advansys_command_done().
606 6. Add some changes for PowerPC (Big Endian) support, but it isn't
607 working yet.
608 7. Fix "nonexistent resource free" problem that occurred on a module
609 unload for boards with an I/O space >= 255. The 'n_io_port' field
610 is only one byte and can not be used to hold an ioport length more
611 than 255.
612
613 3.3A (4/4/00):
614 1. Update to Adv Library 5.8.
615 2. For wide cards add support for CDBs up to 16 bytes.
616 3. Eliminate warnings when CONFIG_PROC_FS is not defined.
617
618 3.3B (5/1/00):
619 1. Support for PowerPC (Big Endian) wide cards. Narrow cards
620 still need work.
621 2. Change bitfields to shift and mask access for endian
622 portability.
623
624 3.3C (10/13/00):
625 1. Update for latest 2.4 kernel.
626 2. Test ABP-480 CardBus support in 2.4 kernel - works!
627 3. Update to Asc Library S123.
628 4. Update to Adv Library 5.12.
629
630 3.3D (11/22/00):
631 1. Update for latest 2.4 kernel.
632 2. Create patches for 2.2 and 2.4 kernels.
633
634 3.3E (1/9/01):
635 1. Now that 2.4 is released remove ifdef code for kernel versions
636 less than 2.2. The driver is now only supported in kernels 2.2,
637 2.4, and greater.
638 2. Add code to release and acquire the io_request_lock in
639 the driver entrypoint functions: advansys_detect and
640 advansys_queuecommand. In kernel 2.4 the SCSI mid-level driver
641 still holds the io_request_lock on entry to SCSI low-level drivers.
642 This was supposed to be removed before 2.4 was released but never
643 happened. When the mid-level SCSI driver is changed all references
644 to the io_request_lock should be removed from the driver.
645 3. Simplify error handling by removing advansys_abort(),
646 AscAbortSRB(), AscResetDevice(). SCSI bus reset requests are
647 now handled by resetting the SCSI bus and fully re-initializing
648 the chip. This simple method of error recovery has proven to work
649 most reliably after attempts at different methods. Also now only
650 support the "new" error handling method and remove the obsolete
651 error handling interface.
652 4. Fix debug build errors.
653
654 3.3F (1/24/01):
655 1. Merge with ConnectCom version from Andy Kellner which
656 updates Adv Library to 5.14.
657 2. Make PowerPC (Big Endian) work for narrow cards and
658 fix problems writing EEPROM for wide cards.
659 3. Remove interrupts_enabled assertion function.
660
661 3.3G (2/16/01):
662 1. Return an error from narrow boards if passed a 16 byte
663 CDB. The wide board can already handle 16 byte CDBs.
664
665 3.3GJ (4/15/02):
666 1. hacks for lk 2.5 series (D. Gilbert)
667
668 3.3GJD (10/14/02):
669 1. change select_queue_depths to slave_configure
670 2. make cmd_per_lun be sane again
671
672 3.3K [2004/06/24]:
673 1. continuing cleanup for lk 2.6 series
674 2. Fix problem in lk 2.6.7-bk2 that broke PCI wide cards
675 3. Fix problem that oopsed ISA cards
676
677 I. Known Problems/Fix List (XXX)
678
679 1. Need to add memory mapping workaround. Test the memory mapping.
680 If it doesn't work revert to I/O port access. Can a test be done
681 safely?
682 2. Handle an interrupt not working. Keep an interrupt counter in
683 the interrupt handler. In the timeout function if the interrupt
684 has not occurred then print a message and run in polled mode.
685 3. Allow bus type scanning order to be changed.
686 4. Need to add support for target mode commands, cf. CAM XPT.
687
688 J. Credits (Chronological Order)
689
690 Bob Frey <bfrey@turbolinux.com.cn> wrote the AdvanSys SCSI driver
691 and maintained it up to 3.3F. He continues to answer questions
692 and help maintain the driver.
693
694 Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and
695 basis for the Linux v1.3.X changes which were included in the
696 1.2 release.
697
698 Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug
699 in advansys_biosparam() which was fixed in the 1.3 release.
700
701 Erik Ratcliffe <erik@caldera.com> has done testing of the
702 AdvanSys driver in the Caldera releases.
703
704 Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to
705 AscWaitTixISRDone() which he found necessary to make the
706 driver work with a SCSI-1 disk.
707
708 Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide
709 support in the 3.1A driver.
710
711 Doug Gilbert <dgilbert@interlog.com> has made changes and
712 suggestions to improve the driver and done a lot of testing.
713
714 Ken Mort <ken@mort.net> reported a DEBUG compile bug fixed
715 in 3.2K.
716
717 Tom Rini <trini@kernel.crashing.org> provided the CONFIG_ISA
718 patch and helped with PowerPC wide and narrow board support.
719
720 Philip Blundell <philb@gnu.org> provided an
721 advansys_interrupts_enabled patch.
722
723 Dave Jones <dave@denial.force9.co.uk> reported the compiler
724 warnings generated when CONFIG_PROC_FS was not defined in
725 the 3.2M driver.
726
727 Jerry Quinn <jlquinn@us.ibm.com> fixed PowerPC support (endian
728 problems) for wide cards.
729
730 Bryan Henderson <bryanh@giraffe-data.com> helped debug narrow
731 card error handling.
732
733 Manuel Veloso <veloso@pobox.com> worked hard on PowerPC narrow
734 board support and fixed a bug in AscGetEEPConfig().
735
736 Arnaldo Carvalho de Melo <acme@conectiva.com.br> made
737 save_flags/restore_flags changes.
738
739 Andy Kellner <AKellner@connectcom.net> continues the Advansys SCSI
740 driver development for ConnectCom (Version > 3.3F).
741
742 K. ConnectCom (AdvanSys) Contact Information
743
744 Mail: ConnectCom Solutions, Inc.
745 1150 Ringwood Court
746 San Jose, CA 95131
747 Operator/Sales: 1-408-383-9400
748 FAX: 1-408-383-9612
749 Tech Support: 1-408-467-2930
750 Tech Support E-Mail: linux@connectcom.net
751 FTP Site: ftp.connectcom.net (login: anonymous)
752 Web Site: http://www.connectcom.net
753
754*/
755
756/*
757 * --- Linux Include Files
758 */
759
1da177e4 760#include <linux/module.h>
1da177e4
LT
761#include <linux/string.h>
762#include <linux/kernel.h>
763#include <linux/types.h>
764#include <linux/ioport.h>
765#include <linux/interrupt.h>
766#include <linux/delay.h>
767#include <linux/slab.h>
768#include <linux/mm.h>
769#include <linux/proc_fs.h>
770#include <linux/init.h>
771#include <linux/blkdev.h>
c304ec94 772#include <linux/isa.h>
b09e05a7 773#include <linux/eisa.h>
8c6af9e1 774#include <linux/pci.h>
1da177e4
LT
775#include <linux/spinlock.h>
776#include <linux/dma-mapping.h>
777
778#include <asm/io.h>
779#include <asm/system.h>
780#include <asm/dma.h>
781
8c6af9e1
MW
782#include <scsi/scsi_cmnd.h>
783#include <scsi/scsi_device.h>
784#include <scsi/scsi_tcq.h>
785#include <scsi/scsi.h>
786#include <scsi/scsi_host.h>
787
b09e05a7 788/* FIXME: (by jejb@steeleye.com)
1da177e4 789 *
b09e05a7 790 * Although all of the necessary command mapping places have the
1da177e4
LT
791 * appropriate dma_map.. APIs, the driver still processes its internal
792 * queue using bus_to_virt() and virt_to_bus() which are illegal under
793 * the API. The entire queue processing structure will need to be
794 * altered to fix this.
795 */
796#warning this driver is still not properly converted to the DMA API
797
1da177e4
LT
798/*
799 * --- Driver Options
800 */
801
802/* Enable driver assertions. */
803#define ADVANSYS_ASSERT
804
805/* Enable driver /proc statistics. */
806#define ADVANSYS_STATS
807
808/* Enable driver tracing. */
809/* #define ADVANSYS_DEBUG */
810
1da177e4
LT
811/*
812 * --- Asc Library Constants and Macros
813 */
814
815#define ASC_LIB_VERSION_MAJOR 1
816#define ASC_LIB_VERSION_MINOR 24
817#define ASC_LIB_SERIAL_NUMBER 123
818
819/*
820 * Portable Data Types
821 *
822 * Any instance where a 32-bit long or pointer type is assumed
823 * for precision or HW defined structures, the following define
824 * types must be used. In Linux the char, short, and int types
825 * are all consistent at 8, 16, and 32 bits respectively. Pointers
826 * and long types are 64 bits on Alpha and UltraSPARC.
827 */
27c868c2
MW
828#define ASC_PADDR __u32 /* Physical/Bus address data type. */
829#define ASC_VADDR __u32 /* Virtual address data type. */
830#define ASC_DCNT __u32 /* Unsigned Data count type. */
831#define ASC_SDCNT __s32 /* Signed Data count type. */
1da177e4
LT
832
833/*
834 * These macros are used to convert a virtual address to a
835 * 32-bit value. This currently can be used on Linux Alpha
836 * which uses 64-bit virtual address but a 32-bit bus address.
837 * This is likely to break in the future, but doing this now
838 * will give us time to change the HW and FW to handle 64-bit
839 * addresses.
840 */
841#define ASC_VADDR_TO_U32 virt_to_bus
842#define ASC_U32_TO_VADDR bus_to_virt
843
844typedef unsigned char uchar;
845
846#ifndef TRUE
847#define TRUE (1)
848#endif
849#ifndef FALSE
850#define FALSE (0)
851#endif
852
853#define EOF (-1)
854#define ERR (-1)
855#define UW_ERR (uint)(0xFFFF)
856#define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
1da177e4
LT
857#define ASC_PCI_ID2FUNC(id) (((id) >> 8) & 0x7)
858#define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
1da177e4
LT
859
860#define ASC_DVCLIB_CALL_DONE (1)
861#define ASC_DVCLIB_CALL_FAILED (0)
862#define ASC_DVCLIB_CALL_ERROR (-1)
863
2672ea86
DJ
864#define PCI_VENDOR_ID_ASP 0x10cd
865#define PCI_DEVICE_ID_ASP_1200A 0x1100
866#define PCI_DEVICE_ID_ASP_ABP940 0x1200
867#define PCI_DEVICE_ID_ASP_ABP940U 0x1300
868#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
869#define PCI_DEVICE_ID_38C0800_REV1 0x2500
870#define PCI_DEVICE_ID_38C1600_REV1 0x2700
871
1da177e4
LT
872/*
873 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
874 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
875 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
876 * SRB structure.
877 */
878#define CC_VERY_LONG_SG_LIST 0
879#define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
880
27c868c2 881#define PortAddr unsigned short /* port address size */
1da177e4
LT
882#define inp(port) inb(port)
883#define outp(port, byte) outb((byte), (port))
884
885#define inpw(port) inw(port)
886#define outpw(port, word) outw((word), (port))
887
888#define ASC_MAX_SG_QUEUE 7
889#define ASC_MAX_SG_LIST 255
890
891#define ASC_CS_TYPE unsigned short
892
893#define ASC_IS_ISA (0x0001)
894#define ASC_IS_ISAPNP (0x0081)
895#define ASC_IS_EISA (0x0002)
896#define ASC_IS_PCI (0x0004)
897#define ASC_IS_PCI_ULTRA (0x0104)
898#define ASC_IS_PCMCIA (0x0008)
899#define ASC_IS_MCA (0x0020)
900#define ASC_IS_VL (0x0040)
901#define ASC_ISA_PNP_PORT_ADDR (0x279)
902#define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
903#define ASC_IS_WIDESCSI_16 (0x0100)
904#define ASC_IS_WIDESCSI_32 (0x0200)
905#define ASC_IS_BIG_ENDIAN (0x8000)
906#define ASC_CHIP_MIN_VER_VL (0x01)
907#define ASC_CHIP_MAX_VER_VL (0x07)
908#define ASC_CHIP_MIN_VER_PCI (0x09)
909#define ASC_CHIP_MAX_VER_PCI (0x0F)
910#define ASC_CHIP_VER_PCI_BIT (0x08)
911#define ASC_CHIP_MIN_VER_ISA (0x11)
912#define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
913#define ASC_CHIP_MAX_VER_ISA (0x27)
914#define ASC_CHIP_VER_ISA_BIT (0x30)
915#define ASC_CHIP_VER_ISAPNP_BIT (0x20)
916#define ASC_CHIP_VER_ASYN_BUG (0x21)
917#define ASC_CHIP_VER_PCI 0x08
918#define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
919#define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
920#define ASC_CHIP_MIN_VER_EISA (0x41)
921#define ASC_CHIP_MAX_VER_EISA (0x47)
922#define ASC_CHIP_VER_EISA_BIT (0x40)
923#define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
924#define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER 0x21
925#define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER 0x0A
926#define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL)
927#define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
928#define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL)
929#define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
930#define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL)
931#define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
932#define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL)
933#define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL)
934
935#define ASC_SCSI_ID_BITS 3
936#define ASC_SCSI_TIX_TYPE uchar
937#define ASC_ALL_DEVICE_BIT_SET 0xFF
938#define ASC_SCSI_BIT_ID_TYPE uchar
939#define ASC_MAX_TID 7
940#define ASC_MAX_LUN 7
941#define ASC_SCSI_WIDTH_BIT_SET 0xFF
942#define ASC_MAX_SENSE_LEN 32
943#define ASC_MIN_SENSE_LEN 14
944#define ASC_MAX_CDB_LEN 12
945#define ASC_SCSI_RESET_HOLD_TIME_US 60
946
1da177e4
LT
947/*
948 * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
949 * and CmdDt (Command Support Data) field bit definitions.
950 */
951#define ADV_INQ_RTN_VPD_AND_CMDDT 0x3
952#define ADV_INQ_RTN_CMDDT_FOR_OP_CODE 0x2
953#define ADV_INQ_RTN_VPD_FOR_PG_CODE 0x1
954#define ADV_INQ_RTN_STD_INQUIRY_DATA 0x0
955
956#define ASC_SCSIDIR_NOCHK 0x00
957#define ASC_SCSIDIR_T2H 0x08
958#define ASC_SCSIDIR_H2T 0x10
959#define ASC_SCSIDIR_NODATA 0x18
960#define SCSI_ASC_NOMEDIA 0x3A
961#define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4))
962#define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F))
963#define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13))
964#define PUT_CDB1(x) ((uchar)((uint)(x) >> 8))
1da177e4 965#define MS_SDTR_LEN 0x03
1da177e4 966#define MS_WDTR_LEN 0x02
1da177e4
LT
967
968#define ASC_SG_LIST_PER_Q 7
969#define QS_FREE 0x00
970#define QS_READY 0x01
971#define QS_DISC1 0x02
972#define QS_DISC2 0x04
973#define QS_BUSY 0x08
974#define QS_ABORTED 0x40
975#define QS_DONE 0x80
976#define QC_NO_CALLBACK 0x01
977#define QC_SG_SWAP_QUEUE 0x02
978#define QC_SG_HEAD 0x04
979#define QC_DATA_IN 0x08
980#define QC_DATA_OUT 0x10
981#define QC_URGENT 0x20
982#define QC_MSG_OUT 0x40
983#define QC_REQ_SENSE 0x80
984#define QCSG_SG_XFER_LIST 0x02
985#define QCSG_SG_XFER_MORE 0x04
986#define QCSG_SG_XFER_END 0x08
987#define QD_IN_PROGRESS 0x00
988#define QD_NO_ERROR 0x01
989#define QD_ABORTED_BY_HOST 0x02
990#define QD_WITH_ERROR 0x04
991#define QD_INVALID_REQUEST 0x80
992#define QD_INVALID_HOST_NUM 0x81
993#define QD_INVALID_DEVICE 0x82
994#define QD_ERR_INTERNAL 0xFF
995#define QHSTA_NO_ERROR 0x00
996#define QHSTA_M_SEL_TIMEOUT 0x11
997#define QHSTA_M_DATA_OVER_RUN 0x12
998#define QHSTA_M_DATA_UNDER_RUN 0x12
999#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
1000#define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
1001#define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1002#define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
1003#define QHSTA_D_HOST_ABORT_FAILED 0x23
1004#define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
1005#define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1006#define QHSTA_D_ASPI_NO_BUF_POOL 0x26
1007#define QHSTA_M_WTM_TIMEOUT 0x41
1008#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
1009#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
1010#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1011#define QHSTA_M_TARGET_STATUS_BUSY 0x45
1012#define QHSTA_M_BAD_TAG_CODE 0x46
1013#define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
1014#define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1015#define QHSTA_D_LRAM_CMP_ERROR 0x81
1016#define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1017#define ASC_FLAG_SCSIQ_REQ 0x01
1018#define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
1019#define ASC_FLAG_BIOS_ASYNC_IO 0x04
1020#define ASC_FLAG_SRB_LINEAR_ADDR 0x08
1021#define ASC_FLAG_WIN16 0x10
1022#define ASC_FLAG_WIN32 0x20
1023#define ASC_FLAG_ISA_OVER_16MB 0x40
1024#define ASC_FLAG_DOS_VM_CALLBACK 0x80
1025#define ASC_TAG_FLAG_EXTRA_BYTES 0x10
1026#define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
1027#define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
1028#define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1029#define ASC_SCSIQ_CPY_BEG 4
1030#define ASC_SCSIQ_SGHD_CPY_BEG 2
1031#define ASC_SCSIQ_B_FWD 0
1032#define ASC_SCSIQ_B_BWD 1
1033#define ASC_SCSIQ_B_STATUS 2
1034#define ASC_SCSIQ_B_QNO 3
1035#define ASC_SCSIQ_B_CNTL 4
1036#define ASC_SCSIQ_B_SG_QUEUE_CNT 5
1037#define ASC_SCSIQ_D_DATA_ADDR 8
1038#define ASC_SCSIQ_D_DATA_CNT 12
1039#define ASC_SCSIQ_B_SENSE_LEN 20
1040#define ASC_SCSIQ_DONE_INFO_BEG 22
1041#define ASC_SCSIQ_D_SRBPTR 22
1042#define ASC_SCSIQ_B_TARGET_IX 26
1043#define ASC_SCSIQ_B_CDB_LEN 28
1044#define ASC_SCSIQ_B_TAG_CODE 29
1045#define ASC_SCSIQ_W_VM_ID 30
1046#define ASC_SCSIQ_DONE_STATUS 32
1047#define ASC_SCSIQ_HOST_STATUS 33
1048#define ASC_SCSIQ_SCSI_STATUS 34
1049#define ASC_SCSIQ_CDB_BEG 36
1050#define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1051#define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
1052#define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
1053#define ASC_SCSIQ_B_SG_WK_QP 49
1054#define ASC_SCSIQ_B_SG_WK_IX 50
1055#define ASC_SCSIQ_W_ALT_DC1 52
1056#define ASC_SCSIQ_B_LIST_CNT 6
1057#define ASC_SCSIQ_B_CUR_LIST_CNT 7
1058#define ASC_SGQ_B_SG_CNTL 4
1059#define ASC_SGQ_B_SG_HEAD_QP 5
1060#define ASC_SGQ_B_SG_LIST_CNT 6
1061#define ASC_SGQ_B_SG_CUR_LIST_CNT 7
1062#define ASC_SGQ_LIST_BEG 8
1063#define ASC_DEF_SCSI1_QNG 4
1064#define ASC_MAX_SCSI1_QNG 4
1065#define ASC_DEF_SCSI2_QNG 16
1066#define ASC_MAX_SCSI2_QNG 32
1067#define ASC_TAG_CODE_MASK 0x23
1068#define ASC_STOP_REQ_RISC_STOP 0x01
1069#define ASC_STOP_ACK_RISC_STOP 0x03
1070#define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
1071#define ASC_STOP_CLEAN_UP_DISC_Q 0x20
1072#define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1073#define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1074#define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1075#define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
1076#define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
1077#define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
1078#define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1079#define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
1080
1081typedef struct asc_scsiq_1 {
27c868c2
MW
1082 uchar status;
1083 uchar q_no;
1084 uchar cntl;
1085 uchar sg_queue_cnt;
1086 uchar target_id;
1087 uchar target_lun;
1088 ASC_PADDR data_addr;
1089 ASC_DCNT data_cnt;
1090 ASC_PADDR sense_addr;
1091 uchar sense_len;
1092 uchar extra_bytes;
1da177e4
LT
1093} ASC_SCSIQ_1;
1094
1095typedef struct asc_scsiq_2 {
27c868c2
MW
1096 ASC_VADDR srb_ptr;
1097 uchar target_ix;
1098 uchar flag;
1099 uchar cdb_len;
1100 uchar tag_code;
1101 ushort vm_id;
1da177e4
LT
1102} ASC_SCSIQ_2;
1103
1104typedef struct asc_scsiq_3 {
27c868c2
MW
1105 uchar done_stat;
1106 uchar host_stat;
1107 uchar scsi_stat;
1108 uchar scsi_msg;
1da177e4
LT
1109} ASC_SCSIQ_3;
1110
1111typedef struct asc_scsiq_4 {
27c868c2
MW
1112 uchar cdb[ASC_MAX_CDB_LEN];
1113 uchar y_first_sg_list_qp;
1114 uchar y_working_sg_qp;
1115 uchar y_working_sg_ix;
1116 uchar y_res;
1117 ushort x_req_count;
1118 ushort x_reconnect_rtn;
1119 ASC_PADDR x_saved_data_addr;
1120 ASC_DCNT x_saved_data_cnt;
1da177e4
LT
1121} ASC_SCSIQ_4;
1122
1123typedef struct asc_q_done_info {
27c868c2
MW
1124 ASC_SCSIQ_2 d2;
1125 ASC_SCSIQ_3 d3;
1126 uchar q_status;
1127 uchar q_no;
1128 uchar cntl;
1129 uchar sense_len;
1130 uchar extra_bytes;
1131 uchar res;
1132 ASC_DCNT remain_bytes;
1da177e4
LT
1133} ASC_QDONE_INFO;
1134
1135typedef struct asc_sg_list {
27c868c2
MW
1136 ASC_PADDR addr;
1137 ASC_DCNT bytes;
1da177e4
LT
1138} ASC_SG_LIST;
1139
1140typedef struct asc_sg_head {
27c868c2
MW
1141 ushort entry_cnt;
1142 ushort queue_cnt;
1143 ushort entry_to_copy;
1144 ushort res;
1145 ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1da177e4
LT
1146} ASC_SG_HEAD;
1147
1148#define ASC_MIN_SG_LIST 2
1149
1150typedef struct asc_min_sg_head {
27c868c2
MW
1151 ushort entry_cnt;
1152 ushort queue_cnt;
1153 ushort entry_to_copy;
1154 ushort res;
1155 ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
1da177e4
LT
1156} ASC_MIN_SG_HEAD;
1157
1158#define QCX_SORT (0x0001)
1159#define QCX_COALEASE (0x0002)
1160
1161typedef struct asc_scsi_q {
27c868c2
MW
1162 ASC_SCSIQ_1 q1;
1163 ASC_SCSIQ_2 q2;
1164 uchar *cdbptr;
1165 ASC_SG_HEAD *sg_head;
1166 ushort remain_sg_entry_cnt;
1167 ushort next_sg_index;
1da177e4
LT
1168} ASC_SCSI_Q;
1169
1170typedef struct asc_scsi_req_q {
27c868c2
MW
1171 ASC_SCSIQ_1 r1;
1172 ASC_SCSIQ_2 r2;
1173 uchar *cdbptr;
1174 ASC_SG_HEAD *sg_head;
1175 uchar *sense_ptr;
1176 ASC_SCSIQ_3 r3;
1177 uchar cdb[ASC_MAX_CDB_LEN];
1178 uchar sense[ASC_MIN_SENSE_LEN];
1da177e4
LT
1179} ASC_SCSI_REQ_Q;
1180
1181typedef struct asc_scsi_bios_req_q {
27c868c2
MW
1182 ASC_SCSIQ_1 r1;
1183 ASC_SCSIQ_2 r2;
1184 uchar *cdbptr;
1185 ASC_SG_HEAD *sg_head;
1186 uchar *sense_ptr;
1187 ASC_SCSIQ_3 r3;
1188 uchar cdb[ASC_MAX_CDB_LEN];
1189 uchar sense[ASC_MIN_SENSE_LEN];
1da177e4
LT
1190} ASC_SCSI_BIOS_REQ_Q;
1191
1192typedef struct asc_risc_q {
27c868c2
MW
1193 uchar fwd;
1194 uchar bwd;
1195 ASC_SCSIQ_1 i1;
1196 ASC_SCSIQ_2 i2;
1197 ASC_SCSIQ_3 i3;
1198 ASC_SCSIQ_4 i4;
1da177e4
LT
1199} ASC_RISC_Q;
1200
1201typedef struct asc_sg_list_q {
27c868c2
MW
1202 uchar seq_no;
1203 uchar q_no;
1204 uchar cntl;
1205 uchar sg_head_qp;
1206 uchar sg_list_cnt;
1207 uchar sg_cur_list_cnt;
1da177e4
LT
1208} ASC_SG_LIST_Q;
1209
1210typedef struct asc_risc_sg_list_q {
27c868c2
MW
1211 uchar fwd;
1212 uchar bwd;
1213 ASC_SG_LIST_Q sg;
1214 ASC_SG_LIST sg_list[7];
1da177e4
LT
1215} ASC_RISC_SG_LIST_Q;
1216
1217#define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL
1218#define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024
1219#define ASCQ_ERR_NO_ERROR 0
1220#define ASCQ_ERR_IO_NOT_FOUND 1
1221#define ASCQ_ERR_LOCAL_MEM 2
1222#define ASCQ_ERR_CHKSUM 3
1223#define ASCQ_ERR_START_CHIP 4
1224#define ASCQ_ERR_INT_TARGET_ID 5
1225#define ASCQ_ERR_INT_LOCAL_MEM 6
1226#define ASCQ_ERR_HALT_RISC 7
1227#define ASCQ_ERR_GET_ASPI_ENTRY 8
1228#define ASCQ_ERR_CLOSE_ASPI 9
1229#define ASCQ_ERR_HOST_INQUIRY 0x0A
1230#define ASCQ_ERR_SAVED_SRB_BAD 0x0B
1231#define ASCQ_ERR_QCNTL_SG_LIST 0x0C
1232#define ASCQ_ERR_Q_STATUS 0x0D
1233#define ASCQ_ERR_WR_SCSIQ 0x0E
1234#define ASCQ_ERR_PC_ADDR 0x0F
1235#define ASCQ_ERR_SYN_OFFSET 0x10
1236#define ASCQ_ERR_SYN_XFER_TIME 0x11
1237#define ASCQ_ERR_LOCK_DMA 0x12
1238#define ASCQ_ERR_UNLOCK_DMA 0x13
1239#define ASCQ_ERR_VDS_CHK_INSTALL 0x14
1240#define ASCQ_ERR_MICRO_CODE_HALT 0x15
1241#define ASCQ_ERR_SET_LRAM_ADDR 0x16
1242#define ASCQ_ERR_CUR_QNG 0x17
1243#define ASCQ_ERR_SG_Q_LINKS 0x18
1244#define ASCQ_ERR_SCSIQ_PTR 0x19
1245#define ASCQ_ERR_ISR_RE_ENTRY 0x1A
1246#define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
1247#define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
1248#define ASCQ_ERR_SG_LIST_ODD_ADDRESS 0x1D
1249#define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1250#define ASCQ_ERR_SCSIQ_NULL_PTR 0x1F
1251#define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR 0x20
1252#define ASCQ_ERR_GET_NUM_OF_FREE_Q 0x21
1253#define ASCQ_ERR_SEND_SCSI_Q 0x22
1254#define ASCQ_ERR_HOST_REQ_RISC_HALT 0x23
1255#define ASCQ_ERR_RESET_SDTR 0x24
1256
1257/*
1258 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
1259 */
1260#define ASC_WARN_NO_ERROR 0x0000
1261#define ASC_WARN_IO_PORT_ROTATE 0x0001
1262#define ASC_WARN_EEPROM_CHKSUM 0x0002
1263#define ASC_WARN_IRQ_MODIFIED 0x0004
1264#define ASC_WARN_AUTO_CONFIG 0x0008
1265#define ASC_WARN_CMD_QNG_CONFLICT 0x0010
1266#define ASC_WARN_EEPROM_RECOVER 0x0020
1267#define ASC_WARN_CFG_MSW_RECOVER 0x0040
1268#define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1269
1270/*
1271 * Error code values are set in ASC_DVC_VAR 'err_code'.
1272 */
1273#define ASC_IERR_WRITE_EEPROM 0x0001
1274#define ASC_IERR_MCODE_CHKSUM 0x0002
1275#define ASC_IERR_SET_PC_ADDR 0x0004
1276#define ASC_IERR_START_STOP_CHIP 0x0008
1277#define ASC_IERR_IRQ_NO 0x0010
1278#define ASC_IERR_SET_IRQ_NO 0x0020
1279#define ASC_IERR_CHIP_VERSION 0x0040
1280#define ASC_IERR_SET_SCSI_ID 0x0080
1281#define ASC_IERR_GET_PHY_ADDR 0x0100
1282#define ASC_IERR_BAD_SIGNATURE 0x0200
1283#define ASC_IERR_NO_BUS_TYPE 0x0400
1284#define ASC_IERR_SCAM 0x0800
1285#define ASC_IERR_SET_SDTR 0x1000
1286#define ASC_IERR_RW_LRAM 0x8000
1287
1288#define ASC_DEF_IRQ_NO 10
1289#define ASC_MAX_IRQ_NO 15
1290#define ASC_MIN_IRQ_NO 10
1291#define ASC_MIN_REMAIN_Q (0x02)
1292#define ASC_DEF_MAX_TOTAL_QNG (0xF0)
1293#define ASC_MIN_TAG_Q_PER_DVC (0x04)
1294#define ASC_DEF_TAG_Q_PER_DVC (0x04)
1295#define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q
1296#define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1297#define ASC_MAX_TOTAL_QNG 240
1298#define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1299#define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
1300#define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
1301#define ASC_MAX_INRAM_TAG_QNG 16
1302#define ASC_IOADR_TABLE_MAX_IX 11
1303#define ASC_IOADR_GAP 0x10
1da177e4
LT
1304#define ASC_LIB_SCSIQ_WK_SP 256
1305#define ASC_MAX_SYN_XFER_NO 16
1306#define ASC_SYN_MAX_OFFSET 0x0F
1307#define ASC_DEF_SDTR_OFFSET 0x0F
1308#define ASC_DEF_SDTR_INDEX 0x00
1309#define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
1310#define SYN_XFER_NS_0 25
1311#define SYN_XFER_NS_1 30
1312#define SYN_XFER_NS_2 35
1313#define SYN_XFER_NS_3 40
1314#define SYN_XFER_NS_4 50
1315#define SYN_XFER_NS_5 60
1316#define SYN_XFER_NS_6 70
1317#define SYN_XFER_NS_7 85
1318#define SYN_ULTRA_XFER_NS_0 12
1319#define SYN_ULTRA_XFER_NS_1 19
1320#define SYN_ULTRA_XFER_NS_2 25
1321#define SYN_ULTRA_XFER_NS_3 32
1322#define SYN_ULTRA_XFER_NS_4 38
1323#define SYN_ULTRA_XFER_NS_5 44
1324#define SYN_ULTRA_XFER_NS_6 50
1325#define SYN_ULTRA_XFER_NS_7 57
1326#define SYN_ULTRA_XFER_NS_8 63
1327#define SYN_ULTRA_XFER_NS_9 69
1328#define SYN_ULTRA_XFER_NS_10 75
1329#define SYN_ULTRA_XFER_NS_11 82
1330#define SYN_ULTRA_XFER_NS_12 88
1331#define SYN_ULTRA_XFER_NS_13 94
1332#define SYN_ULTRA_XFER_NS_14 100
1333#define SYN_ULTRA_XFER_NS_15 107
1334
1335typedef struct ext_msg {
27c868c2
MW
1336 uchar msg_type;
1337 uchar msg_len;
1338 uchar msg_req;
1339 union {
1340 struct {
1341 uchar sdtr_xfer_period;
1342 uchar sdtr_req_ack_offset;
1343 } sdtr;
1344 struct {
1345 uchar wdtr_width;
1346 } wdtr;
1347 struct {
1348 uchar mdp_b3;
1349 uchar mdp_b2;
1350 uchar mdp_b1;
1351 uchar mdp_b0;
1352 } mdp;
1353 } u_ext_msg;
1354 uchar res;
1da177e4
LT
1355} EXT_MSG;
1356
1357#define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
1358#define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
1359#define wdtr_width u_ext_msg.wdtr.wdtr_width
1360#define mdp_b3 u_ext_msg.mdp_b3
1361#define mdp_b2 u_ext_msg.mdp_b2
1362#define mdp_b1 u_ext_msg.mdp_b1
1363#define mdp_b0 u_ext_msg.mdp_b0
1364
1365typedef struct asc_dvc_cfg {
27c868c2
MW
1366 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1367 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1368 ASC_SCSI_BIT_ID_TYPE disc_enable;
1369 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1370 uchar chip_scsi_id;
1371 uchar isa_dma_speed;
1372 uchar isa_dma_channel;
1373 uchar chip_version;
1374 ushort lib_serial_no;
1375 ushort lib_version;
1376 ushort mcode_date;
1377 ushort mcode_version;
1378 uchar max_tag_qng[ASC_MAX_TID + 1];
1379 uchar *overrun_buf;
1380 uchar sdtr_period_offset[ASC_MAX_TID + 1];
1381 ushort pci_slot_info;
1382 uchar adapter_info[6];
1da177e4
LT
1383} ASC_DVC_CFG;
1384
1385#define ASC_DEF_DVC_CNTL 0xFFFF
1386#define ASC_DEF_CHIP_SCSI_ID 7
1387#define ASC_DEF_ISA_DMA_SPEED 4
1388#define ASC_INIT_STATE_NULL 0x0000
1389#define ASC_INIT_STATE_BEG_GET_CFG 0x0001
1390#define ASC_INIT_STATE_END_GET_CFG 0x0002
1391#define ASC_INIT_STATE_BEG_SET_CFG 0x0004
1392#define ASC_INIT_STATE_END_SET_CFG 0x0008
1393#define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
1394#define ASC_INIT_STATE_END_LOAD_MC 0x0020
1395#define ASC_INIT_STATE_BEG_INQUIRY 0x0040
1396#define ASC_INIT_STATE_END_INQUIRY 0x0080
1397#define ASC_INIT_RESET_SCSI_DONE 0x0100
1398#define ASC_INIT_STATE_WITHOUT_EEP 0x8000
1da177e4
LT
1399#define ASC_BUG_FIX_IF_NOT_DWB 0x0001
1400#define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
1401#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1402#define ASC_MIN_TAGGED_CMD 7
1403#define ASC_MAX_SCSI_RESET_WAIT 30
1404
27c868c2 1405struct asc_dvc_var; /* Forward Declaration. */
1da177e4 1406
1da177e4 1407typedef struct asc_dvc_var {
27c868c2
MW
1408 PortAddr iop_base;
1409 ushort err_code;
1410 ushort dvc_cntl;
1411 ushort bug_fix_cntl;
1412 ushort bus_type;
27c868c2
MW
1413 ASC_SCSI_BIT_ID_TYPE init_sdtr;
1414 ASC_SCSI_BIT_ID_TYPE sdtr_done;
1415 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1416 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1417 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1418 ASC_SCSI_BIT_ID_TYPE start_motor;
1419 uchar scsi_reset_wait;
1420 uchar chip_no;
1421 char is_in_int;
1422 uchar max_total_qng;
1423 uchar cur_total_qng;
1424 uchar in_critical_cnt;
1425 uchar irq_no;
1426 uchar last_q_shortage;
1427 ushort init_state;
1428 uchar cur_dvc_qng[ASC_MAX_TID + 1];
1429 uchar max_dvc_qng[ASC_MAX_TID + 1];
1430 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
1431 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
1432 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1433 ASC_DVC_CFG *cfg;
1434 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1435 char redo_scam;
1436 ushort res2;
1437 uchar dos_int13_table[ASC_MAX_TID + 1];
1438 ASC_DCNT max_dma_count;
1439 ASC_SCSI_BIT_ID_TYPE no_scam;
1440 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1441 uchar max_sdtr_index;
1442 uchar host_init_sdtr_index;
1443 struct asc_board *drv_ptr;
1444 ASC_DCNT uc_break;
1da177e4
LT
1445} ASC_DVC_VAR;
1446
1447typedef struct asc_dvc_inq_info {
27c868c2 1448 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1da177e4
LT
1449} ASC_DVC_INQ_INFO;
1450
1451typedef struct asc_cap_info {
27c868c2
MW
1452 ASC_DCNT lba;
1453 ASC_DCNT blk_size;
1da177e4
LT
1454} ASC_CAP_INFO;
1455
1456typedef struct asc_cap_info_array {
27c868c2 1457 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1da177e4
LT
1458} ASC_CAP_INFO_ARRAY;
1459
1460#define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
1461#define ASC_MCNTL_NULL_TARGET (ushort)0x0002
1462#define ASC_CNTL_INITIATOR (ushort)0x0001
1463#define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
1464#define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
1465#define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
1466#define ASC_CNTL_NO_SCAM (ushort)0x0010
1467#define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
1468#define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
1469#define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
1470#define ASC_CNTL_RESET_SCSI (ushort)0x0200
1471#define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
1472#define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
1473#define ASC_CNTL_SCSI_PARITY (ushort)0x1000
1474#define ASC_CNTL_BURST_MODE (ushort)0x2000
1475#define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1476#define ASC_EEP_DVC_CFG_BEG_VL 2
1477#define ASC_EEP_MAX_DVC_ADDR_VL 15
1478#define ASC_EEP_DVC_CFG_BEG 32
1479#define ASC_EEP_MAX_DVC_ADDR 45
1480#define ASC_EEP_DEFINED_WORDS 10
1481#define ASC_EEP_MAX_ADDR 63
1482#define ASC_EEP_RES_WORDS 0
1483#define ASC_EEP_MAX_RETRY 20
1484#define ASC_MAX_INIT_BUSY_RETRY 8
1485#define ASC_EEP_ISA_PNP_WSIZE 16
1486
1487/*
1488 * These macros keep the chip SCSI id and ISA DMA speed
1489 * bitfields in board order. C bitfields aren't portable
1490 * between big and little-endian platforms so they are
1491 * not used.
1492 */
1493
1494#define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
1495#define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
1496#define ASC_EEP_SET_CHIP_ID(cfg, sid) \
1497 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
1498#define ASC_EEP_SET_DMA_SPD(cfg, spd) \
1499 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
1500
1501typedef struct asceep_config {
27c868c2
MW
1502 ushort cfg_lsw;
1503 ushort cfg_msw;
1504 uchar init_sdtr;
1505 uchar disc_enable;
1506 uchar use_cmd_qng;
1507 uchar start_motor;
1508 uchar max_total_qng;
1509 uchar max_tag_qng;
1510 uchar bios_scan;
1511 uchar power_up_wait;
1512 uchar no_scam;
1513 uchar id_speed; /* low order 4 bits is chip scsi id */
1514 /* high order 4 bits is isa dma speed */
1515 uchar dos_int13_table[ASC_MAX_TID + 1];
1516 uchar adapter_info[6];
1517 ushort cntl;
1518 ushort chksum;
1da177e4
LT
1519} ASCEEP_CONFIG;
1520
1521#define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800
1522#define ASC_PCI_CFG_LSW_BURST_MODE 0x0080
1523#define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020
1524
1525#define ASC_EEP_CMD_READ 0x80
1526#define ASC_EEP_CMD_WRITE 0x40
1527#define ASC_EEP_CMD_WRITE_ABLE 0x30
1528#define ASC_EEP_CMD_WRITE_DISABLE 0x00
1529#define ASC_OVERRUN_BSIZE 0x00000048UL
1530#define ASC_CTRL_BREAK_ONCE 0x0001
1531#define ASC_CTRL_BREAK_STAY_IDLE 0x0002
1532#define ASCV_MSGOUT_BEG 0x0000
1533#define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1534#define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1535#define ASCV_BREAK_SAVED_CODE (ushort)0x0006
1536#define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
1537#define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
1538#define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
1539#define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
1540#define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
1541#define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
1542#define ASCV_BREAK_ADDR (ushort)0x0028
1543#define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
1544#define ASCV_BREAK_CONTROL (ushort)0x002C
1545#define ASCV_BREAK_HIT_COUNT (ushort)0x002E
1546
1547#define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
1548#define ASCV_MCODE_CHKSUM_W (ushort)0x0032
1549#define ASCV_MCODE_SIZE_W (ushort)0x0034
1550#define ASCV_STOP_CODE_B (ushort)0x0036
1551#define ASCV_DVC_ERR_CODE_B (ushort)0x0037
1552#define ASCV_OVERRUN_PADDR_D (ushort)0x0038
1553#define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
1554#define ASCV_HALTCODE_W (ushort)0x0040
1555#define ASCV_CHKSUM_W (ushort)0x0042
1556#define ASCV_MC_DATE_W (ushort)0x0044
1557#define ASCV_MC_VER_W (ushort)0x0046
1558#define ASCV_NEXTRDY_B (ushort)0x0048
1559#define ASCV_DONENEXT_B (ushort)0x0049
1560#define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1561#define ASCV_SCSIBUSY_B (ushort)0x004B
1562#define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
1563#define ASCV_CURCDB_B (ushort)0x004D
1564#define ASCV_RCLUN_B (ushort)0x004E
1565#define ASCV_BUSY_QHEAD_B (ushort)0x004F
1566#define ASCV_DISC1_QHEAD_B (ushort)0x0050
1567#define ASCV_DISC_ENABLE_B (ushort)0x0052
1568#define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1569#define ASCV_HOSTSCSI_ID_B (ushort)0x0055
1570#define ASCV_MCODE_CNTL_B (ushort)0x0056
1571#define ASCV_NULL_TARGET_B (ushort)0x0057
1572#define ASCV_FREE_Q_HEAD_W (ushort)0x0058
1573#define ASCV_DONE_Q_TAIL_W (ushort)0x005A
1574#define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
1575#define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
1576#define ASCV_HOST_FLAG_B (ushort)0x005D
1577#define ASCV_TOTAL_READY_Q_B (ushort)0x0064
1578#define ASCV_VER_SERIAL_B (ushort)0x0065
1579#define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1580#define ASCV_WTM_FLAG_B (ushort)0x0068
1581#define ASCV_RISC_FLAG_B (ushort)0x006A
1582#define ASCV_REQ_SG_LIST_QP (ushort)0x006B
1583#define ASC_HOST_FLAG_IN_ISR 0x01
1584#define ASC_HOST_FLAG_ACK_INT 0x02
1585#define ASC_RISC_FLAG_GEN_INT 0x01
1586#define ASC_RISC_FLAG_REQ_SG_LIST 0x02
1587#define IOP_CTRL (0x0F)
1588#define IOP_STATUS (0x0E)
1589#define IOP_INT_ACK IOP_STATUS
1590#define IOP_REG_IFC (0x0D)
1591#define IOP_SYN_OFFSET (0x0B)
1592#define IOP_EXTRA_CONTROL (0x0D)
1593#define IOP_REG_PC (0x0C)
1594#define IOP_RAM_ADDR (0x0A)
1595#define IOP_RAM_DATA (0x08)
1596#define IOP_EEP_DATA (0x06)
1597#define IOP_EEP_CMD (0x07)
1598#define IOP_VERSION (0x03)
1599#define IOP_CONFIG_HIGH (0x04)
1600#define IOP_CONFIG_LOW (0x02)
1601#define IOP_SIG_BYTE (0x01)
1602#define IOP_SIG_WORD (0x00)
1603#define IOP_REG_DC1 (0x0E)
1604#define IOP_REG_DC0 (0x0C)
1605#define IOP_REG_SB (0x0B)
1606#define IOP_REG_DA1 (0x0A)
1607#define IOP_REG_DA0 (0x08)
1608#define IOP_REG_SC (0x09)
1609#define IOP_DMA_SPEED (0x07)
1610#define IOP_REG_FLAG (0x07)
1611#define IOP_FIFO_H (0x06)
1612#define IOP_FIFO_L (0x04)
1613#define IOP_REG_ID (0x05)
1614#define IOP_REG_QP (0x03)
1615#define IOP_REG_IH (0x02)
1616#define IOP_REG_IX (0x01)
1617#define IOP_REG_AX (0x00)
1618#define IFC_REG_LOCK (0x00)
1619#define IFC_REG_UNLOCK (0x09)
1620#define IFC_WR_EN_FILTER (0x10)
1621#define IFC_RD_NO_EEPROM (0x10)
1622#define IFC_SLEW_RATE (0x20)
1623#define IFC_ACT_NEG (0x40)
1624#define IFC_INP_FILTER (0x80)
1625#define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
1626#define SC_SEL (uchar)(0x80)
1627#define SC_BSY (uchar)(0x40)
1628#define SC_ACK (uchar)(0x20)
1629#define SC_REQ (uchar)(0x10)
1630#define SC_ATN (uchar)(0x08)
1631#define SC_IO (uchar)(0x04)
1632#define SC_CD (uchar)(0x02)
1633#define SC_MSG (uchar)(0x01)
1634#define SEC_SCSI_CTL (uchar)(0x80)
1635#define SEC_ACTIVE_NEGATE (uchar)(0x40)
1636#define SEC_SLEW_RATE (uchar)(0x20)
1637#define SEC_ENABLE_FILTER (uchar)(0x10)
1638#define ASC_HALT_EXTMSG_IN (ushort)0x8000
1639#define ASC_HALT_CHK_CONDITION (ushort)0x8100
1640#define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1641#define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
1642#define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
1643#define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1644#define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1645#define ASC_MAX_QNO 0xF8
1646#define ASC_DATA_SEC_BEG (ushort)0x0080
1647#define ASC_DATA_SEC_END (ushort)0x0080
1648#define ASC_CODE_SEC_BEG (ushort)0x0080
1649#define ASC_CODE_SEC_END (ushort)0x0080
1650#define ASC_QADR_BEG (0x4000)
1651#define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
1652#define ASC_QADR_END (ushort)0x7FFF
1653#define ASC_QLAST_ADR (ushort)0x7FC0
1654#define ASC_QBLK_SIZE 0x40
1655#define ASC_BIOS_DATA_QBEG 0xF8
1656#define ASC_MIN_ACTIVE_QNO 0x01
1657#define ASC_QLINK_END 0xFF
1658#define ASC_EEPROM_WORDS 0x10
1659#define ASC_MAX_MGS_LEN 0x10
1660#define ASC_BIOS_ADDR_DEF 0xDC00
1661#define ASC_BIOS_SIZE 0x3800
1662#define ASC_BIOS_RAM_OFF 0x3800
1663#define ASC_BIOS_RAM_SIZE 0x800
1664#define ASC_BIOS_MIN_ADDR 0xC000
1665#define ASC_BIOS_MAX_ADDR 0xEC00
1666#define ASC_BIOS_BANK_SIZE 0x0400
1667#define ASC_MCODE_START_ADDR 0x0080
1668#define ASC_CFG0_HOST_INT_ON 0x0020
1669#define ASC_CFG0_BIOS_ON 0x0040
1670#define ASC_CFG0_VERA_BURST_ON 0x0080
1671#define ASC_CFG0_SCSI_PARITY_ON 0x0800
1672#define ASC_CFG1_SCSI_TARGET_ON 0x0080
1673#define ASC_CFG1_LRAM_8BITS_ON 0x0800
1674#define ASC_CFG_MSW_CLR_MASK 0x3080
1675#define CSW_TEST1 (ASC_CS_TYPE)0x8000
1676#define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
1677#define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
1678#define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
1679#define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
1680#define CSW_TEST2 (ASC_CS_TYPE)0x0400
1681#define CSW_TEST3 (ASC_CS_TYPE)0x0200
1682#define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
1683#define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
1684#define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
1685#define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
1686#define CSW_HALTED (ASC_CS_TYPE)0x0010
1687#define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1688#define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
1689#define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
1690#define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
1691#define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1692#define CIW_INT_ACK (ASC_CS_TYPE)0x0100
1693#define CIW_TEST1 (ASC_CS_TYPE)0x0200
1694#define CIW_TEST2 (ASC_CS_TYPE)0x0400
1695#define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
1696#define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
1697#define CC_CHIP_RESET (uchar)0x80
1698#define CC_SCSI_RESET (uchar)0x40
1699#define CC_HALT (uchar)0x20
1700#define CC_SINGLE_STEP (uchar)0x10
1701#define CC_DMA_ABLE (uchar)0x08
1702#define CC_TEST (uchar)0x04
1703#define CC_BANK_ONE (uchar)0x02
1704#define CC_DIAG (uchar)0x01
1705#define ASC_1000_ID0W 0x04C1
1706#define ASC_1000_ID0W_FIX 0x00C1
1707#define ASC_1000_ID1B 0x25
1da177e4
LT
1708#define ASC_EISA_REV_IOP_MASK (0x0C83)
1709#define ASC_EISA_PID_IOP_MASK (0x0C80)
1710#define ASC_EISA_CFG_IOP_MASK (0x0C86)
1711#define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
1da177e4
LT
1712#define INS_HALTINT (ushort)0x6281
1713#define INS_HALT (ushort)0x6280
1714#define INS_SINT (ushort)0x6200
1715#define INS_RFLAG_WTM (ushort)0x7380
1716#define ASC_MC_SAVE_CODE_WSIZE 0x500
1717#define ASC_MC_SAVE_DATA_WSIZE 0x40
1718
1719typedef struct asc_mc_saved {
27c868c2
MW
1720 ushort data[ASC_MC_SAVE_DATA_WSIZE];
1721 ushort code[ASC_MC_SAVE_CODE_WSIZE];
1da177e4
LT
1722} ASC_MC_SAVED;
1723
1724#define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1725#define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1726#define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1727#define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1728#define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1729#define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1730#define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
1731#define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
1732#define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1733#define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1734#define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1735#define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1736#define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1737#define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1738#define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1739#define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
1740#define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
1741#define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
1742#define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
1743#define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
1744#define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
1745#define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
1746#define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
1747#define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
1748#define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
1749#define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
1750#define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1751#define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1752#define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
1753#define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
1754#define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
1755#define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
1756#define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1757#define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
1758#define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
1759#define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
1760#define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
1761#define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
1762#define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
1763#define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
1764#define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1765#define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1766#define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
1767#define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
1768#define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
1769#define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
1770#define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
1771#define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
1772#define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
1773#define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
1774#define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
1775#define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
1776#define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
1777#define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
1778#define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
1779#define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
1780#define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
1781#define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
1782#define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
1783#define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
1784#define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
1785#define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
1786#define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
1787#define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
1788#define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
1789#define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
1790#define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
1791#define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
1792
27c868c2
MW
1793static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1794static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1795static void AscWaitEEPRead(void);
1796static void AscWaitEEPWrite(void);
1797static ushort AscReadEEPWord(PortAddr, uchar);
1798static ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1799static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1800static int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1801static int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1802static int AscStartChip(PortAddr);
1803static int AscStopChip(PortAddr);
1804static void AscSetChipIH(PortAddr, ushort);
1805static int AscIsChipHalted(PortAddr);
1806static void AscAckInterrupt(PortAddr);
1807static void AscDisableInterrupt(PortAddr);
1808static void AscEnableInterrupt(PortAddr);
1809static void AscSetBank(PortAddr, uchar);
1810static int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1da177e4 1811#ifdef CONFIG_ISA
27c868c2 1812static uchar AscGetIsaDmaSpeed(PortAddr);
1da177e4 1813#endif /* CONFIG_ISA */
27c868c2
MW
1814static uchar AscReadLramByte(PortAddr, ushort);
1815static ushort AscReadLramWord(PortAddr, ushort);
1da177e4 1816#if CC_VERY_LONG_SG_LIST
27c868c2 1817static ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1da177e4 1818#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
1819static void AscWriteLramWord(PortAddr, ushort, ushort);
1820static void AscWriteLramByte(PortAddr, ushort, uchar);
1821static ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
1822static void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1823static void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1824static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1825static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
1826static ushort AscInitAscDvcVar(ASC_DVC_VAR *);
1827static ushort AscInitFromEEP(ASC_DVC_VAR *);
27c868c2
MW
1828static ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1829static int AscTestExternalLram(ASC_DVC_VAR *);
1830static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1831static uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1832static void AscSetChipSDTR(PortAddr, uchar, uchar);
1833static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1834static uchar AscAllocFreeQueue(PortAddr, uchar);
1835static uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1836static int AscHostReqRiscHalt(PortAddr);
1837static int AscStopQueueExe(PortAddr);
1838static int AscSendScsiQueue(ASC_DVC_VAR *,
1839 ASC_SCSI_Q *scsiq, uchar n_q_required);
1840static int AscPutReadyQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1841static int AscPutReadySgListQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1842static int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1843static int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1844static ushort AscInitLram(ASC_DVC_VAR *);
1845static ushort AscInitQLinkVar(ASC_DVC_VAR *);
1846static int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1847static int AscIsrChipHalted(ASC_DVC_VAR *);
1848static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1849 ASC_QDONE_INFO *, ASC_DCNT);
1850static int AscIsrQDone(ASC_DVC_VAR *);
1da177e4 1851#ifdef CONFIG_ISA
27c868c2 1852static ushort AscGetEisaChipCfg(PortAddr);
1da177e4 1853#endif /* CONFIG_ISA */
27c868c2 1854static uchar AscGetChipScsiCtrl(PortAddr);
27c868c2 1855static uchar AscGetChipVersion(PortAddr, ushort);
27c868c2 1856static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
27c868c2 1857static void AscToggleIRQAct(PortAddr);
27c868c2
MW
1858static inline ulong DvcEnterCritical(void);
1859static inline void DvcLeaveCritical(ulong);
27c868c2
MW
1860static void DvcSleepMilliSecond(ASC_DCNT);
1861static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
1862static void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1863static void DvcGetQinfo(PortAddr, ushort, uchar *, int);
27c868c2 1864static ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
47d853cc 1865static void AscAsyncFix(ASC_DVC_VAR *, struct scsi_device *);
27c868c2
MW
1866static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
1867static int AscISR(ASC_DVC_VAR *);
1868static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar);
1869static int AscSgListToQueue(int);
1da177e4 1870#ifdef CONFIG_ISA
27c868c2 1871static void AscEnableIsaDma(uchar);
1da177e4 1872#endif /* CONFIG_ISA */
27c868c2 1873static const char *advansys_info(struct Scsi_Host *shost);
1da177e4
LT
1874
1875/*
1876 * --- Adv Library Constants and Macros
1877 */
1878
1879#define ADV_LIB_VERSION_MAJOR 5
1880#define ADV_LIB_VERSION_MINOR 14
1881
1882/*
1883 * Define Adv Library required special types.
1884 */
1885
1886/*
1887 * Portable Data Types
1888 *
1889 * Any instance where a 32-bit long or pointer type is assumed
1890 * for precision or HW defined structures, the following define
1891 * types must be used. In Linux the char, short, and int types
1892 * are all consistent at 8, 16, and 32 bits respectively. Pointers
1893 * and long types are 64 bits on Alpha and UltraSPARC.
1894 */
27c868c2
MW
1895#define ADV_PADDR __u32 /* Physical address data type. */
1896#define ADV_VADDR __u32 /* Virtual address data type. */
1897#define ADV_DCNT __u32 /* Unsigned Data count type. */
1898#define ADV_SDCNT __s32 /* Signed Data count type. */
1da177e4
LT
1899
1900/*
1901 * These macros are used to convert a virtual address to a
1902 * 32-bit value. This currently can be used on Linux Alpha
1903 * which uses 64-bit virtual address but a 32-bit bus address.
1904 * This is likely to break in the future, but doing this now
1905 * will give us time to change the HW and FW to handle 64-bit
1906 * addresses.
1907 */
1908#define ADV_VADDR_TO_U32 virt_to_bus
1909#define ADV_U32_TO_VADDR bus_to_virt
1910
27c868c2 1911#define AdvPortAddr void __iomem * /* Virtual memory address size */
1da177e4
LT
1912
1913/*
1914 * Define Adv Library required memory access macros.
1915 */
1916#define ADV_MEM_READB(addr) readb(addr)
1917#define ADV_MEM_READW(addr) readw(addr)
1918#define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
1919#define ADV_MEM_WRITEW(addr, word) writew(word, addr)
1920#define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
1921
1922#define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
1923
1924/*
1925 * For wide boards a CDB length maximum of 16 bytes
1926 * is supported.
1927 */
1928#define ADV_MAX_CDB_LEN 16
1929
1930/*
1931 * Define total number of simultaneous maximum element scatter-gather
1932 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
1933 * maximum number of outstanding commands per wide host adapter. Each
1934 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
1935 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
1936 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
1937 * structures or 255 scatter-gather elements.
1938 *
1939 */
1940#define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
1941
1942/*
1943 * Define Adv Library required maximum number of scatter-gather
1944 * elements per request.
1945 */
1946#define ADV_MAX_SG_LIST 255
1947
1948/* Number of SG blocks needed. */
1949#define ADV_NUM_SG_BLOCK \
1950 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
1951
1952/* Total contiguous memory needed for SG blocks. */
1953#define ADV_SG_TOTAL_MEM_SIZE \
1954 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
1955
1956#define ADV_PAGE_SIZE PAGE_SIZE
1957
1958#define ADV_NUM_PAGE_CROSSING \
1959 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1960
1da177e4
LT
1961#define ADV_EEP_DVC_CFG_BEGIN (0x00)
1962#define ADV_EEP_DVC_CFG_END (0x15)
27c868c2 1963#define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
1da177e4
LT
1964#define ADV_EEP_MAX_WORD_ADDR (0x1E)
1965
1966#define ADV_EEP_DELAY_MS 100
1967
27c868c2
MW
1968#define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
1969#define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
1da177e4
LT
1970/*
1971 * For the ASC3550 Bit 13 is Termination Polarity control bit.
1972 * For later ICs Bit 13 controls whether the CIS (Card Information
1973 * Service Section) is loaded from EEPROM.
1974 */
27c868c2
MW
1975#define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
1976#define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
1da177e4
LT
1977/*
1978 * ASC38C1600 Bit 11
1979 *
1980 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
1981 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
1982 * Function 0 will specify INT B.
1983 *
1984 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
1985 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
1986 * Function 1 will specify INT A.
1987 */
27c868c2
MW
1988#define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
1989
1990typedef struct adveep_3550_config {
1991 /* Word Offset, Description */
1992
1993 ushort cfg_lsw; /* 00 power up initialization */
1994 /* bit 13 set - Term Polarity Control */
1995 /* bit 14 set - BIOS Enable */
1996 /* bit 15 set - Big Endian Mode */
1997 ushort cfg_msw; /* 01 unused */
1998 ushort disc_enable; /* 02 disconnect enable */
1999 ushort wdtr_able; /* 03 Wide DTR able */
2000 ushort sdtr_able; /* 04 Synchronous DTR able */
2001 ushort start_motor; /* 05 send start up motor */
2002 ushort tagqng_able; /* 06 tag queuing able */
2003 ushort bios_scan; /* 07 BIOS device control */
2004 ushort scam_tolerant; /* 08 no scam */
2005
2006 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2007 uchar bios_boot_delay; /* power up wait */
2008
2009 uchar scsi_reset_delay; /* 10 reset delay */
2010 uchar bios_id_lun; /* first boot device scsi id & lun */
2011 /* high nibble is lun */
2012 /* low nibble is scsi id */
2013
2014 uchar termination; /* 11 0 - automatic */
2015 /* 1 - low off / high off */
2016 /* 2 - low off / high on */
2017 /* 3 - low on / high on */
2018 /* There is no low on / high off */
2019
2020 uchar reserved1; /* reserved byte (not used) */
2021
2022 ushort bios_ctrl; /* 12 BIOS control bits */
2023 /* bit 0 BIOS don't act as initiator. */
2024 /* bit 1 BIOS > 1 GB support */
2025 /* bit 2 BIOS > 2 Disk Support */
2026 /* bit 3 BIOS don't support removables */
2027 /* bit 4 BIOS support bootable CD */
2028 /* bit 5 BIOS scan enabled */
2029 /* bit 6 BIOS support multiple LUNs */
2030 /* bit 7 BIOS display of message */
2031 /* bit 8 SCAM disabled */
2032 /* bit 9 Reset SCSI bus during init. */
2033 /* bit 10 */
2034 /* bit 11 No verbose initialization. */
2035 /* bit 12 SCSI parity enabled */
2036 /* bit 13 */
2037 /* bit 14 */
2038 /* bit 15 */
2039 ushort ultra_able; /* 13 ULTRA speed able */
2040 ushort reserved2; /* 14 reserved */
2041 uchar max_host_qng; /* 15 maximum host queuing */
2042 uchar max_dvc_qng; /* maximum per device queuing */
2043 ushort dvc_cntl; /* 16 control bit for driver */
2044 ushort bug_fix; /* 17 control bit for bug fix */
2045 ushort serial_number_word1; /* 18 Board serial number word 1 */
2046 ushort serial_number_word2; /* 19 Board serial number word 2 */
2047 ushort serial_number_word3; /* 20 Board serial number word 3 */
2048 ushort check_sum; /* 21 EEP check sum */
2049 uchar oem_name[16]; /* 22 OEM name */
2050 ushort dvc_err_code; /* 30 last device driver error code */
2051 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2052 ushort adv_err_addr; /* 32 last uc error address */
2053 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2054 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2055 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2056 ushort num_of_err; /* 36 number of error */
1da177e4
LT
2057} ADVEEP_3550_CONFIG;
2058
27c868c2
MW
2059typedef struct adveep_38C0800_config {
2060 /* Word Offset, Description */
2061
2062 ushort cfg_lsw; /* 00 power up initialization */
2063 /* bit 13 set - Load CIS */
2064 /* bit 14 set - BIOS Enable */
2065 /* bit 15 set - Big Endian Mode */
2066 ushort cfg_msw; /* 01 unused */
2067 ushort disc_enable; /* 02 disconnect enable */
2068 ushort wdtr_able; /* 03 Wide DTR able */
2069 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2070 ushort start_motor; /* 05 send start up motor */
2071 ushort tagqng_able; /* 06 tag queuing able */
2072 ushort bios_scan; /* 07 BIOS device control */
2073 ushort scam_tolerant; /* 08 no scam */
2074
2075 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2076 uchar bios_boot_delay; /* power up wait */
2077
2078 uchar scsi_reset_delay; /* 10 reset delay */
2079 uchar bios_id_lun; /* first boot device scsi id & lun */
2080 /* high nibble is lun */
2081 /* low nibble is scsi id */
2082
2083 uchar termination_se; /* 11 0 - automatic */
2084 /* 1 - low off / high off */
2085 /* 2 - low off / high on */
2086 /* 3 - low on / high on */
2087 /* There is no low on / high off */
2088
2089 uchar termination_lvd; /* 11 0 - automatic */
2090 /* 1 - low off / high off */
2091 /* 2 - low off / high on */
2092 /* 3 - low on / high on */
2093 /* There is no low on / high off */
2094
2095 ushort bios_ctrl; /* 12 BIOS control bits */
2096 /* bit 0 BIOS don't act as initiator. */
2097 /* bit 1 BIOS > 1 GB support */
2098 /* bit 2 BIOS > 2 Disk Support */
2099 /* bit 3 BIOS don't support removables */
2100 /* bit 4 BIOS support bootable CD */
2101 /* bit 5 BIOS scan enabled */
2102 /* bit 6 BIOS support multiple LUNs */
2103 /* bit 7 BIOS display of message */
2104 /* bit 8 SCAM disabled */
2105 /* bit 9 Reset SCSI bus during init. */
2106 /* bit 10 */
2107 /* bit 11 No verbose initialization. */
2108 /* bit 12 SCSI parity enabled */
2109 /* bit 13 */
2110 /* bit 14 */
2111 /* bit 15 */
2112 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2113 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2114 uchar max_host_qng; /* 15 maximum host queueing */
2115 uchar max_dvc_qng; /* maximum per device queuing */
2116 ushort dvc_cntl; /* 16 control bit for driver */
2117 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2118 ushort serial_number_word1; /* 18 Board serial number word 1 */
2119 ushort serial_number_word2; /* 19 Board serial number word 2 */
2120 ushort serial_number_word3; /* 20 Board serial number word 3 */
2121 ushort check_sum; /* 21 EEP check sum */
2122 uchar oem_name[16]; /* 22 OEM name */
2123 ushort dvc_err_code; /* 30 last device driver error code */
2124 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2125 ushort adv_err_addr; /* 32 last uc error address */
2126 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2127 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2128 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2129 ushort reserved36; /* 36 reserved */
2130 ushort reserved37; /* 37 reserved */
2131 ushort reserved38; /* 38 reserved */
2132 ushort reserved39; /* 39 reserved */
2133 ushort reserved40; /* 40 reserved */
2134 ushort reserved41; /* 41 reserved */
2135 ushort reserved42; /* 42 reserved */
2136 ushort reserved43; /* 43 reserved */
2137 ushort reserved44; /* 44 reserved */
2138 ushort reserved45; /* 45 reserved */
2139 ushort reserved46; /* 46 reserved */
2140 ushort reserved47; /* 47 reserved */
2141 ushort reserved48; /* 48 reserved */
2142 ushort reserved49; /* 49 reserved */
2143 ushort reserved50; /* 50 reserved */
2144 ushort reserved51; /* 51 reserved */
2145 ushort reserved52; /* 52 reserved */
2146 ushort reserved53; /* 53 reserved */
2147 ushort reserved54; /* 54 reserved */
2148 ushort reserved55; /* 55 reserved */
2149 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2150 ushort cisprt_msw; /* 57 CIS PTR MSW */
2151 ushort subsysvid; /* 58 SubSystem Vendor ID */
2152 ushort subsysid; /* 59 SubSystem ID */
2153 ushort reserved60; /* 60 reserved */
2154 ushort reserved61; /* 61 reserved */
2155 ushort reserved62; /* 62 reserved */
2156 ushort reserved63; /* 63 reserved */
1da177e4
LT
2157} ADVEEP_38C0800_CONFIG;
2158
27c868c2
MW
2159typedef struct adveep_38C1600_config {
2160 /* Word Offset, Description */
2161
2162 ushort cfg_lsw; /* 00 power up initialization */
2163 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
2164 /* clear - Func. 0 INTA, Func. 1 INTB */
2165 /* bit 13 set - Load CIS */
2166 /* bit 14 set - BIOS Enable */
2167 /* bit 15 set - Big Endian Mode */
2168 ushort cfg_msw; /* 01 unused */
2169 ushort disc_enable; /* 02 disconnect enable */
2170 ushort wdtr_able; /* 03 Wide DTR able */
2171 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2172 ushort start_motor; /* 05 send start up motor */
2173 ushort tagqng_able; /* 06 tag queuing able */
2174 ushort bios_scan; /* 07 BIOS device control */
2175 ushort scam_tolerant; /* 08 no scam */
2176
2177 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2178 uchar bios_boot_delay; /* power up wait */
2179
2180 uchar scsi_reset_delay; /* 10 reset delay */
2181 uchar bios_id_lun; /* first boot device scsi id & lun */
2182 /* high nibble is lun */
2183 /* low nibble is scsi id */
2184
2185 uchar termination_se; /* 11 0 - automatic */
2186 /* 1 - low off / high off */
2187 /* 2 - low off / high on */
2188 /* 3 - low on / high on */
2189 /* There is no low on / high off */
2190
2191 uchar termination_lvd; /* 11 0 - automatic */
2192 /* 1 - low off / high off */
2193 /* 2 - low off / high on */
2194 /* 3 - low on / high on */
2195 /* There is no low on / high off */
2196
2197 ushort bios_ctrl; /* 12 BIOS control bits */
2198 /* bit 0 BIOS don't act as initiator. */
2199 /* bit 1 BIOS > 1 GB support */
2200 /* bit 2 BIOS > 2 Disk Support */
2201 /* bit 3 BIOS don't support removables */
2202 /* bit 4 BIOS support bootable CD */
2203 /* bit 5 BIOS scan enabled */
2204 /* bit 6 BIOS support multiple LUNs */
2205 /* bit 7 BIOS display of message */
2206 /* bit 8 SCAM disabled */
2207 /* bit 9 Reset SCSI bus during init. */
2208 /* bit 10 Basic Integrity Checking disabled */
2209 /* bit 11 No verbose initialization. */
2210 /* bit 12 SCSI parity enabled */
2211 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
2212 /* bit 14 */
2213 /* bit 15 */
2214 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2215 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2216 uchar max_host_qng; /* 15 maximum host queueing */
2217 uchar max_dvc_qng; /* maximum per device queuing */
2218 ushort dvc_cntl; /* 16 control bit for driver */
2219 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2220 ushort serial_number_word1; /* 18 Board serial number word 1 */
2221 ushort serial_number_word2; /* 19 Board serial number word 2 */
2222 ushort serial_number_word3; /* 20 Board serial number word 3 */
2223 ushort check_sum; /* 21 EEP check sum */
2224 uchar oem_name[16]; /* 22 OEM name */
2225 ushort dvc_err_code; /* 30 last device driver error code */
2226 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2227 ushort adv_err_addr; /* 32 last uc error address */
2228 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2229 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2230 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2231 ushort reserved36; /* 36 reserved */
2232 ushort reserved37; /* 37 reserved */
2233 ushort reserved38; /* 38 reserved */
2234 ushort reserved39; /* 39 reserved */
2235 ushort reserved40; /* 40 reserved */
2236 ushort reserved41; /* 41 reserved */
2237 ushort reserved42; /* 42 reserved */
2238 ushort reserved43; /* 43 reserved */
2239 ushort reserved44; /* 44 reserved */
2240 ushort reserved45; /* 45 reserved */
2241 ushort reserved46; /* 46 reserved */
2242 ushort reserved47; /* 47 reserved */
2243 ushort reserved48; /* 48 reserved */
2244 ushort reserved49; /* 49 reserved */
2245 ushort reserved50; /* 50 reserved */
2246 ushort reserved51; /* 51 reserved */
2247 ushort reserved52; /* 52 reserved */
2248 ushort reserved53; /* 53 reserved */
2249 ushort reserved54; /* 54 reserved */
2250 ushort reserved55; /* 55 reserved */
2251 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2252 ushort cisprt_msw; /* 57 CIS PTR MSW */
2253 ushort subsysvid; /* 58 SubSystem Vendor ID */
2254 ushort subsysid; /* 59 SubSystem ID */
2255 ushort reserved60; /* 60 reserved */
2256 ushort reserved61; /* 61 reserved */
2257 ushort reserved62; /* 62 reserved */
2258 ushort reserved63; /* 63 reserved */
1da177e4
LT
2259} ADVEEP_38C1600_CONFIG;
2260
2261/*
2262 * EEPROM Commands
2263 */
2264#define ASC_EEP_CMD_DONE 0x0200
2265#define ASC_EEP_CMD_DONE_ERR 0x0001
2266
2267/* cfg_word */
2268#define EEP_CFG_WORD_BIG_ENDIAN 0x8000
2269
2270/* bios_ctrl */
2271#define BIOS_CTRL_BIOS 0x0001
2272#define BIOS_CTRL_EXTENDED_XLAT 0x0002
2273#define BIOS_CTRL_GT_2_DISK 0x0004
2274#define BIOS_CTRL_BIOS_REMOVABLE 0x0008
2275#define BIOS_CTRL_BOOTABLE_CD 0x0010
2276#define BIOS_CTRL_MULTIPLE_LUN 0x0040
2277#define BIOS_CTRL_DISPLAY_MSG 0x0080
2278#define BIOS_CTRL_NO_SCAM 0x0100
2279#define BIOS_CTRL_RESET_SCSI_BUS 0x0200
2280#define BIOS_CTRL_INIT_VERBOSE 0x0800
2281#define BIOS_CTRL_SCSI_PARITY 0x1000
2282#define BIOS_CTRL_AIPP_DIS 0x2000
2283
27c868c2 2284#define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
1da177e4 2285
27c868c2 2286#define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1da177e4
LT
2287
2288/*
2289 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
2290 * a special 16K Adv Library and Microcode version. After the issue is
2291 * resolved, should restore 32K support.
2292 *
2293 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
2294 */
27c868c2 2295#define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1da177e4
LT
2296
2297/*
2298 * Byte I/O register address from base of 'iop_base'.
2299 */
2300#define IOPB_INTR_STATUS_REG 0x00
2301#define IOPB_CHIP_ID_1 0x01
2302#define IOPB_INTR_ENABLES 0x02
2303#define IOPB_CHIP_TYPE_REV 0x03
2304#define IOPB_RES_ADDR_4 0x04
2305#define IOPB_RES_ADDR_5 0x05
2306#define IOPB_RAM_DATA 0x06
2307#define IOPB_RES_ADDR_7 0x07
2308#define IOPB_FLAG_REG 0x08
2309#define IOPB_RES_ADDR_9 0x09
2310#define IOPB_RISC_CSR 0x0A
2311#define IOPB_RES_ADDR_B 0x0B
2312#define IOPB_RES_ADDR_C 0x0C
2313#define IOPB_RES_ADDR_D 0x0D
2314#define IOPB_SOFT_OVER_WR 0x0E
2315#define IOPB_RES_ADDR_F 0x0F
2316#define IOPB_MEM_CFG 0x10
2317#define IOPB_RES_ADDR_11 0x11
2318#define IOPB_GPIO_DATA 0x12
2319#define IOPB_RES_ADDR_13 0x13
2320#define IOPB_FLASH_PAGE 0x14
2321#define IOPB_RES_ADDR_15 0x15
2322#define IOPB_GPIO_CNTL 0x16
2323#define IOPB_RES_ADDR_17 0x17
2324#define IOPB_FLASH_DATA 0x18
2325#define IOPB_RES_ADDR_19 0x19
2326#define IOPB_RES_ADDR_1A 0x1A
2327#define IOPB_RES_ADDR_1B 0x1B
2328#define IOPB_RES_ADDR_1C 0x1C
2329#define IOPB_RES_ADDR_1D 0x1D
2330#define IOPB_RES_ADDR_1E 0x1E
2331#define IOPB_RES_ADDR_1F 0x1F
2332#define IOPB_DMA_CFG0 0x20
2333#define IOPB_DMA_CFG1 0x21
2334#define IOPB_TICKLE 0x22
2335#define IOPB_DMA_REG_WR 0x23
2336#define IOPB_SDMA_STATUS 0x24
2337#define IOPB_SCSI_BYTE_CNT 0x25
2338#define IOPB_HOST_BYTE_CNT 0x26
2339#define IOPB_BYTE_LEFT_TO_XFER 0x27
2340#define IOPB_BYTE_TO_XFER_0 0x28
2341#define IOPB_BYTE_TO_XFER_1 0x29
2342#define IOPB_BYTE_TO_XFER_2 0x2A
2343#define IOPB_BYTE_TO_XFER_3 0x2B
2344#define IOPB_ACC_GRP 0x2C
2345#define IOPB_RES_ADDR_2D 0x2D
2346#define IOPB_DEV_ID 0x2E
2347#define IOPB_RES_ADDR_2F 0x2F
2348#define IOPB_SCSI_DATA 0x30
2349#define IOPB_RES_ADDR_31 0x31
2350#define IOPB_RES_ADDR_32 0x32
2351#define IOPB_SCSI_DATA_HSHK 0x33
2352#define IOPB_SCSI_CTRL 0x34
2353#define IOPB_RES_ADDR_35 0x35
2354#define IOPB_RES_ADDR_36 0x36
2355#define IOPB_RES_ADDR_37 0x37
2356#define IOPB_RAM_BIST 0x38
2357#define IOPB_PLL_TEST 0x39
2358#define IOPB_PCI_INT_CFG 0x3A
2359#define IOPB_RES_ADDR_3B 0x3B
2360#define IOPB_RFIFO_CNT 0x3C
2361#define IOPB_RES_ADDR_3D 0x3D
2362#define IOPB_RES_ADDR_3E 0x3E
2363#define IOPB_RES_ADDR_3F 0x3F
2364
2365/*
2366 * Word I/O register address from base of 'iop_base'.
2367 */
27c868c2
MW
2368#define IOPW_CHIP_ID_0 0x00 /* CID0 */
2369#define IOPW_CTRL_REG 0x02 /* CC */
2370#define IOPW_RAM_ADDR 0x04 /* LA */
2371#define IOPW_RAM_DATA 0x06 /* LD */
1da177e4 2372#define IOPW_RES_ADDR_08 0x08
27c868c2
MW
2373#define IOPW_RISC_CSR 0x0A /* CSR */
2374#define IOPW_SCSI_CFG0 0x0C /* CFG0 */
2375#define IOPW_SCSI_CFG1 0x0E /* CFG1 */
1da177e4 2376#define IOPW_RES_ADDR_10 0x10
27c868c2 2377#define IOPW_SEL_MASK 0x12 /* SM */
1da177e4 2378#define IOPW_RES_ADDR_14 0x14
27c868c2 2379#define IOPW_FLASH_ADDR 0x16 /* FA */
1da177e4 2380#define IOPW_RES_ADDR_18 0x18
27c868c2
MW
2381#define IOPW_EE_CMD 0x1A /* EC */
2382#define IOPW_EE_DATA 0x1C /* ED */
2383#define IOPW_SFIFO_CNT 0x1E /* SFC */
1da177e4 2384#define IOPW_RES_ADDR_20 0x20
27c868c2
MW
2385#define IOPW_Q_BASE 0x22 /* QB */
2386#define IOPW_QP 0x24 /* QP */
2387#define IOPW_IX 0x26 /* IX */
2388#define IOPW_SP 0x28 /* SP */
2389#define IOPW_PC 0x2A /* PC */
1da177e4
LT
2390#define IOPW_RES_ADDR_2C 0x2C
2391#define IOPW_RES_ADDR_2E 0x2E
27c868c2
MW
2392#define IOPW_SCSI_DATA 0x30 /* SD */
2393#define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
2394#define IOPW_SCSI_CTRL 0x34 /* SC */
2395#define IOPW_HSHK_CFG 0x36 /* HCFG */
2396#define IOPW_SXFR_STATUS 0x36 /* SXS */
2397#define IOPW_SXFR_CNTL 0x38 /* SXL */
2398#define IOPW_SXFR_CNTH 0x3A /* SXH */
1da177e4 2399#define IOPW_RES_ADDR_3C 0x3C
27c868c2 2400#define IOPW_RFIFO_DATA 0x3E /* RFD */
1da177e4
LT
2401
2402/*
2403 * Doubleword I/O register address from base of 'iop_base'.
2404 */
2405#define IOPDW_RES_ADDR_0 0x00
2406#define IOPDW_RAM_DATA 0x04
2407#define IOPDW_RES_ADDR_8 0x08
2408#define IOPDW_RES_ADDR_C 0x0C
2409#define IOPDW_RES_ADDR_10 0x10
2410#define IOPDW_COMMA 0x14
2411#define IOPDW_COMMB 0x18
2412#define IOPDW_RES_ADDR_1C 0x1C
2413#define IOPDW_SDMA_ADDR0 0x20
2414#define IOPDW_SDMA_ADDR1 0x24
2415#define IOPDW_SDMA_COUNT 0x28
2416#define IOPDW_SDMA_ERROR 0x2C
2417#define IOPDW_RDMA_ADDR0 0x30
2418#define IOPDW_RDMA_ADDR1 0x34
2419#define IOPDW_RDMA_COUNT 0x38
2420#define IOPDW_RDMA_ERROR 0x3C
2421
2422#define ADV_CHIP_ID_BYTE 0x25
2423#define ADV_CHIP_ID_WORD 0x04C1
2424
2425#define ADV_SC_SCSI_BUS_RESET 0x2000
2426
2427#define ADV_INTR_ENABLE_HOST_INTR 0x01
2428#define ADV_INTR_ENABLE_SEL_INTR 0x02
2429#define ADV_INTR_ENABLE_DPR_INTR 0x04
2430#define ADV_INTR_ENABLE_RTA_INTR 0x08
2431#define ADV_INTR_ENABLE_RMA_INTR 0x10
2432#define ADV_INTR_ENABLE_RST_INTR 0x20
2433#define ADV_INTR_ENABLE_DPE_INTR 0x40
2434#define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
2435
2436#define ADV_INTR_STATUS_INTRA 0x01
2437#define ADV_INTR_STATUS_INTRB 0x02
2438#define ADV_INTR_STATUS_INTRC 0x04
2439
2440#define ADV_RISC_CSR_STOP (0x0000)
2441#define ADV_RISC_TEST_COND (0x2000)
2442#define ADV_RISC_CSR_RUN (0x4000)
2443#define ADV_RISC_CSR_SINGLE_STEP (0x8000)
2444
2445#define ADV_CTRL_REG_HOST_INTR 0x0100
2446#define ADV_CTRL_REG_SEL_INTR 0x0200
2447#define ADV_CTRL_REG_DPR_INTR 0x0400
2448#define ADV_CTRL_REG_RTA_INTR 0x0800
2449#define ADV_CTRL_REG_RMA_INTR 0x1000
2450#define ADV_CTRL_REG_RES_BIT14 0x2000
2451#define ADV_CTRL_REG_DPE_INTR 0x4000
2452#define ADV_CTRL_REG_POWER_DONE 0x8000
2453#define ADV_CTRL_REG_ANY_INTR 0xFF00
2454
2455#define ADV_CTRL_REG_CMD_RESET 0x00C6
2456#define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
2457#define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
2458#define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
2459#define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
2460
2461#define ADV_TICKLE_NOP 0x00
2462#define ADV_TICKLE_A 0x01
2463#define ADV_TICKLE_B 0x02
2464#define ADV_TICKLE_C 0x03
2465
2466#define ADV_SCSI_CTRL_RSTOUT 0x2000
2467
2468#define AdvIsIntPending(port) \
2469 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2470
2471/*
2472 * SCSI_CFG0 Register bit definitions
2473 */
27c868c2
MW
2474#define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
2475#define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
2476#define EVEN_PARITY 0x1000 /* Select Even Parity */
2477#define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2478#define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
2479#define PRIM_MODE 0x0100 /* Primitive SCSI mode */
2480#define SCAM_EN 0x0080 /* Enable SCAM selection */
2481#define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2482#define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2483#define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
2484#define OUR_ID 0x000F /* SCSI ID */
1da177e4
LT
2485
2486/*
2487 * SCSI_CFG1 Register bit definitions
2488 */
27c868c2
MW
2489#define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
2490#define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2491#define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
2492#define FILTER_SEL 0x0C00 /* Filter Period Selection */
2493#define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
2494#define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
2495#define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
2496#define ACTIVE_DBL 0x0200 /* Disable Active Negation */
2497#define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
2498#define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
2499#define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
2500#define TERM_CTL 0x0030 /* External SCSI Termination Bits */
2501#define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
2502#define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
2503#define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
1da177e4
LT
2504
2505/*
2506 * Addendum for ASC-38C0800 Chip
2507 *
2508 * The ASC-38C1600 Chip uses the same definitions except that the
2509 * bus mode override bits [12:10] have been moved to byte register
2510 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
2511 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
2512 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
2513 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
2514 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
2515 */
27c868c2
MW
2516#define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
2517#define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
2518#define HVD 0x1000 /* HVD Device Detect */
2519#define LVD 0x0800 /* LVD Device Detect */
2520#define SE 0x0400 /* SE Device Detect */
2521#define TERM_LVD 0x00C0 /* LVD Termination Bits */
2522#define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
2523#define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
2524#define TERM_SE 0x0030 /* SE Termination Bits */
2525#define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
2526#define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
2527#define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
2528#define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
2529#define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
2530#define C_DET_SE 0x0003 /* SE Cable Detect Bits */
2531#define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
2532#define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
1da177e4
LT
2533
2534#define CABLE_ILLEGAL_A 0x7
2535 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
2536
2537#define CABLE_ILLEGAL_B 0xB
2538 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
2539
2540/*
2541 * MEM_CFG Register bit definitions
2542 */
27c868c2
MW
2543#define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
2544#define FAST_EE_CLK 0x20 /* Diagnostic Bit */
2545#define RAM_SZ 0x1C /* Specify size of RAM to RISC */
2546#define RAM_SZ_2KB 0x00 /* 2 KB */
2547#define RAM_SZ_4KB 0x04 /* 4 KB */
2548#define RAM_SZ_8KB 0x08 /* 8 KB */
2549#define RAM_SZ_16KB 0x0C /* 16 KB */
2550#define RAM_SZ_32KB 0x10 /* 32 KB */
2551#define RAM_SZ_64KB 0x14 /* 64 KB */
1da177e4
LT
2552
2553/*
2554 * DMA_CFG0 Register bit definitions
2555 *
2556 * This register is only accessible to the host.
2557 */
27c868c2
MW
2558#define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
2559#define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
2560#define FIFO_THRESH_16B 0x00 /* 16 bytes */
2561#define FIFO_THRESH_32B 0x20 /* 32 bytes */
2562#define FIFO_THRESH_48B 0x30 /* 48 bytes */
2563#define FIFO_THRESH_64B 0x40 /* 64 bytes */
2564#define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
2565#define FIFO_THRESH_96B 0x60 /* 96 bytes */
2566#define FIFO_THRESH_112B 0x70 /* 112 bytes */
2567#define START_CTL 0x0C /* DMA start conditions */
2568#define START_CTL_TH 0x00 /* Wait threshold level (default) */
2569#define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
2570#define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
2571#define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
2572#define READ_CMD 0x03 /* Memory Read Method */
2573#define READ_CMD_MR 0x00 /* Memory Read */
2574#define READ_CMD_MRL 0x02 /* Memory Read Long */
2575#define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
1da177e4
LT
2576
2577/*
2578 * ASC-38C0800 RAM BIST Register bit definitions
2579 */
2580#define RAM_TEST_MODE 0x80
2581#define PRE_TEST_MODE 0x40
2582#define NORMAL_MODE 0x00
2583#define RAM_TEST_DONE 0x10
2584#define RAM_TEST_STATUS 0x0F
2585#define RAM_TEST_HOST_ERROR 0x08
2586#define RAM_TEST_INTRAM_ERROR 0x04
2587#define RAM_TEST_RISC_ERROR 0x02
2588#define RAM_TEST_SCSI_ERROR 0x01
2589#define RAM_TEST_SUCCESS 0x00
2590#define PRE_TEST_VALUE 0x05
2591#define NORMAL_VALUE 0x00
2592
2593/*
2594 * ASC38C1600 Definitions
2595 *
2596 * IOPB_PCI_INT_CFG Bit Field Definitions
2597 */
2598
27c868c2 2599#define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
1da177e4
LT
2600
2601/*
2602 * Bit 1 can be set to change the interrupt for the Function to operate in
2603 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
2604 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
2605 * mode, otherwise the operating mode is undefined.
2606 */
2607#define TOTEMPOLE 0x02
2608
2609/*
2610 * Bit 0 can be used to change the Int Pin for the Function. The value is
2611 * 0 by default for both Functions with Function 0 using INT A and Function
2612 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
2613 * INT A is used.
2614 *
2615 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
2616 * value specified in the PCI Configuration Space.
2617 */
2618#define INTAB 0x01
2619
2620/* a_advlib.h */
2621
2622/*
2623 * Adv Library Status Definitions
2624 */
2625#define ADV_TRUE 1
2626#define ADV_FALSE 0
2627#define ADV_NOERROR 1
2628#define ADV_SUCCESS 1
2629#define ADV_BUSY 0
2630#define ADV_ERROR (-1)
2631
1da177e4
LT
2632/*
2633 * ADV_DVC_VAR 'warn_code' values
2634 */
27c868c2
MW
2635#define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
2636#define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
2637#define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
2638#define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */
2639#define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
1da177e4 2640
27c868c2
MW
2641#define ADV_MAX_TID 15 /* max. target identifier */
2642#define ADV_MAX_LUN 7 /* max. logical unit number */
1da177e4
LT
2643
2644/*
2645 * Error code values are set in ADV_DVC_VAR 'err_code'.
2646 */
27c868c2
MW
2647#define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */
2648#define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
2649#define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */
2650#define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
2651#define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */
2652#define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
2653#define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */
2654#define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
2655#define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
2656#define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */
2657#define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */
2658#define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */
2659#define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */
2660#define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */
1da177e4
LT
2661
2662/*
2663 * Fixed locations of microcode operating variables.
2664 */
27c868c2
MW
2665#define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
2666#define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
2667#define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
2668#define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
2669#define ASC_MC_VERSION_NUM 0x003A /* microcode number */
2670#define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
2671#define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
2672#define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
2673#define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
2674#define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
2675#define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
2676#define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
2677#define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
1da177e4
LT
2678#define ASC_MC_CHIP_TYPE 0x009A
2679#define ASC_MC_INTRB_CODE 0x009B
2680#define ASC_MC_WDTR_ABLE 0x009C
2681#define ASC_MC_SDTR_ABLE 0x009E
2682#define ASC_MC_TAGQNG_ABLE 0x00A0
2683#define ASC_MC_DISC_ENABLE 0x00A2
2684#define ASC_MC_IDLE_CMD_STATUS 0x00A4
2685#define ASC_MC_IDLE_CMD 0x00A6
2686#define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
2687#define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
2688#define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
2689#define ASC_MC_DEFAULT_MEM_CFG 0x00B0
2690#define ASC_MC_DEFAULT_SEL_MASK 0x00B2
2691#define ASC_MC_SDTR_DONE 0x00B6
2692#define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
2693#define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
2694#define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
27c868c2 2695#define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
1da177e4 2696#define ASC_MC_WDTR_DONE 0x0124
27c868c2 2697#define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
1da177e4
LT
2698#define ASC_MC_ICQ 0x0160
2699#define ASC_MC_IRQ 0x0164
2700#define ASC_MC_PPR_ABLE 0x017A
2701
2702/*
2703 * BIOS LRAM variable absolute offsets.
2704 */
2705#define BIOS_CODESEG 0x54
2706#define BIOS_CODELEN 0x56
2707#define BIOS_SIGNATURE 0x58
2708#define BIOS_VERSION 0x5A
2709
2710/*
2711 * Microcode Control Flags
2712 *
2713 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2714 * and handled by the microcode.
2715 */
27c868c2
MW
2716#define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
2717#define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
1da177e4
LT
2718
2719/*
2720 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2721 */
2722#define HSHK_CFG_WIDE_XFR 0x8000
2723#define HSHK_CFG_RATE 0x0F00
2724#define HSHK_CFG_OFFSET 0x001F
2725
27c868c2
MW
2726#define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
2727#define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
2728#define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
2729#define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
2730
2731#define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2732#define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
2733#define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2734#define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
2735#define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2736
2737#define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
2738#define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
2739#define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
2740#define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
2741#define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
1da177e4
LT
2742/*
2743 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
2744 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
2745 */
27c868c2
MW
2746#define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
2747#define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
1da177e4
LT
2748
2749/*
2750 * All fields here are accessed by the board microcode and need to be
2751 * little-endian.
2752 */
27c868c2
MW
2753typedef struct adv_carr_t {
2754 ADV_VADDR carr_va; /* Carrier Virtual Address */
2755 ADV_PADDR carr_pa; /* Carrier Physical Address */
2756 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
2757 /*
2758 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
2759 *
2760 * next_vpa [3:1] Reserved Bits
2761 * next_vpa [0] Done Flag set in Response Queue.
2762 */
2763 ADV_VADDR next_vpa;
1da177e4
LT
2764} ADV_CARR_T;
2765
2766/*
2767 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2768 */
2769#define ASC_NEXT_VPA_MASK 0xFFFFFFF0
2770
2771#define ASC_RQ_DONE 0x00000001
2772#define ASC_RQ_GOOD 0x00000002
2773#define ASC_CQ_STOPPER 0x00000000
2774
2775#define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2776
2777#define ADV_CARRIER_NUM_PAGE_CROSSING \
2778 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2779 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2780
2781#define ADV_CARRIER_BUFSIZE \
2782 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2783
2784/*
2785 * ASC_SCSI_REQ_Q 'a_flag' definitions
2786 *
2787 * The Adv Library should limit use to the lower nibble (4 bits) of
2788 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2789 */
27c868c2
MW
2790#define ADV_POLL_REQUEST 0x01 /* poll for request completion */
2791#define ADV_SCSIQ_DONE 0x02 /* request done */
2792#define ADV_DONT_RETRY 0x08 /* don't do retry */
1da177e4 2793
27c868c2
MW
2794#define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
2795#define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
2796#define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
1da177e4
LT
2797
2798/*
2799 * Adapter temporary configuration structure
2800 *
2801 * This structure can be discarded after initialization. Don't add
2802 * fields here needed after initialization.
2803 *
2804 * Field naming convention:
2805 *
2806 * *_enable indicates the field enables or disables a feature. The
2807 * value of the field is never reset.
2808 */
2809typedef struct adv_dvc_cfg {
27c868c2
MW
2810 ushort disc_enable; /* enable disconnection */
2811 uchar chip_version; /* chip version */
2812 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2813 ushort lib_version; /* Adv Library version number */
2814 ushort control_flag; /* Microcode Control Flag */
2815 ushort mcode_date; /* Microcode date */
2816 ushort mcode_version; /* Microcode version */
2817 ushort pci_slot_info; /* high byte device/function number */
2818 /* bits 7-3 device num., bits 2-0 function num. */
2819 /* low byte bus num. */
2820 ushort serial1; /* EEPROM serial number word 1 */
2821 ushort serial2; /* EEPROM serial number word 2 */
2822 ushort serial3; /* EEPROM serial number word 3 */
1da177e4
LT
2823} ADV_DVC_CFG;
2824
2825struct adv_dvc_var;
2826struct adv_scsi_req_q;
2827
1da177e4
LT
2828/*
2829 * Adapter operation variable structure.
2830 *
2831 * One structure is required per host adapter.
2832 *
2833 * Field naming convention:
2834 *
2835 * *_able indicates both whether a feature should be enabled or disabled
2836 * and whether a device isi capable of the feature. At initialization
2837 * this field may be set, but later if a device is found to be incapable
2838 * of the feature, the field is cleared.
2839 */
2840typedef struct adv_dvc_var {
27c868c2
MW
2841 AdvPortAddr iop_base; /* I/O port address */
2842 ushort err_code; /* fatal error code */
2843 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
27c868c2
MW
2844 ushort wdtr_able; /* try WDTR for a device */
2845 ushort sdtr_able; /* try SDTR for a device */
2846 ushort ultra_able; /* try SDTR Ultra speed for a device */
2847 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
2848 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
2849 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
2850 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
2851 ushort tagqng_able; /* try tagged queuing with a device */
2852 ushort ppr_able; /* PPR message capable per TID bitmask. */
2853 uchar max_dvc_qng; /* maximum number of tagged commands per device */
2854 ushort start_motor; /* start motor command allowed */
2855 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
2856 uchar chip_no; /* should be assigned by caller */
2857 uchar max_host_qng; /* maximum number of Q'ed command allowed */
2858 uchar irq_no; /* IRQ number */
2859 ushort no_scam; /* scam_tolerant of EEPROM */
2860 struct asc_board *drv_ptr; /* driver pointer to private structure */
2861 uchar chip_scsi_id; /* chip SCSI target ID */
2862 uchar chip_type;
2863 uchar bist_err_code;
2864 ADV_CARR_T *carrier_buf;
2865 ADV_CARR_T *carr_freelist; /* Carrier free list. */
2866 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
2867 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
2868 ushort carr_pending_cnt; /* Count of pending carriers. */
2869 /*
2870 * Note: The following fields will not be used after initialization. The
2871 * driver may discard the buffer after initialization is done.
2872 */
2873 ADV_DVC_CFG *cfg; /* temporary configuration structure */
1da177e4
LT
2874} ADV_DVC_VAR;
2875
2876#define NO_OF_SG_PER_BLOCK 15
2877
2878typedef struct asc_sg_block {
27c868c2
MW
2879 uchar reserved1;
2880 uchar reserved2;
2881 uchar reserved3;
2882 uchar sg_cnt; /* Valid entries in block. */
2883 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
2884 struct {
2885 ADV_PADDR sg_addr; /* SG element address. */
2886 ADV_DCNT sg_count; /* SG element count. */
2887 } sg_list[NO_OF_SG_PER_BLOCK];
1da177e4
LT
2888} ADV_SG_BLOCK;
2889
2890/*
2891 * ADV_SCSI_REQ_Q - microcode request structure
2892 *
2893 * All fields in this structure up to byte 60 are used by the microcode.
2894 * The microcode makes assumptions about the size and ordering of fields
2895 * in this structure. Do not change the structure definition here without
2896 * coordinating the change with the microcode.
2897 *
2898 * All fields accessed by microcode must be maintained in little_endian
2899 * order.
2900 */
2901typedef struct adv_scsi_req_q {
27c868c2
MW
2902 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
2903 uchar target_cmd;
2904 uchar target_id; /* Device target identifier. */
2905 uchar target_lun; /* Device target logical unit number. */
2906 ADV_PADDR data_addr; /* Data buffer physical address. */
2907 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
2908 ADV_PADDR sense_addr;
2909 ADV_PADDR carr_pa;
2910 uchar mflag;
2911 uchar sense_len;
2912 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
2913 uchar scsi_cntl;
2914 uchar done_status; /* Completion status. */
2915 uchar scsi_status; /* SCSI status byte. */
2916 uchar host_status; /* Ucode host status. */
2917 uchar sg_working_ix;
2918 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
2919 ADV_PADDR sg_real_addr; /* SG list physical address. */
2920 ADV_PADDR scsiq_rptr;
2921 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
2922 ADV_VADDR scsiq_ptr;
2923 ADV_VADDR carr_va;
2924 /*
2925 * End of microcode structure - 60 bytes. The rest of the structure
2926 * is used by the Adv Library and ignored by the microcode.
2927 */
2928 ADV_VADDR srb_ptr;
2929 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
2930 char *vdata_addr; /* Data buffer virtual address. */
2931 uchar a_flag;
2932 uchar pad[2]; /* Pad out to a word boundary. */
1da177e4
LT
2933} ADV_SCSI_REQ_Q;
2934
2935/*
2936 * Microcode idle loop commands
2937 */
2938#define IDLE_CMD_COMPLETED 0
2939#define IDLE_CMD_STOP_CHIP 0x0001
2940#define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
2941#define IDLE_CMD_SEND_INT 0x0004
2942#define IDLE_CMD_ABORT 0x0008
2943#define IDLE_CMD_DEVICE_RESET 0x0010
27c868c2
MW
2944#define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
2945#define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
1da177e4
LT
2946#define IDLE_CMD_SCSIREQ 0x0080
2947
2948#define IDLE_CMD_STATUS_SUCCESS 0x0001
2949#define IDLE_CMD_STATUS_FAILURE 0x0002
2950
2951/*
2952 * AdvSendIdleCmd() flag definitions.
2953 */
2954#define ADV_NOWAIT 0x01
2955
2956/*
2957 * Wait loop time out values.
2958 */
27c868c2
MW
2959#define SCSI_WAIT_10_SEC 10UL /* 10 seconds */
2960#define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
2961#define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
2962#define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */
2963#define SCSI_MAX_RETRY 10 /* retry count */
1da177e4 2964
27c868c2
MW
2965#define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
2966#define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
2967#define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
2968#define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
1da177e4 2969
27c868c2 2970#define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
1da177e4
LT
2971
2972/*
2973 * Device drivers must define the following functions.
2974 */
27c868c2
MW
2975static inline ulong DvcEnterCritical(void);
2976static inline void DvcLeaveCritical(ulong);
2977static void DvcSleepMilliSecond(ADV_DCNT);
27c868c2
MW
2978static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
2979 uchar *, ASC_SDCNT *, int);
2980static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
1da177e4
LT
2981
2982/*
2983 * Adv Library functions available to drivers.
2984 */
27c868c2
MW
2985static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
2986static int AdvISR(ADV_DVC_VAR *);
27c868c2
MW
2987static int AdvInitAsc3550Driver(ADV_DVC_VAR *);
2988static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
2989static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
2990static int AdvResetChipAndSB(ADV_DVC_VAR *);
2991static int AdvResetSB(ADV_DVC_VAR *asc_dvc);
1da177e4
LT
2992
2993/*
2994 * Internal Adv Library functions.
2995 */
27c868c2 2996static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
27c868c2
MW
2997static int AdvInitFrom3550EEP(ADV_DVC_VAR *);
2998static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
2999static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
3000static ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3001static void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3002static ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3003static void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3004static ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3005static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3006static void AdvWaitEEPCmd(AdvPortAddr);
3007static ushort AdvReadEEPWord(AdvPortAddr, int);
1da177e4 3008
1da177e4
LT
3009/* Read byte from a register. */
3010#define AdvReadByteRegister(iop_base, reg_off) \
3011 (ADV_MEM_READB((iop_base) + (reg_off)))
3012
3013/* Write byte to a register. */
3014#define AdvWriteByteRegister(iop_base, reg_off, byte) \
3015 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3016
3017/* Read word (2 bytes) from a register. */
3018#define AdvReadWordRegister(iop_base, reg_off) \
3019 (ADV_MEM_READW((iop_base) + (reg_off)))
3020
3021/* Write word (2 bytes) to a register. */
3022#define AdvWriteWordRegister(iop_base, reg_off, word) \
3023 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
3024
3025/* Write dword (4 bytes) to a register. */
3026#define AdvWriteDWordRegister(iop_base, reg_off, dword) \
3027 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
3028
3029/* Read byte from LRAM. */
3030#define AdvReadByteLram(iop_base, addr, byte) \
3031do { \
3032 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3033 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3034} while (0)
3035
3036/* Write byte to LRAM. */
3037#define AdvWriteByteLram(iop_base, addr, byte) \
3038 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3039 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3040
3041/* Read word (2 bytes) from LRAM. */
3042#define AdvReadWordLram(iop_base, addr, word) \
3043do { \
3044 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3045 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3046} while (0)
3047
3048/* Write word (2 bytes) to LRAM. */
3049#define AdvWriteWordLram(iop_base, addr, word) \
3050 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3051 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3052
3053/* Write little-endian double word (4 bytes) to LRAM */
3054/* Because of unspecified C language ordering don't use auto-increment. */
3055#define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
3056 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3057 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3058 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3059 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3060 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3061 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3062
3063/* Read word (2 bytes) from LRAM assuming that the address is already set. */
3064#define AdvReadWordAutoIncLram(iop_base) \
3065 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3066
3067/* Write word (2 bytes) to LRAM assuming that the address is already set. */
3068#define AdvWriteWordAutoIncLram(iop_base, word) \
3069 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3070
1da177e4
LT
3071/*
3072 * Define macro to check for Condor signature.
3073 *
3074 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3075 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3076 */
3077#define AdvFindSignature(iop_base) \
3078 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3079 ADV_CHIP_ID_BYTE) && \
3080 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3081 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
3082
3083/*
3084 * Define macro to Return the version number of the chip at 'iop_base'.
3085 *
3086 * The second parameter 'bus_type' is currently unused.
3087 */
3088#define AdvGetChipVersion(iop_base, bus_type) \
3089 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3090
3091/*
3092 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3093 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3094 *
3095 * If the request has not yet been sent to the device it will simply be
3096 * aborted from RISC memory. If the request is disconnected it will be
3097 * aborted on reselection by sending an Abort Message to the target ID.
3098 *
3099 * Return value:
3100 * ADV_TRUE(1) - Queue was successfully aborted.
3101 * ADV_FALSE(0) - Queue was not found on the active queue list.
3102 */
3103#define AdvAbortQueue(asc_dvc, scsiq) \
3104 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3105 (ADV_DCNT) (scsiq))
3106
3107/*
3108 * Send a Bus Device Reset Message to the specified target ID.
3109 *
3110 * All outstanding commands will be purged if sending the
3111 * Bus Device Reset Message is successful.
3112 *
3113 * Return Value:
3114 * ADV_TRUE(1) - All requests on the target are purged.
3115 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3116 * are not purged.
3117 */
3118#define AdvResetDevice(asc_dvc, target_id) \
3119 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3120 (ADV_DCNT) (target_id))
3121
3122/*
3123 * SCSI Wide Type definition.
3124 */
3125#define ADV_SCSI_BIT_ID_TYPE ushort
3126
3127/*
3128 * AdvInitScsiTarget() 'cntl_flag' options.
3129 */
3130#define ADV_SCAN_LUN 0x01
3131#define ADV_CAPINFO_NOLUN 0x02
3132
3133/*
3134 * Convert target id to target id bit mask.
3135 */
3136#define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
3137
3138/*
3139 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3140 */
3141
27c868c2 3142#define QD_NO_STATUS 0x00 /* Request not completed yet. */
1da177e4
LT
3143#define QD_NO_ERROR 0x01
3144#define QD_ABORTED_BY_HOST 0x02
3145#define QD_WITH_ERROR 0x04
3146
3147#define QHSTA_NO_ERROR 0x00
3148#define QHSTA_M_SEL_TIMEOUT 0x11
3149#define QHSTA_M_DATA_OVER_RUN 0x12
3150#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3151#define QHSTA_M_QUEUE_ABORTED 0x15
27c868c2
MW
3152#define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
3153#define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
3154#define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
3155#define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
3156#define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
3157#define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
3158#define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
1da177e4 3159/* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
27c868c2
MW
3160#define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
3161#define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
3162#define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
3163#define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
3164#define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
3165#define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
3166#define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
3167#define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
1da177e4
LT
3168#define QHSTA_M_WTM_TIMEOUT 0x41
3169#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
3170#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
3171#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
27c868c2
MW
3172#define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
3173#define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
3174#define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
1da177e4
LT
3175
3176/*
3177 * Default EEPROM Configuration structure defined in a_init.c.
3178 */
3179static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
3180static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
3181static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
3182
3183/*
3184 * DvcGetPhyAddr() flag arguments
3185 */
27c868c2
MW
3186#define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
3187#define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
3188#define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
3189#define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
3190#define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
3191#define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
1da177e4
LT
3192
3193/* Return the address that is aligned at the next doubleword >= to 'addr'. */
3194#define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
3195#define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
3196#define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
3197
3198/*
3199 * Total contiguous memory needed for driver SG blocks.
3200 *
3201 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3202 * number of scatter-gather elements the driver supports in a
3203 * single request.
3204 */
3205
3206#define ADV_SG_LIST_MAX_BYTE_SIZE \
3207 (sizeof(ADV_SG_BLOCK) * \
3208 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3209
1da177e4
LT
3210/*
3211 * --- Driver Constants and Macros
3212 */
3213
1da177e4
LT
3214/* Reference Scsi_Host hostdata */
3215#define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3216
3217/* asc_board_t flags */
3218#define ASC_HOST_IN_RESET 0x01
27c868c2 3219#define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
1da177e4
LT
3220#define ASC_SELECT_QUEUE_DEPTHS 0x08
3221
3222#define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3223#define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD)
3224
27c868c2 3225#define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
1da177e4 3226
27c868c2 3227#define ASC_INFO_SIZE 128 /* advansys_info() line size */
1da177e4
LT
3228
3229#ifdef CONFIG_PROC_FS
3230/* /proc/scsi/advansys/[0...] related definitions */
3231#define ASC_PRTBUF_SIZE 2048
3232#define ASC_PRTLINE_SIZE 160
3233
3234#define ASC_PRT_NEXT() \
3235 if (cp) { \
3236 totlen += len; \
3237 leftlen -= len; \
3238 if (leftlen == 0) { \
3239 return totlen; \
3240 } \
3241 cp += len; \
3242 }
3243#endif /* CONFIG_PROC_FS */
3244
3245/* Asc Library return codes */
3246#define ASC_TRUE 1
3247#define ASC_FALSE 0
3248#define ASC_NOERROR 1
3249#define ASC_BUSY 0
3250#define ASC_ERROR (-1)
3251
3252/* struct scsi_cmnd function return codes */
3253#define STATUS_BYTE(byte) (byte)
3254#define MSG_BYTE(byte) ((byte) << 8)
3255#define HOST_BYTE(byte) ((byte) << 16)
3256#define DRIVER_BYTE(byte) ((byte) << 24)
3257
3258/*
3259 * The following definitions and macros are OS independent interfaces to
3260 * the queue functions:
3261 * REQ - SCSI request structure
3262 * REQP - pointer to SCSI request structure
3263 * REQPTID(reqp) - reqp's target id
3264 * REQPNEXT(reqp) - reqp's next pointer
3265 * REQPNEXTP(reqp) - pointer to reqp's next pointer
3266 * REQPTIME(reqp) - reqp's time stamp value
3267 * REQTIMESTAMP() - system time stamp value
3268 */
27c868c2 3269typedef struct scsi_cmnd REQ, *REQP;
1da177e4
LT
3270#define REQPNEXT(reqp) ((REQP) ((reqp)->host_scribble))
3271#define REQPNEXTP(reqp) ((REQP *) &((reqp)->host_scribble))
3272#define REQPTID(reqp) ((reqp)->device->id)
3273#define REQPTIME(reqp) ((reqp)->SCp.this_residual)
3274#define REQTIMESTAMP() (jiffies)
3275
3276#define REQTIMESTAT(function, ascq, reqp, tid) \
3277{ \
3278 /*
3279 * If the request time stamp is less than the system time stamp, then \
3280 * maybe the system time stamp wrapped. Set the request time to zero.\
3281 */ \
3282 if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3283 REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3284 } else { \
3285 /* Indicate an error occurred with the assertion. */ \
3286 ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3287 REQPTIME(reqp) = 0; \
3288 } \
3289 /* Handle first minimum time case without external initialization. */ \
3290 if (((ascq)->q_tot_cnt[tid] == 1) || \
3291 (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3292 (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3293 ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3294 (function), (tid), (ascq)->q_min_tim[tid]); \
3295 } \
3296 if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3297 (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3298 ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3299 (function), tid, (ascq)->q_max_tim[tid]); \
3300 } \
3301 (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3302 /* Reset the time stamp field. */ \
3303 REQPTIME(reqp) = 0; \
3304}
3305
3306/* asc_enqueue() flags */
3307#define ASC_FRONT 1
3308#define ASC_BACK 2
3309
3310/* asc_dequeue_list() argument */
3311#define ASC_TID_ALL (-1)
3312
3313/* Return non-zero, if the queue is empty. */
3314#define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0)
3315
1da177e4 3316#ifndef ADVANSYS_STATS
27c868c2
MW
3317#define ASC_STATS(shost, counter)
3318#define ASC_STATS_ADD(shost, counter, count)
1da177e4 3319#else /* ADVANSYS_STATS */
27c868c2
MW
3320#define ASC_STATS(shost, counter) \
3321 (ASC_BOARDP(shost)->asc_stats.counter++)
1da177e4 3322
27c868c2
MW
3323#define ASC_STATS_ADD(shost, counter, count) \
3324 (ASC_BOARDP(shost)->asc_stats.counter += (count))
1da177e4
LT
3325#endif /* ADVANSYS_STATS */
3326
3327#define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3328
3329/* If the result wraps when calculating tenths, return 0. */
3330#define ASC_TENTHS(num, den) \
3331 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3332 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3333
3334/*
3335 * Display a message to the console.
3336 */
3337#define ASC_PRINT(s) \
3338 { \
3339 printk("advansys: "); \
3340 printk(s); \
3341 }
3342
3343#define ASC_PRINT1(s, a1) \
3344 { \
3345 printk("advansys: "); \
3346 printk((s), (a1)); \
3347 }
3348
3349#define ASC_PRINT2(s, a1, a2) \
3350 { \
3351 printk("advansys: "); \
3352 printk((s), (a1), (a2)); \
3353 }
3354
3355#define ASC_PRINT3(s, a1, a2, a3) \
3356 { \
3357 printk("advansys: "); \
3358 printk((s), (a1), (a2), (a3)); \
3359 }
3360
3361#define ASC_PRINT4(s, a1, a2, a3, a4) \
3362 { \
3363 printk("advansys: "); \
3364 printk((s), (a1), (a2), (a3), (a4)); \
3365 }
3366
1da177e4
LT
3367#ifndef ADVANSYS_DEBUG
3368
3369#define ASC_DBG(lvl, s)
3370#define ASC_DBG1(lvl, s, a1)
3371#define ASC_DBG2(lvl, s, a1, a2)
3372#define ASC_DBG3(lvl, s, a1, a2, a3)
3373#define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3374#define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3375#define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3376#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3377#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3378#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3379#define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3380#define ASC_DBG_PRT_HEX(lvl, name, start, length)
3381#define ASC_DBG_PRT_CDB(lvl, cdb, len)
3382#define ASC_DBG_PRT_SENSE(lvl, sense, len)
3383#define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3384
3385#else /* ADVANSYS_DEBUG */
3386
3387/*
3388 * Debugging Message Levels:
3389 * 0: Errors Only
3390 * 1: High-Level Tracing
3391 * 2-N: Verbose Tracing
3392 */
3393
3394#define ASC_DBG(lvl, s) \
3395 { \
3396 if (asc_dbglvl >= (lvl)) { \
3397 printk(s); \
3398 } \
3399 }
3400
3401#define ASC_DBG1(lvl, s, a1) \
3402 { \
3403 if (asc_dbglvl >= (lvl)) { \
3404 printk((s), (a1)); \
3405 } \
3406 }
3407
3408#define ASC_DBG2(lvl, s, a1, a2) \
3409 { \
3410 if (asc_dbglvl >= (lvl)) { \
3411 printk((s), (a1), (a2)); \
3412 } \
3413 }
3414
3415#define ASC_DBG3(lvl, s, a1, a2, a3) \
3416 { \
3417 if (asc_dbglvl >= (lvl)) { \
3418 printk((s), (a1), (a2), (a3)); \
3419 } \
3420 }
3421
3422#define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3423 { \
3424 if (asc_dbglvl >= (lvl)) { \
3425 printk((s), (a1), (a2), (a3), (a4)); \
3426 } \
3427 }
3428
3429#define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3430 { \
3431 if (asc_dbglvl >= (lvl)) { \
3432 asc_prt_scsi_host(s); \
3433 } \
3434 }
3435
3436#define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3437 { \
3438 if (asc_dbglvl >= (lvl)) { \
3439 asc_prt_scsi_cmnd(s); \
3440 } \
3441 }
3442
3443#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3444 { \
3445 if (asc_dbglvl >= (lvl)) { \
3446 asc_prt_asc_scsi_q(scsiqp); \
3447 } \
3448 }
3449
3450#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3451 { \
3452 if (asc_dbglvl >= (lvl)) { \
3453 asc_prt_asc_qdone_info(qdone); \
3454 } \
3455 }
3456
3457#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3458 { \
3459 if (asc_dbglvl >= (lvl)) { \
3460 asc_prt_adv_scsi_req_q(scsiqp); \
3461 } \
3462 }
3463
3464#define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3465 { \
3466 if (asc_dbglvl >= (lvl)) { \
3467 asc_prt_hex((name), (start), (length)); \
3468 } \
3469 }
3470
3471#define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3472 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3473
3474#define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3475 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3476
3477#define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3478 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3479#endif /* ADVANSYS_DEBUG */
3480
3481#ifndef ADVANSYS_ASSERT
3482#define ASC_ASSERT(a)
3483#else /* ADVANSYS_ASSERT */
3484
3485#define ASC_ASSERT(a) \
3486 { \
3487 if (!(a)) { \
3488 printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3489 __FILE__, __LINE__); \
3490 } \
3491 }
3492
3493#endif /* ADVANSYS_ASSERT */
3494
1da177e4
LT
3495/*
3496 * --- Driver Structures
3497 */
3498
3499#ifdef ADVANSYS_STATS
3500
3501/* Per board statistics structure */
3502struct asc_stats {
27c868c2
MW
3503 /* Driver Entrypoint Statistics */
3504 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
3505 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
3506 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
3507 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
3508 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
3509 ADV_DCNT done; /* # calls to request's scsi_done function */
3510 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
3511 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
3512 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
3513 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3514 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
3515 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
3516 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
3517 ADV_DCNT exe_unknown; /* # unknown returns. */
3518 /* Data Transfer Statistics */
3519 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
3520 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
3521 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
3522 ADV_DCNT sg_elem; /* # scatter-gather elements */
3523 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
1da177e4
LT
3524};
3525#endif /* ADVANSYS_STATS */
3526
3527/*
3528 * Request queuing structure
3529 */
3530typedef struct asc_queue {
27c868c2
MW
3531 ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */
3532 REQP q_first[ADV_MAX_TID + 1]; /* first queued request */
3533 REQP q_last[ADV_MAX_TID + 1]; /* last queued request */
1da177e4 3534#ifdef ADVANSYS_STATS
27c868c2
MW
3535 short q_cur_cnt[ADV_MAX_TID + 1]; /* current queue count */
3536 short q_max_cnt[ADV_MAX_TID + 1]; /* maximum queue count */
3537 ADV_DCNT q_tot_cnt[ADV_MAX_TID + 1]; /* total enqueue count */
3538 ADV_DCNT q_tot_tim[ADV_MAX_TID + 1]; /* total time queued */
3539 ushort q_max_tim[ADV_MAX_TID + 1]; /* maximum time queued */
3540 ushort q_min_tim[ADV_MAX_TID + 1]; /* minimum time queued */
3541#endif /* ADVANSYS_STATS */
1da177e4
LT
3542} asc_queue_t;
3543
3544/*
3545 * Adv Library Request Structures
3546 *
3547 * The following two structures are used to process Wide Board requests.
3548 *
3549 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
3550 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
3551 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
3552 * Mid-Level SCSI request structure.
3553 *
3554 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
3555 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
3556 * up to 255 scatter-gather elements may be used per request or
3557 * ADV_SCSI_REQ_Q.
3558 *
3559 * Both structures must be 32 byte aligned.
3560 */
3561typedef struct adv_sgblk {
27c868c2
MW
3562 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
3563 uchar align[32]; /* Sgblock structure padding. */
3564 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
1da177e4
LT
3565} adv_sgblk_t;
3566
3567typedef struct adv_req {
27c868c2
MW
3568 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
3569 uchar align[32]; /* Request structure padding. */
3570 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
3571 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
3572 struct adv_req *next_reqp; /* Next Request Structure. */
1da177e4
LT
3573} adv_req_t;
3574
3575/*
3576 * Structure allocated for each board.
3577 *
8dfb5379 3578 * This structure is allocated by scsi_host_alloc() at the end
1da177e4
LT
3579 * of the 'Scsi_Host' structure starting at the 'hostdata'
3580 * field. It is guaranteed to be allocated from DMA-able memory.
3581 */
3582typedef struct asc_board {
394dbf3f 3583 struct device *dev;
27c868c2
MW
3584 int id; /* Board Id */
3585 uint flags; /* Board flags */
3586 union {
3587 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
3588 ADV_DVC_VAR adv_dvc_var; /* Wide board */
3589 } dvc_var;
3590 union {
3591 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
3592 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
3593 } dvc_cfg;
3594 ushort asc_n_io_port; /* Number I/O ports. */
3595 asc_queue_t active; /* Active command queue */
3596 asc_queue_t waiting; /* Waiting command queue */
3597 asc_queue_t done; /* Done command queue */
3598 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
3599 struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */
3600 ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
3601 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
3602 ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
3603 union {
3604 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
3605 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
3606 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
3607 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
3608 } eep_config;
3609 ulong last_reset; /* Saved last reset time */
3610 spinlock_t lock; /* Board spinlock */
27c868c2
MW
3611 /* /proc/scsi/advansys/[0...] */
3612 char *prtbuf; /* /proc print buffer */
1da177e4 3613#ifdef ADVANSYS_STATS
27c868c2
MW
3614 struct asc_stats asc_stats; /* Board statistics */
3615#endif /* ADVANSYS_STATS */
3616 /*
3617 * The following fields are used only for Narrow Boards.
3618 */
27c868c2
MW
3619 uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */
3620 /*
3621 * The following fields are used only for Wide Boards.
3622 */
3623 void __iomem *ioremap_addr; /* I/O Memory remap address. */
3624 ushort ioport; /* I/O Port address. */
b2c16f58 3625 ADV_CARR_T *carrp; /* ADV_CARR_T memory block. */
27c868c2
MW
3626 adv_req_t *orig_reqp; /* adv_req_t memory block. */
3627 adv_req_t *adv_reqp; /* Request structures. */
3628 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
3629 ushort bios_signature; /* BIOS Signature. */
3630 ushort bios_version; /* BIOS Version. */
3631 ushort bios_codeseg; /* BIOS Code Segment. */
3632 ushort bios_codelen; /* BIOS Code Segment Length. */
1da177e4
LT
3633} asc_board_t;
3634
1da177e4 3635/* Number of boards detected in system. */
78e77d8b
MW
3636static int asc_board_count;
3637
1da177e4 3638/* Overrun buffer used by all narrow boards. */
27c868c2 3639static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
1da177e4
LT
3640
3641/*
3642 * Global structures required to issue a command.
3643 */
27c868c2
MW
3644static ASC_SCSI_Q asc_scsi_q = { {0} };
3645static ASC_SG_HEAD asc_sg_head = { 0 };
1da177e4 3646
1da177e4 3647#ifdef ADVANSYS_DEBUG
27c868c2 3648static int asc_dbglvl = 3;
1da177e4
LT
3649#endif /* ADVANSYS_DEBUG */
3650
1da177e4
LT
3651/*
3652 * --- Driver Function Prototypes
1da177e4
LT
3653 */
3654
27c868c2
MW
3655static int advansys_slave_configure(struct scsi_device *);
3656static void asc_scsi_done_list(struct scsi_cmnd *);
3657static int asc_execute_scsi_cmnd(struct scsi_cmnd *);
3658static int asc_build_req(asc_board_t *, struct scsi_cmnd *);
3659static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
3660static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
27c868c2
MW
3661static void asc_enqueue(asc_queue_t *, REQP, int);
3662static REQP asc_dequeue(asc_queue_t *, int);
3663static REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
3664static int asc_rmqueue(asc_queue_t *, REQP);
3665static void asc_execute_queue(asc_queue_t *);
1da177e4 3666#ifdef CONFIG_PROC_FS
27c868c2
MW
3667static int asc_proc_copy(off_t, off_t, char *, int, char *, int);
3668static int asc_prt_board_devices(struct Scsi_Host *, char *, int);
3669static int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
3670static int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
3671static int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
3672static int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
3673static int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
3674static int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
3675static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
3676static int asc_prt_line(char *, int, char *fmt, ...);
1da177e4
LT
3677#endif /* CONFIG_PROC_FS */
3678
1da177e4
LT
3679/* Statistics function prototypes. */
3680#ifdef ADVANSYS_STATS
3681#ifdef CONFIG_PROC_FS
27c868c2
MW
3682static int asc_prt_board_stats(struct Scsi_Host *, char *, int);
3683static int asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
1da177e4
LT
3684#endif /* CONFIG_PROC_FS */
3685#endif /* ADVANSYS_STATS */
3686
3687/* Debug function prototypes. */
3688#ifdef ADVANSYS_DEBUG
27c868c2
MW
3689static void asc_prt_scsi_host(struct Scsi_Host *);
3690static void asc_prt_scsi_cmnd(struct scsi_cmnd *);
3691static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
3692static void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
3693static void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
3694static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
3695static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
3696static void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
3697static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
3698static void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
3699static void asc_prt_hex(char *f, uchar *, int);
1da177e4
LT
3700#endif /* ADVANSYS_DEBUG */
3701
1da177e4
LT
3702#ifdef CONFIG_PROC_FS
3703/*
c304ec94 3704 * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
1da177e4
LT
3705 *
3706 * *buffer: I/O buffer
3707 * **start: if inout == FALSE pointer into buffer where user read should start
3708 * offset: current offset into a /proc/scsi/advansys/[0...] file
3709 * length: length of buffer
3710 * hostno: Scsi_Host host_no
3711 * inout: TRUE - user is writing; FALSE - user is reading
3712 *
3713 * Return the number of bytes read from or written to a
3714 * /proc/scsi/advansys/[0...] file.
3715 *
3716 * Note: This function uses the per board buffer 'prtbuf' which is
3717 * allocated when the board is initialized in advansys_detect(). The
3718 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
3719 * used to write to the buffer. The way asc_proc_copy() is written
3720 * if 'prtbuf' is too small it will not be overwritten. Instead the
3721 * user just won't get all the available statistics.
3722 */
70c8d897 3723static int
1da177e4 3724advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
27c868c2 3725 off_t offset, int length, int inout)
1da177e4 3726{
27c868c2 3727 asc_board_t *boardp;
27c868c2
MW
3728 char *cp;
3729 int cplen;
3730 int cnt;
3731 int totcnt;
3732 int leftlen;
3733 char *curbuf;
3734 off_t advoffset;
1da177e4 3735#ifdef ADVANSYS_STATS
27c868c2 3736 int tgt_id;
1da177e4
LT
3737#endif /* ADVANSYS_STATS */
3738
27c868c2 3739 ASC_DBG(1, "advansys_proc_info: begin\n");
1da177e4 3740
27c868c2
MW
3741 /*
3742 * User write not supported.
3743 */
3744 if (inout == TRUE) {
3745 return (-ENOSYS);
3746 }
1da177e4 3747
27c868c2
MW
3748 /*
3749 * User read of /proc/scsi/advansys/[0...] file.
3750 */
1da177e4 3751
2a437959 3752 boardp = ASC_BOARDP(shost);
27c868c2
MW
3753
3754 /* Copy read data starting at the beginning of the buffer. */
3755 *start = buffer;
3756 curbuf = buffer;
3757 advoffset = 0;
3758 totcnt = 0;
3759 leftlen = length;
3760
3761 /*
3762 * Get board configuration information.
3763 *
3764 * advansys_info() returns the board string from its own static buffer.
3765 */
2a437959 3766 cp = (char *)advansys_info(shost);
27c868c2
MW
3767 strcat(cp, "\n");
3768 cplen = strlen(cp);
3769 /* Copy board information. */
3770 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3771 totcnt += cnt;
3772 leftlen -= cnt;
3773 if (leftlen == 0) {
3774 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3775 return totcnt;
3776 }
3777 advoffset += cplen;
3778 curbuf += cnt;
3779
3780 /*
3781 * Display Wide Board BIOS Information.
3782 */
3783 if (ASC_WIDE_BOARD(boardp)) {
3784 cp = boardp->prtbuf;
2a437959 3785 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 3786 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
ecec1947 3787 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
27c868c2
MW
3788 cplen);
3789 totcnt += cnt;
3790 leftlen -= cnt;
3791 if (leftlen == 0) {
3792 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3793 return totcnt;
3794 }
3795 advoffset += cplen;
3796 curbuf += cnt;
3797 }
1da177e4 3798
27c868c2
MW
3799 /*
3800 * Display driver information for each device attached to the board.
3801 */
3802 cp = boardp->prtbuf;
2a437959 3803 cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
3804 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3805 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3806 totcnt += cnt;
3807 leftlen -= cnt;
3808 if (leftlen == 0) {
3809 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3810 return totcnt;
3811 }
3812 advoffset += cplen;
3813 curbuf += cnt;
3814
3815 /*
3816 * Display EEPROM configuration for the board.
3817 */
3818 cp = boardp->prtbuf;
3819 if (ASC_NARROW_BOARD(boardp)) {
2a437959 3820 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 3821 } else {
2a437959 3822 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
3823 }
3824 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3825 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3826 totcnt += cnt;
3827 leftlen -= cnt;
3828 if (leftlen == 0) {
3829 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3830 return totcnt;
3831 }
3832 advoffset += cplen;
3833 curbuf += cnt;
3834
3835 /*
3836 * Display driver configuration and information for the board.
3837 */
3838 cp = boardp->prtbuf;
2a437959 3839 cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
3840 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3841 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3842 totcnt += cnt;
3843 leftlen -= cnt;
3844 if (leftlen == 0) {
3845 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3846 return totcnt;
3847 }
3848 advoffset += cplen;
3849 curbuf += cnt;
1da177e4
LT
3850
3851#ifdef ADVANSYS_STATS
27c868c2
MW
3852 /*
3853 * Display driver statistics for the board.
3854 */
3855 cp = boardp->prtbuf;
2a437959 3856 cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
3857 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
3858 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3859 totcnt += cnt;
3860 leftlen -= cnt;
3861 if (leftlen == 0) {
3862 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3863 return totcnt;
3864 }
3865 advoffset += cplen;
3866 curbuf += cnt;
3867
3868 /*
3869 * Display driver statistics for each target.
3870 */
3871 for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
3872 cp = boardp->prtbuf;
2a437959 3873 cplen = asc_prt_target_stats(shost, tgt_id, cp,
ecec1947 3874 ASC_PRTBUF_SIZE);
27c868c2 3875 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
ecec1947
MW
3876 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
3877 cplen);
27c868c2
MW
3878 totcnt += cnt;
3879 leftlen -= cnt;
3880 if (leftlen == 0) {
3881 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3882 return totcnt;
3883 }
3884 advoffset += cplen;
3885 curbuf += cnt;
3886 }
1da177e4
LT
3887#endif /* ADVANSYS_STATS */
3888
27c868c2
MW
3889 /*
3890 * Display Asc Library dynamic configuration information
3891 * for the board.
3892 */
3893 cp = boardp->prtbuf;
3894 if (ASC_NARROW_BOARD(boardp)) {
2a437959 3895 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 3896 } else {
2a437959 3897 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
3898 }
3899 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3900 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3901 totcnt += cnt;
3902 leftlen -= cnt;
3903 if (leftlen == 0) {
3904 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3905 return totcnt;
3906 }
3907 advoffset += cplen;
3908 curbuf += cnt;
1da177e4 3909
27c868c2 3910 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
1da177e4 3911
27c868c2 3912 return totcnt;
1da177e4 3913}
1da177e4 3914#endif /* CONFIG_PROC_FS */
1da177e4
LT
3915
3916/*
3917 * advansys_info()
3918 *
3919 * Return suitable for printing on the console with the argument
3920 * adapter's configuration information.
3921 *
3922 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
3923 * otherwise the static 'info' array will be overrun.
3924 */
27c868c2 3925static const char *advansys_info(struct Scsi_Host *shost)
1da177e4 3926{
27c868c2
MW
3927 static char info[ASC_INFO_SIZE];
3928 asc_board_t *boardp;
3929 ASC_DVC_VAR *asc_dvc_varp;
3930 ADV_DVC_VAR *adv_dvc_varp;
3931 char *busname;
27c868c2
MW
3932 char *widename = NULL;
3933
3934 boardp = ASC_BOARDP(shost);
3935 if (ASC_NARROW_BOARD(boardp)) {
3936 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3937 ASC_DBG(1, "advansys_info: begin\n");
3938 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
3939 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
3940 ASC_IS_ISAPNP) {
3941 busname = "ISA PnP";
3942 } else {
3943 busname = "ISA";
3944 }
27c868c2
MW
3945 sprintf(info,
3946 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
3947 ASC_VERSION, busname,
3948 (ulong)shost->io_port,
4a2d31c8
MW
3949 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
3950 shost->irq, shost->dma_channel);
27c868c2
MW
3951 } else {
3952 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
3953 busname = "VL";
3954 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
3955 busname = "EISA";
3956 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
3957 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
3958 == ASC_IS_PCI_ULTRA) {
3959 busname = "PCI Ultra";
3960 } else {
3961 busname = "PCI";
3962 }
3963 } else {
3964 busname = "?";
ecec1947
MW
3965 ASC_PRINT2("advansys_info: board %d: unknown "
3966 "bus type %d\n", boardp->id,
3967 asc_dvc_varp->bus_type);
27c868c2 3968 }
27c868c2
MW
3969 sprintf(info,
3970 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
ecec1947 3971 ASC_VERSION, busname, (ulong)shost->io_port,
4a2d31c8
MW
3972 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
3973 shost->irq);
27c868c2
MW
3974 }
3975 } else {
3976 /*
3977 * Wide Adapter Information
3978 *
3979 * Memory-mapped I/O is used instead of I/O space to access
3980 * the adapter, but display the I/O Port range. The Memory
3981 * I/O address is displayed through the driver /proc file.
3982 */
3983 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
3984 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
27c868c2
MW
3985 widename = "Ultra-Wide";
3986 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
27c868c2
MW
3987 widename = "Ultra2-Wide";
3988 } else {
27c868c2
MW
3989 widename = "Ultra3-Wide";
3990 }
3991 sprintf(info,
3992 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
3993 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
4a2d31c8 3994 (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, shost->irq);
27c868c2
MW
3995 }
3996 ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
3997 ASC_DBG(1, "advansys_info: end\n");
3998 return info;
1da177e4
LT
3999}
4000
4001/*
4002 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
4003 *
4004 * This function always returns 0. Command return status is saved
4005 * in the 'scp' result field.
4006 */
70c8d897 4007static int
27c868c2 4008advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *))
1da177e4 4009{
27c868c2
MW
4010 struct Scsi_Host *shost;
4011 asc_board_t *boardp;
4012 ulong flags;
4013 struct scsi_cmnd *done_scp;
1da177e4 4014
27c868c2
MW
4015 shost = scp->device->host;
4016 boardp = ASC_BOARDP(shost);
4017 ASC_STATS(shost, queuecommand);
1da177e4 4018
27c868c2
MW
4019 /* host_lock taken by mid-level prior to call but need to protect */
4020 /* against own ISR */
4021 spin_lock_irqsave(&boardp->lock, flags);
1da177e4 4022
27c868c2
MW
4023 /*
4024 * Block new commands while handling a reset or abort request.
4025 */
4026 if (boardp->flags & ASC_HOST_IN_RESET) {
4027 ASC_DBG1(1,
4028 "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
4029 (ulong)scp);
4030 scp->result = HOST_BYTE(DID_RESET);
1da177e4 4031
27c868c2
MW
4032 /*
4033 * Add blocked requests to the board's 'done' queue. The queued
4034 * requests will be completed at the end of the abort or reset
4035 * handling.
4036 */
4037 asc_enqueue(&boardp->done, scp, ASC_BACK);
4038 spin_unlock_irqrestore(&boardp->lock, flags);
4039 return 0;
4040 }
1da177e4 4041
27c868c2
MW
4042 /*
4043 * Attempt to execute any waiting commands for the board.
4044 */
4045 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4046 ASC_DBG(1,
4047 "advansys_queuecommand: before asc_execute_queue() waiting\n");
4048 asc_execute_queue(&boardp->waiting);
4049 }
4050
4051 /*
4052 * Save the function pointer to Linux mid-level 'done' function
4053 * and attempt to execute the command.
4054 *
4055 * If ASC_NOERROR is returned the request has been added to the
4056 * board's 'active' queue and will be completed by the interrupt
4057 * handler.
4058 *
4059 * If ASC_BUSY is returned add the request to the board's per
4060 * target waiting list. This is the first time the request has
4061 * been tried. Add it to the back of the waiting list. It will be
4062 * retried later.
4063 *
4064 * If an error occurred, the request will have been placed on the
4065 * board's 'done' queue and must be completed before returning.
4066 */
4067 scp->scsi_done = done;
4068 switch (asc_execute_scsi_cmnd(scp)) {
4069 case ASC_NOERROR:
4070 break;
4071 case ASC_BUSY:
4072 asc_enqueue(&boardp->waiting, scp, ASC_BACK);
4073 break;
4074 case ASC_ERROR:
4075 default:
4076 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
4077 /* Interrupts could be enabled here. */
4078 asc_scsi_done_list(done_scp);
4079 break;
4080 }
4081 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 4082
27c868c2 4083 return 0;
1da177e4
LT
4084}
4085
4086/*
4087 * advansys_reset()
4088 *
4089 * Reset the bus associated with the command 'scp'.
4090 *
4091 * This function runs its own thread. Interrupts must be blocked but
4092 * sleeping is allowed and no locking other than for host structures is
4093 * required. Returns SUCCESS or FAILED.
4094 */
27c868c2 4095static int advansys_reset(struct scsi_cmnd *scp)
1da177e4 4096{
27c868c2
MW
4097 struct Scsi_Host *shost;
4098 asc_board_t *boardp;
4099 ASC_DVC_VAR *asc_dvc_varp;
4100 ADV_DVC_VAR *adv_dvc_varp;
4101 ulong flags;
4102 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4103 struct scsi_cmnd *tscp, *new_last_scp;
4104 int status;
4105 int ret = SUCCESS;
4106
4107 ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp);
1da177e4
LT
4108
4109#ifdef ADVANSYS_STATS
27c868c2
MW
4110 if (scp->device->host != NULL) {
4111 ASC_STATS(scp->device->host, reset);
4112 }
1da177e4
LT
4113#endif /* ADVANSYS_STATS */
4114
27c868c2
MW
4115 if ((shost = scp->device->host) == NULL) {
4116 scp->result = HOST_BYTE(DID_ERROR);
4117 return FAILED;
4118 }
1da177e4 4119
27c868c2 4120 boardp = ASC_BOARDP(shost);
1da177e4 4121
27c868c2
MW
4122 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
4123 boardp->id);
4124 /*
4125 * Check for re-entrancy.
4126 */
1da177e4 4127 spin_lock_irqsave(&boardp->lock, flags);
27c868c2
MW
4128 if (boardp->flags & ASC_HOST_IN_RESET) {
4129 spin_unlock_irqrestore(&boardp->lock, flags);
4130 return FAILED;
4131 }
4132 boardp->flags |= ASC_HOST_IN_RESET;
4133 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 4134
27c868c2
MW
4135 if (ASC_NARROW_BOARD(boardp)) {
4136 /*
4137 * Narrow Board
4138 */
4139 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
1da177e4 4140
27c868c2
MW
4141 /*
4142 * Reset the chip and SCSI bus.
4143 */
4144 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
4145 status = AscInitAsc1000Driver(asc_dvc_varp);
4146
4147 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
4148 if (asc_dvc_varp->err_code) {
ecec1947
MW
4149 ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
4150 "error: 0x%x\n", boardp->id,
4151 asc_dvc_varp->err_code);
27c868c2
MW
4152 ret = FAILED;
4153 } else if (status) {
ecec1947
MW
4154 ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
4155 "warning: 0x%x\n", boardp->id, status);
27c868c2 4156 } else {
ecec1947
MW
4157 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
4158 "successful.\n", boardp->id);
27c868c2
MW
4159 }
4160
4161 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
4162 spin_lock_irqsave(&boardp->lock, flags);
1da177e4 4163
27c868c2
MW
4164 } else {
4165 /*
4166 * Wide Board
4167 *
4168 * If the suggest reset bus flags are set, then reset the bus.
4169 * Otherwise only reset the device.
4170 */
4171 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
1da177e4 4172
27c868c2
MW
4173 /*
4174 * Reset the target's SCSI bus.
4175 */
4176 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
4177 switch (AdvResetChipAndSB(adv_dvc_varp)) {
4178 case ASC_TRUE:
ecec1947
MW
4179 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
4180 "successful.\n", boardp->id);
27c868c2
MW
4181 break;
4182 case ASC_FALSE:
4183 default:
ecec1947
MW
4184 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
4185 "error.\n", boardp->id);
27c868c2
MW
4186 ret = FAILED;
4187 break;
4188 }
4189 spin_lock_irqsave(&boardp->lock, flags);
4190 (void)AdvISR(adv_dvc_varp);
4191 }
4192 /* Board lock is held. */
4193
4194 /*
4195 * Dequeue all board 'done' requests. A pointer to the last request
4196 * is returned in 'last_scp'.
4197 */
4198 done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
4199
4200 /*
4201 * Dequeue all board 'active' requests for all devices and set
4202 * the request status to DID_RESET. A pointer to the last request
4203 * is returned in 'last_scp'.
4204 */
4205 if (done_scp == NULL) {
ecec1947
MW
4206 done_scp = asc_dequeue_list(&boardp->active, &last_scp,
4207 ASC_TID_ALL);
27c868c2
MW
4208 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4209 tscp->result = HOST_BYTE(DID_RESET);
4210 }
4211 } else {
4212 /* Append to 'done_scp' at the end with 'last_scp'. */
4213 ASC_ASSERT(last_scp != NULL);
4214 last_scp->host_scribble =
4215 (unsigned char *)asc_dequeue_list(&boardp->active,
4216 &new_last_scp,
4217 ASC_TID_ALL);
4218 if (new_last_scp != NULL) {
4219 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4220 for (tscp = REQPNEXT(last_scp); tscp;
4221 tscp = REQPNEXT(tscp)) {
4222 tscp->result = HOST_BYTE(DID_RESET);
4223 }
4224 last_scp = new_last_scp;
4225 }
4226 }
1da177e4 4227
27c868c2
MW
4228 /*
4229 * Dequeue all 'waiting' requests and set the request status
4230 * to DID_RESET.
4231 */
4232 if (done_scp == NULL) {
ecec1947
MW
4233 done_scp = asc_dequeue_list(&boardp->waiting, &last_scp,
4234 ASC_TID_ALL);
27c868c2
MW
4235 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4236 tscp->result = HOST_BYTE(DID_RESET);
4237 }
4238 } else {
4239 /* Append to 'done_scp' at the end with 'last_scp'. */
4240 ASC_ASSERT(last_scp != NULL);
4241 last_scp->host_scribble =
4242 (unsigned char *)asc_dequeue_list(&boardp->waiting,
4243 &new_last_scp,
4244 ASC_TID_ALL);
4245 if (new_last_scp != NULL) {
4246 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4247 for (tscp = REQPNEXT(last_scp); tscp;
4248 tscp = REQPNEXT(tscp)) {
4249 tscp->result = HOST_BYTE(DID_RESET);
4250 }
4251 last_scp = new_last_scp;
4252 }
4253 }
1da177e4 4254
27c868c2
MW
4255 /* Save the time of the most recently completed reset. */
4256 boardp->last_reset = jiffies;
1da177e4 4257
27c868c2
MW
4258 /* Clear reset flag. */
4259 boardp->flags &= ~ASC_HOST_IN_RESET;
4260 spin_unlock_irqrestore(&boardp->lock, flags);
4261
4262 /*
4263 * Complete all the 'done_scp' requests.
4264 */
ecec1947 4265 if (done_scp)
27c868c2 4266 asc_scsi_done_list(done_scp);
1da177e4 4267
27c868c2 4268 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
1da177e4 4269
27c868c2 4270 return ret;
1da177e4
LT
4271}
4272
4273/*
4274 * advansys_biosparam()
4275 *
4276 * Translate disk drive geometry if the "BIOS greater than 1 GB"
4277 * support is enabled for a drive.
4278 *
4279 * ip (information pointer) is an int array with the following definition:
4280 * ip[0]: heads
4281 * ip[1]: sectors
4282 * ip[2]: cylinders
4283 */
70c8d897 4284static int
1da177e4 4285advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
27c868c2 4286 sector_t capacity, int ip[])
1da177e4 4287{
27c868c2
MW
4288 asc_board_t *boardp;
4289
4290 ASC_DBG(1, "advansys_biosparam: begin\n");
4291 ASC_STATS(sdev->host, biosparam);
4292 boardp = ASC_BOARDP(sdev->host);
4293 if (ASC_NARROW_BOARD(boardp)) {
4294 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
4295 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
4296 ip[0] = 255;
4297 ip[1] = 63;
4298 } else {
4299 ip[0] = 64;
4300 ip[1] = 32;
4301 }
4302 } else {
4303 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
4304 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
4305 ip[0] = 255;
4306 ip[1] = 63;
4307 } else {
4308 ip[0] = 64;
4309 ip[1] = 32;
4310 }
4311 }
4312 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
4313 ASC_DBG(1, "advansys_biosparam: end\n");
4314 return 0;
1da177e4
LT
4315}
4316
8dfb5379 4317static struct scsi_host_template advansys_template = {
27c868c2 4318 .proc_name = "advansys",
1da177e4 4319#ifdef CONFIG_PROC_FS
27c868c2 4320 .proc_info = advansys_proc_info,
1da177e4 4321#endif
27c868c2 4322 .name = "advansys",
27c868c2
MW
4323 .info = advansys_info,
4324 .queuecommand = advansys_queuecommand,
4325 .eh_bus_reset_handler = advansys_reset,
4326 .bios_param = advansys_biosparam,
4327 .slave_configure = advansys_slave_configure,
4328 /*
4329 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
8dfb5379
MW
4330 * must be set. The flag will be cleared in advansys_board_found
4331 * for non-ISA adapters.
27c868c2
MW
4332 */
4333 .unchecked_isa_dma = 1,
4334 /*
4335 * All adapters controlled by this driver are capable of large
4336 * scatter-gather lists. According to the mid-level SCSI documentation
4337 * this obviates any performance gain provided by setting
4338 * 'use_clustering'. But empirically while CPU utilization is increased
4339 * by enabling clustering, I/O throughput increases as well.
4340 */
4341 .use_clustering = ENABLE_CLUSTERING,
1da177e4 4342};
1da177e4 4343
1da177e4
LT
4344/*
4345 * --- Miscellaneous Driver Functions
4346 */
4347
4348/*
4349 * First-level interrupt handler.
4350 *
4351 * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
4352 * all boards are currently checked for interrupts on each interrupt, 'dev_id'
4353 * is not referenced. 'dev_id' could be used to identify an interrupt passed
4354 * to the AdvanSys driver which is for a device sharing an interrupt with
4355 * an AdvanSys adapter.
4356 */
27c868c2 4357static irqreturn_t advansys_interrupt(int irq, void *dev_id)
1da177e4 4358{
074c8fe4 4359 unsigned long flags;
27c868c2
MW
4360 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4361 struct scsi_cmnd *new_last_scp;
074c8fe4
MW
4362 struct Scsi_Host *shost = dev_id;
4363 asc_board_t *boardp = ASC_BOARDP(shost);
4364 irqreturn_t result = IRQ_NONE;
27c868c2 4365
074c8fe4
MW
4366 ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp);
4367 spin_lock_irqsave(&boardp->lock, flags);
4368 if (ASC_NARROW_BOARD(boardp)) {
4369 /*
4370 * Narrow Board
4371 */
4372 if (AscIsIntPending(shost->io_port)) {
4373 result = IRQ_HANDLED;
4374 ASC_STATS(shost, interrupt);
4375 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
4376 AscISR(&boardp->dvc_var.asc_dvc_var);
4377 }
4378 } else {
4379 /*
4380 * Wide Board
4381 */
4382 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
4383 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
4384 result = IRQ_HANDLED;
4385 ASC_STATS(shost, interrupt);
4386 }
4387 }
27c868c2
MW
4388
4389 /*
074c8fe4
MW
4390 * Start waiting requests and create a list of completed requests.
4391 *
4392 * If a reset request is being performed for the board, the reset
4393 * handler will complete pending requests after it has completed.
4394 */
4395 if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
4396 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%p, "
4397 "last_scp 0x%p\n", done_scp, last_scp);
4398
4399 /* Start any waiting commands for the board. */
4400 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4401 ASC_DBG(1, "advansys_interrupt: before "
4402 "asc_execute_queue()\n");
4403 asc_execute_queue(&boardp->waiting);
27c868c2 4404 }
1da177e4 4405
27c868c2 4406 /*
074c8fe4 4407 * Add to the list of requests that must be completed.
27c868c2 4408 *
074c8fe4
MW
4409 * 'done_scp' will always be NULL on the first iteration of
4410 * this loop. 'last_scp' is set at the same time as 'done_scp'.
27c868c2 4411 */
074c8fe4
MW
4412 if (done_scp == NULL) {
4413 done_scp = asc_dequeue_list(&boardp->done,
4414 &last_scp, ASC_TID_ALL);
4415 } else {
4416 ASC_ASSERT(last_scp != NULL);
4417 last_scp->host_scribble =
4418 (unsigned char *)asc_dequeue_list(&boardp->
4419 done,
4420 &new_last_scp,
4421 ASC_TID_ALL);
4422 if (new_last_scp != NULL) {
4423 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4424 last_scp = new_last_scp;
27c868c2
MW
4425 }
4426 }
27c868c2 4427 }
074c8fe4 4428 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 4429
27c868c2
MW
4430 /*
4431 * If interrupts were enabled on entry, then they
4432 * are now enabled here.
4433 *
4434 * Complete all requests on the done list.
4435 */
1da177e4 4436
27c868c2 4437 asc_scsi_done_list(done_scp);
1da177e4 4438
27c868c2 4439 ASC_DBG(1, "advansys_interrupt: end\n");
074c8fe4 4440 return result;
1da177e4
LT
4441}
4442
47d853cc
MW
4443static void
4444advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
4445{
4446 ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
4447 ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
4448
4449 if (sdev->lun == 0) {
4450 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
4451 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
4452 asc_dvc->init_sdtr |= tid_bit;
4453 } else {
4454 asc_dvc->init_sdtr &= ~tid_bit;
4455 }
4456
4457 if (orig_init_sdtr != asc_dvc->init_sdtr)
4458 AscAsyncFix(asc_dvc, sdev);
4459 }
4460
4461 if (sdev->tagged_supported) {
4462 if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
4463 if (sdev->lun == 0) {
4464 asc_dvc->cfg->can_tagged_qng |= tid_bit;
4465 asc_dvc->use_tagged_qng |= tid_bit;
4466 }
4467 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
4468 asc_dvc->max_dvc_qng[sdev->id]);
4469 }
4470 } else {
4471 if (sdev->lun == 0) {
4472 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
4473 asc_dvc->use_tagged_qng &= ~tid_bit;
4474 }
4475 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
4476 }
4477
4478 if ((sdev->lun == 0) &&
4479 (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
4480 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
4481 asc_dvc->cfg->disc_enable);
4482 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
4483 asc_dvc->use_tagged_qng);
4484 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
4485 asc_dvc->cfg->can_tagged_qng);
4486
4487 asc_dvc->max_dvc_qng[sdev->id] =
4488 asc_dvc->cfg->max_tag_qng[sdev->id];
4489 AscWriteLramByte(asc_dvc->iop_base,
4490 (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
4491 asc_dvc->max_dvc_qng[sdev->id]);
4492 }
4493}
4494
1da177e4 4495/*
47d853cc
MW
4496 * Wide Transfers
4497 *
4498 * If the EEPROM enabled WDTR for the device and the device supports wide
4499 * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and
4500 * write the new value to the microcode.
1da177e4 4501 */
47d853cc
MW
4502static void
4503advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
1da177e4 4504{
47d853cc
MW
4505 unsigned short cfg_word;
4506 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
4507 if ((cfg_word & tidmask) != 0)
4508 return;
4509
4510 cfg_word |= tidmask;
4511 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
1da177e4 4512
27c868c2 4513 /*
47d853cc
MW
4514 * Clear the microcode SDTR and WDTR negotiation done indicators for
4515 * the target to cause it to negotiate with the new setting set above.
4516 * WDTR when accepted causes the target to enter asynchronous mode, so
4517 * SDTR must be negotiated.
27c868c2 4518 */
47d853cc
MW
4519 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
4520 cfg_word &= ~tidmask;
4521 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
4522 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
4523 cfg_word &= ~tidmask;
4524 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
4525}
4526
4527/*
4528 * Synchronous Transfers
4529 *
4530 * If the EEPROM enabled SDTR for the device and the device
4531 * supports synchronous transfers, then turn on the device's
4532 * 'sdtr_able' bit. Write the new value to the microcode.
4533 */
4534static void
4535advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
4536{
4537 unsigned short cfg_word;
4538 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
4539 if ((cfg_word & tidmask) != 0)
4540 return;
4541
4542 cfg_word |= tidmask;
4543 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
4544
4545 /*
4546 * Clear the microcode "SDTR negotiation" done indicator for the
4547 * target to cause it to negotiate with the new setting set above.
4548 */
4549 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
4550 cfg_word &= ~tidmask;
4551 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
4552}
4553
4554/*
4555 * PPR (Parallel Protocol Request) Capable
4556 *
4557 * If the device supports DT mode, then it must be PPR capable.
4558 * The PPR message will be used in place of the SDTR and WDTR
4559 * messages to negotiate synchronous speed and offset, transfer
4560 * width, and protocol options.
4561 */
4562static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
4563 AdvPortAddr iop_base, unsigned short tidmask)
4564{
4565 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
4566 adv_dvc->ppr_able |= tidmask;
4567 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
4568}
4569
4570static void
4571advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
4572{
4573 AdvPortAddr iop_base = adv_dvc->iop_base;
4574 unsigned short tidmask = 1 << sdev->id;
4575
4576 if (sdev->lun == 0) {
4577 /*
4578 * Handle WDTR, SDTR, and Tag Queuing. If the feature
4579 * is enabled in the EEPROM and the device supports the
4580 * feature, then enable it in the microcode.
4581 */
4582
4583 if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
4584 advansys_wide_enable_wdtr(iop_base, tidmask);
4585 if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
4586 advansys_wide_enable_sdtr(iop_base, tidmask);
4587 if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
4588 advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
4589
4590 /*
4591 * Tag Queuing is disabled for the BIOS which runs in polled
4592 * mode and would see no benefit from Tag Queuing. Also by
4593 * disabling Tag Queuing in the BIOS devices with Tag Queuing
4594 * bugs will at least work with the BIOS.
4595 */
4596 if ((adv_dvc->tagqng_able & tidmask) &&
4597 sdev->tagged_supported) {
4598 unsigned short cfg_word;
4599 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
4600 cfg_word |= tidmask;
4601 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
4602 cfg_word);
4603 AdvWriteByteLram(iop_base,
4604 ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
4605 adv_dvc->max_dvc_qng);
27c868c2 4606 }
47d853cc
MW
4607 }
4608
4609 if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) {
4610 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
4611 adv_dvc->max_dvc_qng);
27c868c2 4612 } else {
47d853cc 4613 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
27c868c2 4614 }
47d853cc
MW
4615}
4616
4617/*
4618 * Set the number of commands to queue per device for the
4619 * specified host adapter.
4620 */
4621static int advansys_slave_configure(struct scsi_device *sdev)
4622{
4623 asc_board_t *boardp = ASC_BOARDP(sdev->host);
4624 boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
4625
4626 /*
4627 * Save a pointer to the sdev and set its initial/maximum
4628 * queue depth. Only save the pointer for a lun0 dev though.
4629 */
4630 if (sdev->lun == 0)
4631 boardp->device[sdev->id] = sdev;
4632
4633 if (ASC_NARROW_BOARD(boardp))
4634 advansys_narrow_slave_configure(sdev,
4635 &boardp->dvc_var.asc_dvc_var);
4636 else
4637 advansys_wide_slave_configure(sdev,
4638 &boardp->dvc_var.adv_dvc_var);
4639
27c868c2 4640 return 0;
1da177e4
LT
4641}
4642
4643/*
4644 * Complete all requests on the singly linked list pointed
4645 * to by 'scp'.
4646 *
4647 * Interrupts can be enabled on entry.
4648 */
27c868c2 4649static void asc_scsi_done_list(struct scsi_cmnd *scp)
1da177e4 4650{
27c868c2 4651 struct scsi_cmnd *tscp;
1da177e4 4652
27c868c2
MW
4653 ASC_DBG(2, "asc_scsi_done_list: begin\n");
4654 while (scp != NULL) {
4655 asc_board_t *boardp;
1da177e4 4656
27c868c2
MW
4657 ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp);
4658 tscp = REQPNEXT(scp);
4659 scp->host_scribble = NULL;
1da177e4 4660
27c868c2 4661 boardp = ASC_BOARDP(scp->device->host);
1da177e4 4662
27c868c2 4663 if (scp->use_sg)
394dbf3f 4664 dma_unmap_sg(boardp->dev,
27c868c2
MW
4665 (struct scatterlist *)scp->request_buffer,
4666 scp->use_sg, scp->sc_data_direction);
4667 else if (scp->request_bufflen)
394dbf3f 4668 dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
27c868c2
MW
4669 scp->request_bufflen,
4670 scp->sc_data_direction);
1da177e4 4671
27c868c2
MW
4672 ASC_STATS(scp->device->host, done);
4673 ASC_ASSERT(scp->scsi_done != NULL);
1da177e4 4674
27c868c2 4675 scp->scsi_done(scp);
1da177e4 4676
27c868c2
MW
4677 scp = tscp;
4678 }
4679 ASC_DBG(2, "asc_scsi_done_list: done\n");
4680 return;
1da177e4
LT
4681}
4682
4683/*
4684 * Execute a single 'Scsi_Cmnd'.
4685 *
4686 * The function 'done' is called when the request has been completed.
4687 *
4688 * Scsi_Cmnd:
4689 *
4690 * host - board controlling device
4691 * device - device to send command
4692 * target - target of device
4693 * lun - lun of device
4694 * cmd_len - length of SCSI CDB
4695 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
4696 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
4697 *
4698 * if (use_sg == 0) {
4699 * request_buffer - buffer address for request
4700 * request_bufflen - length of request buffer
4701 * } else {
4702 * request_buffer - pointer to scatterlist structure
4703 * }
4704 *
4705 * sense_buffer - sense command buffer
4706 *
4707 * result (4 bytes of an int):
4708 * Byte Meaning
4709 * 0 SCSI Status Byte Code
4710 * 1 SCSI One Byte Message Code
4711 * 2 Host Error Code
4712 * 3 Mid-Level Error Code
4713 *
4714 * host driver fields:
4715 * SCp - Scsi_Pointer used for command processing status
4716 * scsi_done - used to save caller's done function
4717 * host_scribble - used for pointer to another struct scsi_cmnd
4718 *
4719 * If this function returns ASC_NOERROR the request has been enqueued
4720 * on the board's 'active' queue and will be completed from the
4721 * interrupt handler.
4722 *
4723 * If this function returns ASC_NOERROR the request has been enqueued
4724 * on the board's 'done' queue and must be completed by the caller.
4725 *
4726 * If ASC_BUSY is returned the request will be enqueued by the
4727 * caller on the target's waiting queue and re-tried later.
4728 */
27c868c2 4729static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
1da177e4 4730{
27c868c2
MW
4731 asc_board_t *boardp;
4732 ASC_DVC_VAR *asc_dvc_varp;
4733 ADV_DVC_VAR *adv_dvc_varp;
4734 ADV_SCSI_REQ_Q *adv_scsiqp;
4735 struct scsi_device *device;
4736 int ret;
4737
4738 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
4739 (ulong)scp, (ulong)scp->scsi_done);
4740
4741 boardp = ASC_BOARDP(scp->device->host);
4742 device = boardp->device[scp->device->id];
4743
4744 if (ASC_NARROW_BOARD(boardp)) {
4745 /*
4746 * Build and execute Narrow Board request.
4747 */
4748
4749 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4750
4751 /*
4752 * Build Asc Library request structure using the
4753 * global structures 'asc_scsi_req' and 'asc_sg_head'.
4754 *
4755 * If an error is returned, then the request has been
4756 * queued on the board done queue. It will be completed
4757 * by the caller.
4758 *
4759 * asc_build_req() can not return ASC_BUSY.
4760 */
4761 if (asc_build_req(boardp, scp) == ASC_ERROR) {
4762 ASC_STATS(scp->device->host, build_error);
4763 return ASC_ERROR;
4764 }
4765
4766 /*
4767 * Execute the command. If there is no error, add the command
4768 * to the active queue.
4769 */
4770 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
4771 case ASC_NOERROR:
4772 ASC_STATS(scp->device->host, exe_noerror);
4773 /*
ecec1947
MW
4774 * Increment monotonically increasing per device
4775 * successful request counter. Wrapping doesn't matter.
27c868c2
MW
4776 */
4777 boardp->reqcnt[scp->device->id]++;
4778 asc_enqueue(&boardp->active, scp, ASC_BACK);
ecec1947
MW
4779 ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue(), "
4780 "ASC_NOERROR\n");
27c868c2
MW
4781 break;
4782 case ASC_BUSY:
4783 /*
ecec1947
MW
4784 * Caller will enqueue request on the target's waiting
4785 * queue and retry later.
27c868c2
MW
4786 */
4787 ASC_STATS(scp->device->host, exe_busy);
4788 break;
4789 case ASC_ERROR:
ecec1947
MW
4790 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4791 "AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4792 boardp->id, asc_dvc_varp->err_code);
27c868c2
MW
4793 ASC_STATS(scp->device->host, exe_error);
4794 scp->result = HOST_BYTE(DID_ERROR);
4795 asc_enqueue(&boardp->done, scp, ASC_BACK);
4796 break;
4797 default:
ecec1947
MW
4798 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4799 "AscExeScsiQueue() unknown, err_code 0x%x\n",
4800 boardp->id, asc_dvc_varp->err_code);
27c868c2
MW
4801 ASC_STATS(scp->device->host, exe_unknown);
4802 scp->result = HOST_BYTE(DID_ERROR);
4803 asc_enqueue(&boardp->done, scp, ASC_BACK);
4804 break;
4805 }
4806 } else {
4807 /*
4808 * Build and execute Wide Board request.
4809 */
4810 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4811
4812 /*
4813 * Build and get a pointer to an Adv Library request structure.
4814 *
4815 * If the request is successfully built then send it below,
4816 * otherwise return with an error.
4817 */
4818 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
4819 case ASC_NOERROR:
ecec1947
MW
4820 ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req "
4821 "ASC_NOERROR\n");
27c868c2
MW
4822 break;
4823 case ASC_BUSY:
ecec1947
MW
4824 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
4825 "ASC_BUSY\n");
27c868c2 4826 /*
ecec1947
MW
4827 * If busy is returned the request has not been
4828 * enqueued. It will be enqueued by the caller on the
4829 * target's waiting queue and retried later.
27c868c2 4830 *
ecec1947
MW
4831 * The asc_stats fields 'adv_build_noreq' and
4832 * 'adv_build_nosg' count wide board busy conditions.
4833 * They are updated in adv_build_req and
4834 * adv_get_sglist, respectively.
27c868c2
MW
4835 */
4836 return ASC_BUSY;
4837 case ASC_ERROR:
4838 /*
4839 * If an error is returned, then the request has been
4840 * queued on the board done queue. It will be completed
4841 * by the caller.
4842 */
4843 default:
ecec1947
MW
4844 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
4845 "ASC_ERROR\n");
27c868c2
MW
4846 ASC_STATS(scp->device->host, build_error);
4847 return ASC_ERROR;
4848 }
1da177e4 4849
27c868c2
MW
4850 /*
4851 * Execute the command. If there is no error, add the command
4852 * to the active queue.
4853 */
4854 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
4855 case ASC_NOERROR:
4856 ASC_STATS(scp->device->host, exe_noerror);
4857 /*
ecec1947
MW
4858 * Increment monotonically increasing per device
4859 * successful request counter. Wrapping doesn't matter.
27c868c2
MW
4860 */
4861 boardp->reqcnt[scp->device->id]++;
4862 asc_enqueue(&boardp->active, scp, ASC_BACK);
ecec1947
MW
4863 ASC_DBG(1, "asc_execute_scsi_cmnd: AdvExeScsiQueue(), "
4864 "ASC_NOERROR\n");
27c868c2
MW
4865 break;
4866 case ASC_BUSY:
4867 /*
ecec1947
MW
4868 * Caller will enqueue request on the target's waiting
4869 * queue and retry later.
27c868c2
MW
4870 */
4871 ASC_STATS(scp->device->host, exe_busy);
4872 break;
4873 case ASC_ERROR:
ecec1947
MW
4874 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4875 "AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4876 boardp->id, adv_dvc_varp->err_code);
27c868c2
MW
4877 ASC_STATS(scp->device->host, exe_error);
4878 scp->result = HOST_BYTE(DID_ERROR);
4879 asc_enqueue(&boardp->done, scp, ASC_BACK);
4880 break;
4881 default:
ecec1947
MW
4882 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4883 "AdvExeScsiQueue() unknown, err_code 0x%x\n",
4884 boardp->id, adv_dvc_varp->err_code);
27c868c2
MW
4885 ASC_STATS(scp->device->host, exe_unknown);
4886 scp->result = HOST_BYTE(DID_ERROR);
4887 asc_enqueue(&boardp->done, scp, ASC_BACK);
4888 break;
4889 }
4890 }
4891
4892 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
4893 return ret;
1da177e4
LT
4894}
4895
4896/*
4897 * Build a request structure for the Asc Library (Narrow Board).
4898 *
4899 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
4900 * used to build the request.
4901 *
4902 * If an error occurs, then queue the request on the board done
4903 * queue and return ASC_ERROR.
4904 */
27c868c2 4905static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
1da177e4 4906{
27c868c2
MW
4907 /*
4908 * Mutually exclusive access is required to 'asc_scsi_q' and
4909 * 'asc_sg_head' until after the request is started.
4910 */
4911 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
4912
4913 /*
4914 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
4915 */
4916 asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
4917
4918 /*
4919 * Build the ASC_SCSI_Q request.
4920 *
4921 * For narrow boards a CDB length maximum of 12 bytes
4922 * is supported.
4923 */
4924 if (scp->cmd_len > ASC_MAX_CDB_LEN) {
ecec1947
MW
4925 ASC_PRINT3("asc_build_req: board %d: cmd_len %d > "
4926 "ASC_MAX_CDB_LEN %d\n", boardp->id, scp->cmd_len,
4927 ASC_MAX_CDB_LEN);
27c868c2
MW
4928 scp->result = HOST_BYTE(DID_ERROR);
4929 asc_enqueue(&boardp->done, scp, ASC_BACK);
4930 return ASC_ERROR;
4931 }
4932 asc_scsi_q.cdbptr = &scp->cmnd[0];
4933 asc_scsi_q.q2.cdb_len = scp->cmd_len;
4934 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
4935 asc_scsi_q.q1.target_lun = scp->device->lun;
4936 asc_scsi_q.q2.target_ix =
4937 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
4938 asc_scsi_q.q1.sense_addr =
4939 cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
4940 asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
4941
4942 /*
4943 * If there are any outstanding requests for the current target,
4944 * then every 255th request send an ORDERED request. This heuristic
4945 * tries to retain the benefit of request sorting while preventing
4946 * request starvation. 255 is the max number of tags or pending commands
4947 * a device may have outstanding.
4948 *
4949 * The request count is incremented below for every successfully
4950 * started request.
4951 *
4952 */
4953 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
4954 (boardp->reqcnt[scp->device->id] % 255) == 0) {
4955 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
4956 } else {
4957 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
4958 }
1da177e4 4959
27c868c2
MW
4960 /*
4961 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
4962 * buffer command.
4963 */
4964 if (scp->use_sg == 0) {
4965 /*
4966 * CDB request of single contiguous buffer.
4967 */
4968 ASC_STATS(scp->device->host, cont_cnt);
4969 scp->SCp.dma_handle = scp->request_bufflen ?
394dbf3f 4970 dma_map_single(boardp->dev, scp->request_buffer,
27c868c2
MW
4971 scp->request_bufflen,
4972 scp->sc_data_direction) : 0;
4973 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
4974 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
4975 ASC_STATS_ADD(scp->device->host, cont_xfer,
4976 ASC_CEILING(scp->request_bufflen, 512));
4977 asc_scsi_q.q1.sg_queue_cnt = 0;
4978 asc_scsi_q.sg_head = NULL;
4979 } else {
4980 /*
4981 * CDB scatter-gather request list.
4982 */
4983 int sgcnt;
4984 int use_sg;
4985 struct scatterlist *slp;
4986
4987 slp = (struct scatterlist *)scp->request_buffer;
394dbf3f
MW
4988 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
4989 scp->sc_data_direction);
27c868c2
MW
4990
4991 if (use_sg > scp->device->host->sg_tablesize) {
394dbf3f
MW
4992 ASC_PRINT3("asc_build_req: board %d: use_sg %d > "
4993 "sg_tablesize %d\n", boardp->id, use_sg,
4994 scp->device->host->sg_tablesize);
4995 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
27c868c2
MW
4996 scp->sc_data_direction);
4997 scp->result = HOST_BYTE(DID_ERROR);
4998 asc_enqueue(&boardp->done, scp, ASC_BACK);
4999 return ASC_ERROR;
5000 }
5001
5002 ASC_STATS(scp->device->host, sg_cnt);
1da177e4 5003
27c868c2
MW
5004 /*
5005 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
5006 * structure to point to it.
5007 */
5008 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
5009
5010 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
5011 asc_scsi_q.sg_head = &asc_sg_head;
5012 asc_scsi_q.q1.data_cnt = 0;
5013 asc_scsi_q.q1.data_addr = 0;
5014 /* This is a byte value, otherwise it would need to be swapped. */
5015 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
5016 ASC_STATS_ADD(scp->device->host, sg_elem,
5017 asc_sg_head.entry_cnt);
1da177e4 5018
27c868c2
MW
5019 /*
5020 * Convert scatter-gather list into ASC_SG_HEAD list.
5021 */
5022 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
5023 asc_sg_head.sg_list[sgcnt].addr =
5024 cpu_to_le32(sg_dma_address(slp));
5025 asc_sg_head.sg_list[sgcnt].bytes =
5026 cpu_to_le32(sg_dma_len(slp));
5027 ASC_STATS_ADD(scp->device->host, sg_xfer,
5028 ASC_CEILING(sg_dma_len(slp), 512));
5029 }
5030 }
1da177e4 5031
27c868c2
MW
5032 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
5033 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
1da177e4 5034
27c868c2 5035 return ASC_NOERROR;
1da177e4
LT
5036}
5037
5038/*
5039 * Build a request structure for the Adv Library (Wide Board).
5040 *
5041 * If an adv_req_t can not be allocated to issue the request,
5042 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
5043 *
5044 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
5045 * microcode for DMA addresses or math operations are byte swapped
5046 * to little-endian order.
5047 */
27c868c2 5048static int
1da177e4 5049adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
27c868c2 5050 ADV_SCSI_REQ_Q **adv_scsiqpp)
1da177e4 5051{
27c868c2
MW
5052 adv_req_t *reqp;
5053 ADV_SCSI_REQ_Q *scsiqp;
5054 int i;
5055 int ret;
27c868c2
MW
5056
5057 /*
5058 * Allocate an adv_req_t structure from the board to execute
5059 * the command.
5060 */
5061 if (boardp->adv_reqp == NULL) {
5062 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
5063 ASC_STATS(scp->device->host, adv_build_noreq);
5064 return ASC_BUSY;
5065 } else {
5066 reqp = boardp->adv_reqp;
5067 boardp->adv_reqp = reqp->next_reqp;
5068 reqp->next_reqp = NULL;
5069 }
1da177e4 5070
27c868c2
MW
5071 /*
5072 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
5073 */
5074 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5075
5076 /*
5077 * Initialize the structure.
5078 */
5079 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
5080
5081 /*
5082 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
5083 */
5084 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
5085
5086 /*
5087 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
5088 */
5089 reqp->cmndp = scp;
5090
5091 /*
5092 * Build the ADV_SCSI_REQ_Q request.
5093 */
5094
5095 /*
5096 * Set CDB length and copy it to the request structure.
5097 * For wide boards a CDB length maximum of 16 bytes
5098 * is supported.
5099 */
5100 if (scp->cmd_len > ADV_MAX_CDB_LEN) {
5101 ASC_PRINT3
5102 ("adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n",
5103 boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
5104 scp->result = HOST_BYTE(DID_ERROR);
5105 asc_enqueue(&boardp->done, scp, ASC_BACK);
5106 return ASC_ERROR;
5107 }
5108 scsiqp->cdb_len = scp->cmd_len;
5109 /* Copy first 12 CDB bytes to cdb[]. */
5110 for (i = 0; i < scp->cmd_len && i < 12; i++) {
5111 scsiqp->cdb[i] = scp->cmnd[i];
5112 }
5113 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
5114 for (; i < scp->cmd_len; i++) {
5115 scsiqp->cdb16[i - 12] = scp->cmnd[i];
5116 }
1da177e4 5117
27c868c2
MW
5118 scsiqp->target_id = scp->device->id;
5119 scsiqp->target_lun = scp->device->lun;
1da177e4 5120
27c868c2
MW
5121 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
5122 scsiqp->sense_len = sizeof(scp->sense_buffer);
1da177e4 5123
27c868c2
MW
5124 /*
5125 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
5126 * buffer command.
5127 */
1da177e4 5128
1da177e4 5129 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
27c868c2
MW
5130 scsiqp->vdata_addr = scp->request_buffer;
5131 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
1da177e4 5132
27c868c2
MW
5133 if (scp->use_sg == 0) {
5134 /*
5135 * CDB request of single contiguous buffer.
5136 */
5137 reqp->sgblkp = NULL;
5138 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
5139 if (scp->request_bufflen) {
5140 scsiqp->vdata_addr = scp->request_buffer;
5141 scp->SCp.dma_handle =
394dbf3f 5142 dma_map_single(boardp->dev, scp->request_buffer,
27c868c2
MW
5143 scp->request_bufflen,
5144 scp->sc_data_direction);
5145 } else {
5146 scsiqp->vdata_addr = NULL;
5147 scp->SCp.dma_handle = 0;
5148 }
5149 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
5150 scsiqp->sg_list_ptr = NULL;
5151 scsiqp->sg_real_addr = 0;
5152 ASC_STATS(scp->device->host, cont_cnt);
5153 ASC_STATS_ADD(scp->device->host, cont_xfer,
5154 ASC_CEILING(scp->request_bufflen, 512));
5155 } else {
5156 /*
5157 * CDB scatter-gather request list.
5158 */
5159 struct scatterlist *slp;
5160 int use_sg;
5161
5162 slp = (struct scatterlist *)scp->request_buffer;
394dbf3f
MW
5163 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
5164 scp->sc_data_direction);
27c868c2
MW
5165
5166 if (use_sg > ADV_MAX_SG_LIST) {
394dbf3f
MW
5167 ASC_PRINT3("adv_build_req: board %d: use_sg %d > "
5168 "ADV_MAX_SG_LIST %d\n", boardp->id, use_sg,
5169 scp->device->host->sg_tablesize);
5170 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
27c868c2
MW
5171 scp->sc_data_direction);
5172 scp->result = HOST_BYTE(DID_ERROR);
5173 asc_enqueue(&boardp->done, scp, ASC_BACK);
5174
5175 /*
394dbf3f
MW
5176 * Free the 'adv_req_t' structure by adding it back
5177 * to the board free list.
27c868c2
MW
5178 */
5179 reqp->next_reqp = boardp->adv_reqp;
5180 boardp->adv_reqp = reqp;
5181
5182 return ASC_ERROR;
5183 }
5184
394dbf3f
MW
5185 ret = adv_get_sglist(boardp, reqp, scp, use_sg);
5186 if (ret != ADV_SUCCESS) {
27c868c2 5187 /*
394dbf3f
MW
5188 * Free the adv_req_t structure by adding it back to
5189 * the board free list.
27c868c2
MW
5190 */
5191 reqp->next_reqp = boardp->adv_reqp;
5192 boardp->adv_reqp = reqp;
5193
5194 return ret;
5195 }
5196
5197 ASC_STATS(scp->device->host, sg_cnt);
5198 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
5199 }
1da177e4 5200
27c868c2
MW
5201 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5202 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
1da177e4 5203
27c868c2 5204 *adv_scsiqpp = scsiqp;
1da177e4 5205
27c868c2 5206 return ASC_NOERROR;
1da177e4
LT
5207}
5208
5209/*
5210 * Build scatter-gather list for Adv Library (Wide Board).
5211 *
5212 * Additional ADV_SG_BLOCK structures will need to be allocated
5213 * if the total number of scatter-gather elements exceeds
5214 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
5215 * assumed to be physically contiguous.
5216 *
5217 * Return:
5218 * ADV_SUCCESS(1) - SG List successfully created
5219 * ADV_ERROR(-1) - SG List creation failed
5220 */
27c868c2
MW
5221static int
5222adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
5223 int use_sg)
1da177e4 5224{
27c868c2
MW
5225 adv_sgblk_t *sgblkp;
5226 ADV_SCSI_REQ_Q *scsiqp;
5227 struct scatterlist *slp;
5228 int sg_elem_cnt;
5229 ADV_SG_BLOCK *sg_block, *prev_sg_block;
5230 ADV_PADDR sg_block_paddr;
5231 int i;
5232
5233 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5234 slp = (struct scatterlist *)scp->request_buffer;
5235 sg_elem_cnt = use_sg;
5236 prev_sg_block = NULL;
5237 reqp->sgblkp = NULL;
5238
5239 do {
5240 /*
5241 * Allocate a 'adv_sgblk_t' structure from the board free
5242 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
5243 * (15) scatter-gather elements.
5244 */
5245 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
5246 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
5247 ASC_STATS(scp->device->host, adv_build_nosg);
5248
5249 /*
5250 * Allocation failed. Free 'adv_sgblk_t' structures already
5251 * allocated for the request.
5252 */
5253 while ((sgblkp = reqp->sgblkp) != NULL) {
5254 /* Remove 'sgblkp' from the request list. */
5255 reqp->sgblkp = sgblkp->next_sgblkp;
5256
5257 /* Add 'sgblkp' to the board free list. */
5258 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5259 boardp->adv_sgblkp = sgblkp;
5260 }
5261 return ASC_BUSY;
5262 } else {
5263 /* Complete 'adv_sgblk_t' board allocation. */
5264 boardp->adv_sgblkp = sgblkp->next_sgblkp;
5265 sgblkp->next_sgblkp = NULL;
5266
5267 /*
5268 * Get 8 byte aligned virtual and physical addresses for
5269 * the allocated ADV_SG_BLOCK structure.
5270 */
5271 sg_block =
5272 (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
5273 sg_block_paddr = virt_to_bus(sg_block);
5274
5275 /*
5276 * Check if this is the first 'adv_sgblk_t' for the request.
5277 */
5278 if (reqp->sgblkp == NULL) {
5279 /* Request's first scatter-gather block. */
5280 reqp->sgblkp = sgblkp;
5281
5282 /*
5283 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
5284 * address pointers.
5285 */
5286 scsiqp->sg_list_ptr = sg_block;
5287 scsiqp->sg_real_addr =
5288 cpu_to_le32(sg_block_paddr);
5289 } else {
5290 /* Request's second or later scatter-gather block. */
5291 sgblkp->next_sgblkp = reqp->sgblkp;
5292 reqp->sgblkp = sgblkp;
5293
5294 /*
5295 * Point the previous ADV_SG_BLOCK structure to
5296 * the newly allocated ADV_SG_BLOCK structure.
5297 */
5298 ASC_ASSERT(prev_sg_block != NULL);
5299 prev_sg_block->sg_ptr =
5300 cpu_to_le32(sg_block_paddr);
5301 }
5302 }
5303
5304 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
5305 sg_block->sg_list[i].sg_addr =
5306 cpu_to_le32(sg_dma_address(slp));
5307 sg_block->sg_list[i].sg_count =
5308 cpu_to_le32(sg_dma_len(slp));
5309 ASC_STATS_ADD(scp->device->host, sg_xfer,
5310 ASC_CEILING(sg_dma_len(slp), 512));
5311
5312 if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */
5313 sg_block->sg_cnt = i + 1;
5314 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
5315 return ADV_SUCCESS;
5316 }
5317 slp++;
5318 }
5319 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
5320 prev_sg_block = sg_block;
5321 }
5322 while (1);
5323 /* NOTREACHED */
1da177e4
LT
5324}
5325
5326/*
5327 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
5328 *
5329 * Interrupt callback function for the Narrow SCSI Asc Library.
5330 */
27c868c2 5331static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
1da177e4 5332{
27c868c2
MW
5333 asc_board_t *boardp;
5334 struct scsi_cmnd *scp;
5335 struct Scsi_Host *shost;
27c868c2
MW
5336
5337 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
5338 (ulong)asc_dvc_varp, (ulong)qdonep);
5339 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
5340
5341 /*
5342 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5343 * command that has been completed.
5344 */
5345 scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
5346 ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp);
5347
5348 if (scp == NULL) {
5349 ASC_PRINT("asc_isr_callback: scp is NULL\n");
5350 return;
5351 }
5352 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5353
27c868c2 5354 shost = scp->device->host;
27c868c2
MW
5355 ASC_STATS(shost, callback);
5356 ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
5357
5358 /*
5359 * If the request isn't found on the active queue, it may
5360 * have been removed to handle a reset request.
5361 * Display a message and return.
5362 */
5363 boardp = ASC_BOARDP(shost);
5364 ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
5365 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5366 ASC_PRINT2
5367 ("asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
5368 boardp->id, (ulong)scp);
5369 return;
5370 }
1da177e4 5371
27c868c2
MW
5372 /*
5373 * 'qdonep' contains the command's ending status.
5374 */
5375 switch (qdonep->d3.done_stat) {
5376 case QD_NO_ERROR:
5377 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
5378 scp->result = 0;
1da177e4 5379
27c868c2
MW
5380 /*
5381 * Check for an underrun condition.
5382 *
5383 * If there was no error and an underrun condition, then
47d853cc 5384 * return the number of underrun bytes.
27c868c2
MW
5385 */
5386 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
5387 qdonep->remain_bytes <= scp->request_bufflen) {
5388 ASC_DBG1(1,
5389 "asc_isr_callback: underrun condition %u bytes\n",
5390 (unsigned)qdonep->remain_bytes);
5391 scp->resid = qdonep->remain_bytes;
5392 }
5393 break;
5394
5395 case QD_WITH_ERROR:
5396 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
5397 switch (qdonep->d3.host_stat) {
5398 case QHSTA_NO_ERROR:
5399 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
5400 ASC_DBG(2,
5401 "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5402 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5403 sizeof(scp->sense_buffer));
5404 /*
5405 * Note: The 'status_byte()' macro used by target drivers
5406 * defined in scsi.h shifts the status byte returned by
5407 * host drivers right by 1 bit. This is why target drivers
5408 * also use right shifted status byte definitions. For
5409 * instance target drivers use CHECK_CONDITION, defined to
5410 * 0x1, instead of the SCSI defined check condition value
5411 * of 0x2. Host drivers are supposed to return the status
5412 * byte as it is defined by SCSI.
5413 */
5414 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5415 STATUS_BYTE(qdonep->d3.scsi_stat);
5416 } else {
5417 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
5418 }
5419 break;
5420
5421 default:
5422 /* QHSTA error occurred */
5423 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
5424 qdonep->d3.host_stat);
5425 scp->result = HOST_BYTE(DID_BAD_TARGET);
5426 break;
5427 }
5428 break;
5429
5430 case QD_ABORTED_BY_HOST:
5431 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
5432 scp->result =
5433 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
5434 scsi_msg) |
5435 STATUS_BYTE(qdonep->d3.scsi_stat);
5436 break;
5437
5438 default:
5439 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n",
5440 qdonep->d3.done_stat);
5441 scp->result =
5442 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
5443 scsi_msg) |
5444 STATUS_BYTE(qdonep->d3.scsi_stat);
5445 break;
5446 }
1da177e4 5447
27c868c2
MW
5448 /*
5449 * If the 'init_tidmask' bit isn't already set for the target and the
5450 * current request finished normally, then set the bit for the target
5451 * to indicate that a device is present.
5452 */
5453 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5454 qdonep->d3.done_stat == QD_NO_ERROR &&
5455 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
5456 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5457 }
1da177e4 5458
27c868c2
MW
5459 /*
5460 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5461 * function, add the command to the end of the board's done queue.
5462 * The done function for the command will be called from
5463 * advansys_interrupt().
5464 */
5465 asc_enqueue(&boardp->done, scp, ASC_BACK);
1da177e4 5466
27c868c2 5467 return;
1da177e4
LT
5468}
5469
5470/*
5471 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
5472 *
5473 * Callback function for the Wide SCSI Adv Library.
5474 */
27c868c2 5475static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
1da177e4 5476{
27c868c2
MW
5477 asc_board_t *boardp;
5478 adv_req_t *reqp;
5479 adv_sgblk_t *sgblkp;
5480 struct scsi_cmnd *scp;
5481 struct Scsi_Host *shost;
27c868c2
MW
5482 ADV_DCNT resid_cnt;
5483
5484 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
5485 (ulong)adv_dvc_varp, (ulong)scsiqp);
5486 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5487
5488 /*
5489 * Get the adv_req_t structure for the command that has been
5490 * completed. The adv_req_t structure actually contains the
5491 * completed ADV_SCSI_REQ_Q structure.
5492 */
5493 reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
5494 ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp);
5495 if (reqp == NULL) {
5496 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
5497 return;
5498 }
1da177e4 5499
27c868c2
MW
5500 /*
5501 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5502 * command that has been completed.
5503 *
5504 * Note: The adv_req_t request structure and adv_sgblk_t structure,
5505 * if any, are dropped, because a board structure pointer can not be
5506 * determined.
5507 */
5508 scp = reqp->cmndp;
5509 ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp);
5510 if (scp == NULL) {
5511 ASC_PRINT
5512 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
5513 return;
5514 }
5515 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5516
27c868c2 5517 shost = scp->device->host;
27c868c2
MW
5518 ASC_STATS(shost, callback);
5519 ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
5520
5521 /*
5522 * If the request isn't found on the active queue, it may have been
5523 * removed to handle a reset request. Display a message and return.
5524 *
5525 * Note: Because the structure may still be in use don't attempt
5526 * to free the adv_req_t and adv_sgblk_t, if any, structures.
5527 */
5528 boardp = ASC_BOARDP(shost);
5529 ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
5530 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5531 ASC_PRINT2
5532 ("adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
5533 boardp->id, (ulong)scp);
5534 return;
5535 }
1da177e4 5536
27c868c2
MW
5537 /*
5538 * 'done_status' contains the command's ending status.
5539 */
5540 switch (scsiqp->done_status) {
5541 case QD_NO_ERROR:
5542 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
5543 scp->result = 0;
1da177e4 5544
27c868c2
MW
5545 /*
5546 * Check for an underrun condition.
5547 *
5548 * If there was no error and an underrun condition, then
5549 * then return the number of underrun bytes.
5550 */
5551 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
5552 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
5553 resid_cnt <= scp->request_bufflen) {
5554 ASC_DBG1(1,
5555 "adv_isr_callback: underrun condition %lu bytes\n",
5556 (ulong)resid_cnt);
5557 scp->resid = resid_cnt;
5558 }
5559 break;
5560
5561 case QD_WITH_ERROR:
5562 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
5563 switch (scsiqp->host_status) {
5564 case QHSTA_NO_ERROR:
5565 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
5566 ASC_DBG(2,
5567 "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5568 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5569 sizeof(scp->sense_buffer));
5570 /*
5571 * Note: The 'status_byte()' macro used by target drivers
5572 * defined in scsi.h shifts the status byte returned by
5573 * host drivers right by 1 bit. This is why target drivers
5574 * also use right shifted status byte definitions. For
5575 * instance target drivers use CHECK_CONDITION, defined to
5576 * 0x1, instead of the SCSI defined check condition value
5577 * of 0x2. Host drivers are supposed to return the status
5578 * byte as it is defined by SCSI.
5579 */
5580 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5581 STATUS_BYTE(scsiqp->scsi_status);
5582 } else {
5583 scp->result = STATUS_BYTE(scsiqp->scsi_status);
5584 }
5585 break;
5586
5587 default:
5588 /* Some other QHSTA error occurred. */
5589 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
5590 scsiqp->host_status);
5591 scp->result = HOST_BYTE(DID_BAD_TARGET);
5592 break;
5593 }
5594 break;
5595
5596 case QD_ABORTED_BY_HOST:
5597 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
5598 scp->result =
5599 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
5600 break;
5601
5602 default:
5603 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n",
5604 scsiqp->done_status);
5605 scp->result =
5606 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
5607 break;
5608 }
1da177e4 5609
27c868c2
MW
5610 /*
5611 * If the 'init_tidmask' bit isn't already set for the target and the
5612 * current request finished normally, then set the bit for the target
5613 * to indicate that a device is present.
5614 */
5615 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5616 scsiqp->done_status == QD_NO_ERROR &&
5617 scsiqp->host_status == QHSTA_NO_ERROR) {
5618 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5619 }
1da177e4 5620
27c868c2
MW
5621 /*
5622 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5623 * function, add the command to the end of the board's done queue.
5624 * The done function for the command will be called from
5625 * advansys_interrupt().
5626 */
5627 asc_enqueue(&boardp->done, scp, ASC_BACK);
5628
5629 /*
5630 * Free all 'adv_sgblk_t' structures allocated for the request.
5631 */
5632 while ((sgblkp = reqp->sgblkp) != NULL) {
5633 /* Remove 'sgblkp' from the request list. */
5634 reqp->sgblkp = sgblkp->next_sgblkp;
5635
5636 /* Add 'sgblkp' to the board free list. */
5637 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5638 boardp->adv_sgblkp = sgblkp;
5639 }
1da177e4 5640
27c868c2
MW
5641 /*
5642 * Free the adv_req_t structure used with the command by adding
5643 * it back to the board free list.
5644 */
5645 reqp->next_reqp = boardp->adv_reqp;
5646 boardp->adv_reqp = reqp;
1da177e4 5647
27c868c2 5648 ASC_DBG(1, "adv_isr_callback: done\n");
1da177e4 5649
27c868c2 5650 return;
1da177e4
LT
5651}
5652
5653/*
5654 * adv_async_callback() - Adv Library asynchronous event callback function.
5655 */
27c868c2 5656static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
1da177e4 5657{
27c868c2
MW
5658 switch (code) {
5659 case ADV_ASYNC_SCSI_BUS_RESET_DET:
5660 /*
5661 * The firmware detected a SCSI Bus reset.
5662 */
5663 ASC_DBG(0,
5664 "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
5665 break;
5666
5667 case ADV_ASYNC_RDMA_FAILURE:
5668 /*
5669 * Handle RDMA failure by resetting the SCSI Bus and
5670 * possibly the chip if it is unresponsive. Log the error
5671 * with a unique code.
5672 */
5673 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
5674 AdvResetChipAndSB(adv_dvc_varp);
5675 break;
5676
5677 case ADV_HOST_SCSI_BUS_RESET:
5678 /*
5679 * Host generated SCSI bus reset occurred.
5680 */
5681 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
5682 break;
5683
5684 default:
5685 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
5686 break;
5687 }
1da177e4
LT
5688}
5689
5690/*
5691 * Add a 'REQP' to the end of specified queue. Set 'tidmask'
5692 * to indicate a command is queued for the device.
5693 *
5694 * 'flag' may be either ASC_FRONT or ASC_BACK.
5695 *
5696 * 'REQPNEXT(reqp)' returns reqp's next pointer.
5697 */
27c868c2 5698static void asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
1da177e4 5699{
27c868c2
MW
5700 int tid;
5701
5702 ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
5703 (ulong)ascq, (ulong)reqp, flag);
5704 ASC_ASSERT(reqp != NULL);
5705 ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
5706 tid = REQPTID(reqp);
5707 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5708 if (flag == ASC_FRONT) {
5709 reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
5710 ascq->q_first[tid] = reqp;
5711 /* If the queue was empty, set the last pointer. */
5712 if (ascq->q_last[tid] == NULL) {
5713 ascq->q_last[tid] = reqp;
5714 }
5715 } else { /* ASC_BACK */
5716 if (ascq->q_last[tid] != NULL) {
5717 ascq->q_last[tid]->host_scribble =
5718 (unsigned char *)reqp;
5719 }
5720 ascq->q_last[tid] = reqp;
5721 reqp->host_scribble = NULL;
5722 /* If the queue was empty, set the first pointer. */
5723 if (ascq->q_first[tid] == NULL) {
5724 ascq->q_first[tid] = reqp;
5725 }
5726 }
5727 /* The queue has at least one entry, set its bit. */
5728 ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
1da177e4 5729#ifdef ADVANSYS_STATS
27c868c2
MW
5730 /* Maintain request queue statistics. */
5731 ascq->q_tot_cnt[tid]++;
5732 ascq->q_cur_cnt[tid]++;
5733 if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
5734 ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
5735 ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
5736 tid, ascq->q_max_cnt[tid]);
5737 }
5738 REQPTIME(reqp) = REQTIMESTAMP();
1da177e4 5739#endif /* ADVANSYS_STATS */
27c868c2
MW
5740 ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong)reqp);
5741 return;
1da177e4
LT
5742}
5743
5744/*
5745 * Return first queued 'REQP' on the specified queue for
5746 * the specified target device. Clear the 'tidmask' bit for
5747 * the device if no more commands are left queued for it.
5748 *
5749 * 'REQPNEXT(reqp)' returns reqp's next pointer.
5750 */
27c868c2 5751static REQP asc_dequeue(asc_queue_t *ascq, int tid)
1da177e4 5752{
27c868c2
MW
5753 REQP reqp;
5754
5755 ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5756 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5757 if ((reqp = ascq->q_first[tid]) != NULL) {
5758 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
5759 ascq->q_first[tid] = REQPNEXT(reqp);
5760 /* If the queue is empty, clear its bit and the last pointer. */
5761 if (ascq->q_first[tid] == NULL) {
5762 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5763 ASC_ASSERT(ascq->q_last[tid] == reqp);
5764 ascq->q_last[tid] = NULL;
5765 }
1da177e4 5766#ifdef ADVANSYS_STATS
27c868c2
MW
5767 /* Maintain request queue statistics. */
5768 ascq->q_cur_cnt[tid]--;
5769 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
5770 REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
1da177e4 5771#endif /* ADVANSYS_STATS */
27c868c2
MW
5772 }
5773 ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong)reqp);
5774 return reqp;
1da177e4
LT
5775}
5776
5777/*
5778 * Return a pointer to a singly linked list of all the requests queued
5779 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
5780 *
5781 * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
5782 * the last request returned in the singly linked list.
5783 *
5784 * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
5785 * then all queued requests are concatenated into one list and
5786 * returned.
5787 *
5788 * Note: If 'lastpp' is used to append a new list to the end of
5789 * an old list, only change the old list last pointer if '*lastpp'
5790 * (or the function return value) is not NULL, i.e. use a temporary
5791 * variable for 'lastpp' and check its value after the function return
5792 * before assigning it to the list last pointer.
5793 *
5794 * Unfortunately collecting queuing time statistics adds overhead to
5795 * the function that isn't inherent to the function's algorithm.
5796 */
27c868c2 5797static REQP asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
1da177e4 5798{
27c868c2
MW
5799 REQP firstp, lastp;
5800 int i;
5801
5802 ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5803 ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
5804
5805 /*
5806 * If 'tid' is not ASC_TID_ALL, return requests only for
5807 * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
5808 * requests for all tids.
5809 */
5810 if (tid != ASC_TID_ALL) {
5811 /* Return all requests for the specified 'tid'. */
5812 if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
5813 /* List is empty; Set first and last return pointers to NULL. */
5814 firstp = lastp = NULL;
5815 } else {
5816 firstp = ascq->q_first[tid];
5817 lastp = ascq->q_last[tid];
5818 ascq->q_first[tid] = ascq->q_last[tid] = NULL;
5819 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
1da177e4 5820#ifdef ADVANSYS_STATS
27c868c2
MW
5821 {
5822 REQP reqp;
5823 ascq->q_cur_cnt[tid] = 0;
5824 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
5825 REQTIMESTAT("asc_dequeue_list", ascq,
5826 reqp, tid);
5827 }
5828 }
1da177e4 5829#endif /* ADVANSYS_STATS */
27c868c2
MW
5830 }
5831 } else {
5832 /* Return all requests for all tids. */
5833 firstp = lastp = NULL;
5834 for (i = 0; i <= ADV_MAX_TID; i++) {
5835 if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
5836 if (firstp == NULL) {
5837 firstp = ascq->q_first[i];
5838 lastp = ascq->q_last[i];
5839 } else {
5840 ASC_ASSERT(lastp != NULL);
5841 lastp->host_scribble =
5842 (unsigned char *)ascq->q_first[i];
5843 lastp = ascq->q_last[i];
5844 }
5845 ascq->q_first[i] = ascq->q_last[i] = NULL;
5846 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
1da177e4 5847#ifdef ADVANSYS_STATS
27c868c2 5848 ascq->q_cur_cnt[i] = 0;
1da177e4 5849#endif /* ADVANSYS_STATS */
27c868c2
MW
5850 }
5851 }
1da177e4 5852#ifdef ADVANSYS_STATS
27c868c2
MW
5853 {
5854 REQP reqp;
5855 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
5856 REQTIMESTAT("asc_dequeue_list", ascq, reqp,
5857 reqp->device->id);
5858 }
5859 }
1da177e4 5860#endif /* ADVANSYS_STATS */
27c868c2
MW
5861 }
5862 if (lastpp) {
5863 *lastpp = lastp;
5864 }
5865 ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong)firstp);
5866 return firstp;
1da177e4
LT
5867}
5868
5869/*
5870 * Remove the specified 'REQP' from the specified queue for
5871 * the specified target device. Clear the 'tidmask' bit for the
5872 * device if no more commands are left queued for it.
5873 *
5874 * 'REQPNEXT(reqp)' returns reqp's the next pointer.
5875 *
5876 * Return ASC_TRUE if the command was found and removed,
5877 * otherwise return ASC_FALSE.
5878 */
27c868c2 5879static int asc_rmqueue(asc_queue_t *ascq, REQP reqp)
1da177e4 5880{
27c868c2
MW
5881 REQP currp, prevp;
5882 int tid;
5883 int ret = ASC_FALSE;
5884
5885 ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
5886 (ulong)ascq, (ulong)reqp);
5887 ASC_ASSERT(reqp != NULL);
5888
5889 tid = REQPTID(reqp);
5890 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5891
5892 /*
5893 * Handle the common case of 'reqp' being the first
5894 * entry on the queue.
5895 */
5896 if (reqp == ascq->q_first[tid]) {
5897 ret = ASC_TRUE;
5898 ascq->q_first[tid] = REQPNEXT(reqp);
5899 /* If the queue is now empty, clear its bit and the last pointer. */
5900 if (ascq->q_first[tid] == NULL) {
5901 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5902 ASC_ASSERT(ascq->q_last[tid] == reqp);
5903 ascq->q_last[tid] = NULL;
5904 }
5905 } else if (ascq->q_first[tid] != NULL) {
5906 ASC_ASSERT(ascq->q_last[tid] != NULL);
5907 /*
5908 * Because the case of 'reqp' being the first entry has been
5909 * handled above and it is known the queue is not empty, if
5910 * 'reqp' is found on the queue it is guaranteed the queue will
5911 * not become empty and that 'q_first[tid]' will not be changed.
5912 *
5913 * Set 'prevp' to the first entry, 'currp' to the second entry,
5914 * and search for 'reqp'.
5915 */
5916 for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
5917 currp; prevp = currp, currp = REQPNEXT(currp)) {
5918 if (currp == reqp) {
5919 ret = ASC_TRUE;
5920 prevp->host_scribble =
5921 (unsigned char *)REQPNEXT(currp);
5922 reqp->host_scribble = NULL;
5923 if (ascq->q_last[tid] == reqp) {
5924 ascq->q_last[tid] = prevp;
5925 }
5926 break;
5927 }
5928 }
5929 }
1da177e4 5930#ifdef ADVANSYS_STATS
27c868c2
MW
5931 /* Maintain request queue statistics. */
5932 if (ret == ASC_TRUE) {
5933 ascq->q_cur_cnt[tid]--;
5934 REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
5935 }
5936 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
1da177e4 5937#endif /* ADVANSYS_STATS */
27c868c2
MW
5938 ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong)reqp, ret);
5939 return ret;
1da177e4
LT
5940}
5941
5942/*
5943 * Execute as many queued requests as possible for the specified queue.
5944 *
5945 * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd.
5946 */
27c868c2 5947static void asc_execute_queue(asc_queue_t *ascq)
1da177e4 5948{
27c868c2
MW
5949 ADV_SCSI_BIT_ID_TYPE scan_tidmask;
5950 REQP reqp;
5951 int i;
5952
5953 ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong)ascq);
5954 /*
5955 * Execute queued commands for devices attached to
5956 * the current board in round-robin fashion.
5957 */
5958 scan_tidmask = ascq->q_tidmask;
5959 do {
5960 for (i = 0; i <= ADV_MAX_TID; i++) {
5961 if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
5962 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
5963 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
5964 } else
5965 if (asc_execute_scsi_cmnd
5966 ((struct scsi_cmnd *)reqp)
5967 == ASC_BUSY) {
5968 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
5969 /*
5970 * The request returned ASC_BUSY. Enqueue at the front of
5971 * target's waiting list to maintain correct ordering.
5972 */
5973 asc_enqueue(ascq, reqp, ASC_FRONT);
5974 }
5975 }
5976 }
5977 } while (scan_tidmask);
5978 return;
1da177e4
LT
5979}
5980
5981#ifdef CONFIG_PROC_FS
5982/*
5983 * asc_prt_board_devices()
5984 *
5985 * Print driver information for devices attached to the board.
5986 *
5987 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5988 * cf. asc_prt_line().
5989 *
5990 * Return the number of characters copied into 'cp'. No more than
5991 * 'cplen' characters will be copied to 'cp'.
5992 */
27c868c2 5993static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 5994{
27c868c2
MW
5995 asc_board_t *boardp;
5996 int leftlen;
5997 int totlen;
5998 int len;
5999 int chip_scsi_id;
6000 int i;
6001
6002 boardp = ASC_BOARDP(shost);
6003 leftlen = cplen;
6004 totlen = len = 0;
6005
6006 len = asc_prt_line(cp, leftlen,
6007 "\nDevice Information for AdvanSys SCSI Host %d:\n",
6008 shost->host_no);
6009 ASC_PRT_NEXT();
6010
6011 if (ASC_NARROW_BOARD(boardp)) {
6012 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6013 } else {
6014 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6015 }
1da177e4 6016
27c868c2
MW
6017 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
6018 ASC_PRT_NEXT();
6019 for (i = 0; i <= ADV_MAX_TID; i++) {
6020 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
6021 len = asc_prt_line(cp, leftlen, " %X,", i);
6022 ASC_PRT_NEXT();
6023 }
6024 }
6025 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
6026 ASC_PRT_NEXT();
1da177e4 6027
27c868c2 6028 return totlen;
1da177e4
LT
6029}
6030
6031/*
6032 * Display Wide Board BIOS Information.
6033 */
27c868c2 6034static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6035{
27c868c2
MW
6036 asc_board_t *boardp;
6037 int leftlen;
6038 int totlen;
6039 int len;
6040 ushort major, minor, letter;
6041
6042 boardp = ASC_BOARDP(shost);
6043 leftlen = cplen;
6044 totlen = len = 0;
6045
6046 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
6047 ASC_PRT_NEXT();
6048
6049 /*
6050 * If the BIOS saved a valid signature, then fill in
6051 * the BIOS code segment base address.
6052 */
6053 if (boardp->bios_signature != 0x55AA) {
6054 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
6055 ASC_PRT_NEXT();
6056 len = asc_prt_line(cp, leftlen,
6057 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
6058 ASC_PRT_NEXT();
6059 len = asc_prt_line(cp, leftlen,
6060 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
6061 ASC_PRT_NEXT();
6062 } else {
6063 major = (boardp->bios_version >> 12) & 0xF;
6064 minor = (boardp->bios_version >> 8) & 0xF;
6065 letter = (boardp->bios_version & 0xFF);
1da177e4 6066
27c868c2
MW
6067 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
6068 major, minor,
6069 letter >= 26 ? '?' : letter + 'A');
6070 ASC_PRT_NEXT();
1da177e4 6071
27c868c2
MW
6072 /*
6073 * Current available ROM BIOS release is 3.1I for UW
6074 * and 3.2I for U2W. This code doesn't differentiate
6075 * UW and U2W boards.
6076 */
6077 if (major < 3 || (major <= 3 && minor < 1) ||
6078 (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
6079 len = asc_prt_line(cp, leftlen,
6080 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
6081 ASC_PRT_NEXT();
6082 len = asc_prt_line(cp, leftlen,
6083 "ftp://ftp.connectcom.net/pub\n");
6084 ASC_PRT_NEXT();
6085 }
6086 }
1da177e4 6087
27c868c2 6088 return totlen;
1da177e4
LT
6089}
6090
6091/*
6092 * Add serial number to information bar if signature AAh
6093 * is found in at bit 15-9 (7 bits) of word 1.
6094 *
6095 * Serial Number consists fo 12 alpha-numeric digits.
6096 *
6097 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
6098 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
6099 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
6100 * 5 - Product revision (A-J) Word0: " "
6101 *
6102 * Signature Word1: 15-9 (7 bits)
6103 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
6104 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
6105 *
6106 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
6107 *
6108 * Note 1: Only production cards will have a serial number.
6109 *
6110 * Note 2: Signature is most significant 7 bits (0xFE).
6111 *
6112 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
6113 */
27c868c2 6114static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
1da177e4 6115{
27c868c2
MW
6116 ushort w, num;
6117
6118 if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
6119 return ASC_FALSE;
6120 } else {
6121 /*
6122 * First word - 6 digits.
6123 */
6124 w = serialnum[0];
6125
6126 /* Product type - 1st digit. */
6127 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
6128 /* Product type is P=Prototype */
6129 *cp += 0x8;
6130 }
6131 cp++;
6132
6133 /* Manufacturing location - 2nd digit. */
6134 *cp++ = 'A' + ((w & 0x1C00) >> 10);
6135
6136 /* Product ID - 3rd, 4th digits. */
6137 num = w & 0x3FF;
6138 *cp++ = '0' + (num / 100);
6139 num %= 100;
6140 *cp++ = '0' + (num / 10);
6141
6142 /* Product revision - 5th digit. */
6143 *cp++ = 'A' + (num % 10);
6144
6145 /*
6146 * Second word
6147 */
6148 w = serialnum[1];
6149
6150 /*
6151 * Year - 6th digit.
6152 *
6153 * If bit 15 of third word is set, then the
6154 * last digit of the year is greater than 7.
6155 */
6156 if (serialnum[2] & 0x8000) {
6157 *cp++ = '8' + ((w & 0x1C0) >> 6);
6158 } else {
6159 *cp++ = '0' + ((w & 0x1C0) >> 6);
6160 }
6161
6162 /* Week of year - 7th, 8th digits. */
6163 num = w & 0x003F;
6164 *cp++ = '0' + num / 10;
6165 num %= 10;
6166 *cp++ = '0' + num;
6167
6168 /*
6169 * Third word
6170 */
6171 w = serialnum[2] & 0x7FFF;
6172
6173 /* Serial number - 9th digit. */
6174 *cp++ = 'A' + (w / 1000);
6175
6176 /* 10th, 11th, 12th digits. */
6177 num = w % 1000;
6178 *cp++ = '0' + num / 100;
6179 num %= 100;
6180 *cp++ = '0' + num / 10;
6181 num %= 10;
6182 *cp++ = '0' + num;
6183
6184 *cp = '\0'; /* Null Terminate the string. */
6185 return ASC_TRUE;
6186 }
1da177e4
LT
6187}
6188
6189/*
6190 * asc_prt_asc_board_eeprom()
6191 *
6192 * Print board EEPROM configuration.
6193 *
6194 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6195 * cf. asc_prt_line().
6196 *
6197 * Return the number of characters copied into 'cp'. No more than
6198 * 'cplen' characters will be copied to 'cp'.
6199 */
27c868c2 6200static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6201{
27c868c2
MW
6202 asc_board_t *boardp;
6203 ASC_DVC_VAR *asc_dvc_varp;
6204 int leftlen;
6205 int totlen;
6206 int len;
6207 ASCEEP_CONFIG *ep;
6208 int i;
1da177e4 6209#ifdef CONFIG_ISA
27c868c2 6210 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
1da177e4 6211#endif /* CONFIG_ISA */
27c868c2
MW
6212 uchar serialstr[13];
6213
6214 boardp = ASC_BOARDP(shost);
6215 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6216 ep = &boardp->eep_config.asc_eep;
6217
6218 leftlen = cplen;
6219 totlen = len = 0;
6220
6221 len = asc_prt_line(cp, leftlen,
6222 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6223 shost->host_no);
6224 ASC_PRT_NEXT();
6225
6226 if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
6227 == ASC_TRUE) {
6228 len =
6229 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6230 serialstr);
6231 ASC_PRT_NEXT();
6232 } else {
6233 if (ep->adapter_info[5] == 0xBB) {
6234 len = asc_prt_line(cp, leftlen,
6235 " Default Settings Used for EEPROM-less Adapter.\n");
6236 ASC_PRT_NEXT();
6237 } else {
6238 len = asc_prt_line(cp, leftlen,
6239 " Serial Number Signature Not Present.\n");
6240 ASC_PRT_NEXT();
6241 }
6242 }
1da177e4 6243
27c868c2
MW
6244 len = asc_prt_line(cp, leftlen,
6245 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6246 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
6247 ep->max_tag_qng);
6248 ASC_PRT_NEXT();
6249
6250 len = asc_prt_line(cp, leftlen,
6251 " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
6252 ASC_PRT_NEXT();
6253
6254 len = asc_prt_line(cp, leftlen, " Target ID: ");
6255 ASC_PRT_NEXT();
6256 for (i = 0; i <= ASC_MAX_TID; i++) {
6257 len = asc_prt_line(cp, leftlen, " %d", i);
6258 ASC_PRT_NEXT();
6259 }
6260 len = asc_prt_line(cp, leftlen, "\n");
6261 ASC_PRT_NEXT();
6262
6263 len = asc_prt_line(cp, leftlen, " Disconnects: ");
6264 ASC_PRT_NEXT();
6265 for (i = 0; i <= ASC_MAX_TID; i++) {
6266 len = asc_prt_line(cp, leftlen, " %c",
6267 (ep->
6268 disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6269 'N');
6270 ASC_PRT_NEXT();
6271 }
6272 len = asc_prt_line(cp, leftlen, "\n");
6273 ASC_PRT_NEXT();
6274
6275 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
6276 ASC_PRT_NEXT();
6277 for (i = 0; i <= ASC_MAX_TID; i++) {
6278 len = asc_prt_line(cp, leftlen, " %c",
6279 (ep->
6280 use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6281 'N');
6282 ASC_PRT_NEXT();
6283 }
6284 len = asc_prt_line(cp, leftlen, "\n");
6285 ASC_PRT_NEXT();
6286
6287 len = asc_prt_line(cp, leftlen, " Start Motor: ");
6288 ASC_PRT_NEXT();
6289 for (i = 0; i <= ASC_MAX_TID; i++) {
6290 len = asc_prt_line(cp, leftlen, " %c",
6291 (ep->
6292 start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6293 'N');
6294 ASC_PRT_NEXT();
6295 }
6296 len = asc_prt_line(cp, leftlen, "\n");
6297 ASC_PRT_NEXT();
6298
6299 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6300 ASC_PRT_NEXT();
6301 for (i = 0; i <= ASC_MAX_TID; i++) {
6302 len = asc_prt_line(cp, leftlen, " %c",
6303 (ep->
6304 init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6305 'N');
6306 ASC_PRT_NEXT();
6307 }
6308 len = asc_prt_line(cp, leftlen, "\n");
6309 ASC_PRT_NEXT();
1da177e4
LT
6310
6311#ifdef CONFIG_ISA
27c868c2
MW
6312 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
6313 len = asc_prt_line(cp, leftlen,
6314 " Host ISA DMA speed: %d MB/S\n",
6315 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
6316 ASC_PRT_NEXT();
6317 }
1da177e4
LT
6318#endif /* CONFIG_ISA */
6319
27c868c2 6320 return totlen;
1da177e4
LT
6321}
6322
6323/*
6324 * asc_prt_adv_board_eeprom()
6325 *
6326 * Print board EEPROM configuration.
6327 *
6328 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6329 * cf. asc_prt_line().
6330 *
6331 * Return the number of characters copied into 'cp'. No more than
6332 * 'cplen' characters will be copied to 'cp'.
6333 */
27c868c2 6334static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6335{
27c868c2
MW
6336 asc_board_t *boardp;
6337 ADV_DVC_VAR *adv_dvc_varp;
6338 int leftlen;
6339 int totlen;
6340 int len;
6341 int i;
6342 char *termstr;
6343 uchar serialstr[13];
6344 ADVEEP_3550_CONFIG *ep_3550 = NULL;
6345 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
6346 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
6347 ushort word;
6348 ushort *wordp;
6349 ushort sdtr_speed = 0;
6350
6351 boardp = ASC_BOARDP(shost);
6352 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6353 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6354 ep_3550 = &boardp->eep_config.adv_3550_eep;
6355 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6356 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
6357 } else {
6358 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
6359 }
1da177e4 6360
27c868c2
MW
6361 leftlen = cplen;
6362 totlen = len = 0;
1da177e4 6363
27c868c2
MW
6364 len = asc_prt_line(cp, leftlen,
6365 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6366 shost->host_no);
6367 ASC_PRT_NEXT();
1da177e4 6368
27c868c2
MW
6369 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6370 wordp = &ep_3550->serial_number_word1;
6371 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6372 wordp = &ep_38C0800->serial_number_word1;
6373 } else {
6374 wordp = &ep_38C1600->serial_number_word1;
6375 }
1da177e4 6376
27c868c2
MW
6377 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
6378 len =
6379 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6380 serialstr);
6381 ASC_PRT_NEXT();
6382 } else {
6383 len = asc_prt_line(cp, leftlen,
6384 " Serial Number Signature Not Present.\n");
6385 ASC_PRT_NEXT();
6386 }
1da177e4 6387
27c868c2
MW
6388 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6389 len = asc_prt_line(cp, leftlen,
6390 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6391 ep_3550->adapter_scsi_id,
6392 ep_3550->max_host_qng, ep_3550->max_dvc_qng);
6393 ASC_PRT_NEXT();
6394 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6395 len = asc_prt_line(cp, leftlen,
6396 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6397 ep_38C0800->adapter_scsi_id,
6398 ep_38C0800->max_host_qng,
6399 ep_38C0800->max_dvc_qng);
6400 ASC_PRT_NEXT();
6401 } else {
6402 len = asc_prt_line(cp, leftlen,
6403 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6404 ep_38C1600->adapter_scsi_id,
6405 ep_38C1600->max_host_qng,
6406 ep_38C1600->max_dvc_qng);
6407 ASC_PRT_NEXT();
6408 }
6409 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6410 word = ep_3550->termination;
6411 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6412 word = ep_38C0800->termination_lvd;
6413 } else {
6414 word = ep_38C1600->termination_lvd;
6415 }
6416 switch (word) {
6417 case 1:
6418 termstr = "Low Off/High Off";
6419 break;
6420 case 2:
6421 termstr = "Low Off/High On";
6422 break;
6423 case 3:
6424 termstr = "Low On/High On";
6425 break;
6426 default:
6427 case 0:
6428 termstr = "Automatic";
6429 break;
6430 }
1da177e4 6431
27c868c2
MW
6432 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6433 len = asc_prt_line(cp, leftlen,
6434 " termination: %u (%s), bios_ctrl: 0x%x\n",
6435 ep_3550->termination, termstr,
6436 ep_3550->bios_ctrl);
6437 ASC_PRT_NEXT();
6438 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6439 len = asc_prt_line(cp, leftlen,
6440 " termination: %u (%s), bios_ctrl: 0x%x\n",
6441 ep_38C0800->termination_lvd, termstr,
6442 ep_38C0800->bios_ctrl);
6443 ASC_PRT_NEXT();
6444 } else {
6445 len = asc_prt_line(cp, leftlen,
6446 " termination: %u (%s), bios_ctrl: 0x%x\n",
6447 ep_38C1600->termination_lvd, termstr,
6448 ep_38C1600->bios_ctrl);
6449 ASC_PRT_NEXT();
6450 }
1da177e4 6451
27c868c2
MW
6452 len = asc_prt_line(cp, leftlen, " Target ID: ");
6453 ASC_PRT_NEXT();
6454 for (i = 0; i <= ADV_MAX_TID; i++) {
6455 len = asc_prt_line(cp, leftlen, " %X", i);
6456 ASC_PRT_NEXT();
6457 }
6458 len = asc_prt_line(cp, leftlen, "\n");
6459 ASC_PRT_NEXT();
1da177e4 6460
27c868c2
MW
6461 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6462 word = ep_3550->disc_enable;
6463 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6464 word = ep_38C0800->disc_enable;
6465 } else {
6466 word = ep_38C1600->disc_enable;
6467 }
6468 len = asc_prt_line(cp, leftlen, " Disconnects: ");
6469 ASC_PRT_NEXT();
6470 for (i = 0; i <= ADV_MAX_TID; i++) {
6471 len = asc_prt_line(cp, leftlen, " %c",
6472 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6473 ASC_PRT_NEXT();
6474 }
6475 len = asc_prt_line(cp, leftlen, "\n");
6476 ASC_PRT_NEXT();
1da177e4 6477
27c868c2
MW
6478 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6479 word = ep_3550->tagqng_able;
6480 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6481 word = ep_38C0800->tagqng_able;
6482 } else {
6483 word = ep_38C1600->tagqng_able;
6484 }
6485 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
6486 ASC_PRT_NEXT();
6487 for (i = 0; i <= ADV_MAX_TID; i++) {
6488 len = asc_prt_line(cp, leftlen, " %c",
6489 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6490 ASC_PRT_NEXT();
6491 }
6492 len = asc_prt_line(cp, leftlen, "\n");
6493 ASC_PRT_NEXT();
6494
6495 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6496 word = ep_3550->start_motor;
6497 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6498 word = ep_38C0800->start_motor;
6499 } else {
6500 word = ep_38C1600->start_motor;
6501 }
6502 len = asc_prt_line(cp, leftlen, " Start Motor: ");
6503 ASC_PRT_NEXT();
6504 for (i = 0; i <= ADV_MAX_TID; i++) {
6505 len = asc_prt_line(cp, leftlen, " %c",
6506 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6507 ASC_PRT_NEXT();
6508 }
6509 len = asc_prt_line(cp, leftlen, "\n");
6510 ASC_PRT_NEXT();
6511
6512 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6513 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6514 ASC_PRT_NEXT();
6515 for (i = 0; i <= ADV_MAX_TID; i++) {
6516 len = asc_prt_line(cp, leftlen, " %c",
6517 (ep_3550->
6518 sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
6519 'Y' : 'N');
6520 ASC_PRT_NEXT();
6521 }
6522 len = asc_prt_line(cp, leftlen, "\n");
6523 ASC_PRT_NEXT();
6524 }
6525
6526 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6527 len = asc_prt_line(cp, leftlen, " Ultra Transfer: ");
6528 ASC_PRT_NEXT();
6529 for (i = 0; i <= ADV_MAX_TID; i++) {
6530 len = asc_prt_line(cp, leftlen, " %c",
6531 (ep_3550->
6532 ultra_able & ADV_TID_TO_TIDMASK(i))
6533 ? 'Y' : 'N');
6534 ASC_PRT_NEXT();
6535 }
6536 len = asc_prt_line(cp, leftlen, "\n");
6537 ASC_PRT_NEXT();
6538 }
6539
6540 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6541 word = ep_3550->wdtr_able;
6542 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6543 word = ep_38C0800->wdtr_able;
6544 } else {
6545 word = ep_38C1600->wdtr_able;
6546 }
6547 len = asc_prt_line(cp, leftlen, " Wide Transfer: ");
6548 ASC_PRT_NEXT();
6549 for (i = 0; i <= ADV_MAX_TID; i++) {
6550 len = asc_prt_line(cp, leftlen, " %c",
6551 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6552 ASC_PRT_NEXT();
6553 }
6554 len = asc_prt_line(cp, leftlen, "\n");
6555 ASC_PRT_NEXT();
6556
6557 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
6558 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
6559 len = asc_prt_line(cp, leftlen,
6560 " Synchronous Transfer Speed (Mhz):\n ");
6561 ASC_PRT_NEXT();
6562 for (i = 0; i <= ADV_MAX_TID; i++) {
6563 char *speed_str;
6564
6565 if (i == 0) {
6566 sdtr_speed = adv_dvc_varp->sdtr_speed1;
6567 } else if (i == 4) {
6568 sdtr_speed = adv_dvc_varp->sdtr_speed2;
6569 } else if (i == 8) {
6570 sdtr_speed = adv_dvc_varp->sdtr_speed3;
6571 } else if (i == 12) {
6572 sdtr_speed = adv_dvc_varp->sdtr_speed4;
6573 }
6574 switch (sdtr_speed & ADV_MAX_TID) {
6575 case 0:
6576 speed_str = "Off";
6577 break;
6578 case 1:
6579 speed_str = " 5";
6580 break;
6581 case 2:
6582 speed_str = " 10";
6583 break;
6584 case 3:
6585 speed_str = " 20";
6586 break;
6587 case 4:
6588 speed_str = " 40";
6589 break;
6590 case 5:
6591 speed_str = " 80";
6592 break;
6593 default:
6594 speed_str = "Unk";
6595 break;
6596 }
6597 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
6598 ASC_PRT_NEXT();
6599 if (i == 7) {
6600 len = asc_prt_line(cp, leftlen, "\n ");
6601 ASC_PRT_NEXT();
6602 }
6603 sdtr_speed >>= 4;
6604 }
6605 len = asc_prt_line(cp, leftlen, "\n");
6606 ASC_PRT_NEXT();
6607 }
6608
6609 return totlen;
6610}
6611
6612/*
6613 * asc_prt_driver_conf()
6614 *
6615 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6616 * cf. asc_prt_line().
1da177e4
LT
6617 *
6618 * Return the number of characters copied into 'cp'. No more than
6619 * 'cplen' characters will be copied to 'cp'.
6620 */
27c868c2 6621static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6622{
27c868c2
MW
6623 asc_board_t *boardp;
6624 int leftlen;
6625 int totlen;
6626 int len;
6627 int chip_scsi_id;
6628
6629 boardp = ASC_BOARDP(shost);
6630
6631 leftlen = cplen;
6632 totlen = len = 0;
6633
6634 len = asc_prt_line(cp, leftlen,
6635 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
6636 shost->host_no);
6637 ASC_PRT_NEXT();
6638
6639 len = asc_prt_line(cp, leftlen,
6640 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
6641 shost->host_busy, shost->last_reset, shost->max_id,
6642 shost->max_lun, shost->max_channel);
6643 ASC_PRT_NEXT();
6644
6645 len = asc_prt_line(cp, leftlen,
6646 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
6647 shost->unique_id, shost->can_queue, shost->this_id,
6648 shost->sg_tablesize, shost->cmd_per_lun);
6649 ASC_PRT_NEXT();
6650
6651 len = asc_prt_line(cp, leftlen,
6652 " unchecked_isa_dma %d, use_clustering %d\n",
6653 shost->unchecked_isa_dma, shost->use_clustering);
6654 ASC_PRT_NEXT();
6655
6656 len = asc_prt_line(cp, leftlen,
6657 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
6658 boardp->flags, boardp->last_reset, jiffies,
6659 boardp->asc_n_io_port);
6660 ASC_PRT_NEXT();
6661
4a2d31c8 6662 len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port);
27c868c2
MW
6663 ASC_PRT_NEXT();
6664
6665 if (ASC_NARROW_BOARD(boardp)) {
6666 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6667 } else {
6668 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6669 }
1da177e4 6670
27c868c2 6671 return totlen;
1da177e4
LT
6672}
6673
6674/*
6675 * asc_prt_asc_board_info()
6676 *
6677 * Print dynamic board configuration information.
6678 *
6679 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6680 * cf. asc_prt_line().
6681 *
6682 * Return the number of characters copied into 'cp'. No more than
6683 * 'cplen' characters will be copied to 'cp'.
6684 */
27c868c2 6685static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6686{
27c868c2
MW
6687 asc_board_t *boardp;
6688 int chip_scsi_id;
6689 int leftlen;
6690 int totlen;
6691 int len;
6692 ASC_DVC_VAR *v;
6693 ASC_DVC_CFG *c;
6694 int i;
6695 int renegotiate = 0;
6696
6697 boardp = ASC_BOARDP(shost);
6698 v = &boardp->dvc_var.asc_dvc_var;
6699 c = &boardp->dvc_cfg.asc_dvc_cfg;
6700 chip_scsi_id = c->chip_scsi_id;
6701
6702 leftlen = cplen;
6703 totlen = len = 0;
6704
6705 len = asc_prt_line(cp, leftlen,
6706 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6707 shost->host_no);
6708 ASC_PRT_NEXT();
6709
6710 len = asc_prt_line(cp, leftlen,
6711 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
6712 c->chip_version, c->lib_version, c->lib_serial_no,
6713 c->mcode_date);
6714 ASC_PRT_NEXT();
6715
6716 len = asc_prt_line(cp, leftlen,
6717 " mcode_version 0x%x, err_code %u\n",
6718 c->mcode_version, v->err_code);
6719 ASC_PRT_NEXT();
6720
6721 /* Current number of commands waiting for the host. */
6722 len = asc_prt_line(cp, leftlen,
6723 " Total Command Pending: %d\n", v->cur_total_qng);
6724 ASC_PRT_NEXT();
6725
6726 len = asc_prt_line(cp, leftlen, " Command Queuing:");
6727 ASC_PRT_NEXT();
6728 for (i = 0; i <= ASC_MAX_TID; i++) {
6729 if ((chip_scsi_id == i) ||
6730 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6731 continue;
6732 }
6733 len = asc_prt_line(cp, leftlen, " %X:%c",
6734 i,
6735 (v->
6736 use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
6737 'Y' : 'N');
6738 ASC_PRT_NEXT();
6739 }
6740 len = asc_prt_line(cp, leftlen, "\n");
6741 ASC_PRT_NEXT();
6742
6743 /* Current number of commands waiting for a device. */
6744 len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
6745 ASC_PRT_NEXT();
6746 for (i = 0; i <= ASC_MAX_TID; i++) {
6747 if ((chip_scsi_id == i) ||
6748 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6749 continue;
6750 }
6751 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
6752 ASC_PRT_NEXT();
6753 }
6754 len = asc_prt_line(cp, leftlen, "\n");
6755 ASC_PRT_NEXT();
6756
6757 /* Current limit on number of commands that can be sent to a device. */
6758 len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
6759 ASC_PRT_NEXT();
6760 for (i = 0; i <= ASC_MAX_TID; i++) {
6761 if ((chip_scsi_id == i) ||
6762 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6763 continue;
6764 }
6765 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
6766 ASC_PRT_NEXT();
6767 }
6768 len = asc_prt_line(cp, leftlen, "\n");
6769 ASC_PRT_NEXT();
6770
6771 /* Indicate whether the device has returned queue full status. */
6772 len = asc_prt_line(cp, leftlen, " Command Queue Full:");
6773 ASC_PRT_NEXT();
6774 for (i = 0; i <= ASC_MAX_TID; i++) {
6775 if ((chip_scsi_id == i) ||
6776 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6777 continue;
6778 }
6779 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
6780 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
6781 i, boardp->queue_full_cnt[i]);
6782 } else {
6783 len = asc_prt_line(cp, leftlen, " %X:N", i);
6784 }
6785 ASC_PRT_NEXT();
6786 }
6787 len = asc_prt_line(cp, leftlen, "\n");
6788 ASC_PRT_NEXT();
6789
6790 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6791 ASC_PRT_NEXT();
6792 for (i = 0; i <= ASC_MAX_TID; i++) {
6793 if ((chip_scsi_id == i) ||
6794 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6795 continue;
6796 }
6797 len = asc_prt_line(cp, leftlen, " %X:%c",
6798 i,
6799 (v->
6800 sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6801 'N');
6802 ASC_PRT_NEXT();
6803 }
6804 len = asc_prt_line(cp, leftlen, "\n");
6805 ASC_PRT_NEXT();
6806
6807 for (i = 0; i <= ASC_MAX_TID; i++) {
6808 uchar syn_period_ix;
6809
6810 if ((chip_scsi_id == i) ||
6811 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
6812 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
6813 continue;
6814 }
6815
6816 len = asc_prt_line(cp, leftlen, " %X:", i);
6817 ASC_PRT_NEXT();
6818
6819 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
6820 len = asc_prt_line(cp, leftlen, " Asynchronous");
6821 ASC_PRT_NEXT();
6822 } else {
6823 syn_period_ix =
6824 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
6825 1);
6826
6827 len = asc_prt_line(cp, leftlen,
6828 " Transfer Period Factor: %d (%d.%d Mhz),",
6829 v->sdtr_period_tbl[syn_period_ix],
6830 250 /
6831 v->sdtr_period_tbl[syn_period_ix],
6832 ASC_TENTHS(250,
6833 v->
6834 sdtr_period_tbl
6835 [syn_period_ix]));
6836 ASC_PRT_NEXT();
6837
6838 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
6839 boardp->
6840 sdtr_data[i] & ASC_SYN_MAX_OFFSET);
6841 ASC_PRT_NEXT();
6842 }
6843
6844 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
6845 len = asc_prt_line(cp, leftlen, "*\n");
6846 renegotiate = 1;
6847 } else {
6848 len = asc_prt_line(cp, leftlen, "\n");
6849 }
6850 ASC_PRT_NEXT();
6851 }
1da177e4 6852
27c868c2
MW
6853 if (renegotiate) {
6854 len = asc_prt_line(cp, leftlen,
6855 " * = Re-negotiation pending before next command.\n");
6856 ASC_PRT_NEXT();
6857 }
1da177e4 6858
27c868c2 6859 return totlen;
1da177e4
LT
6860}
6861
6862/*
6863 * asc_prt_adv_board_info()
6864 *
6865 * Print dynamic board configuration information.
6866 *
6867 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6868 * cf. asc_prt_line().
6869 *
6870 * Return the number of characters copied into 'cp'. No more than
6871 * 'cplen' characters will be copied to 'cp'.
6872 */
27c868c2 6873static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6874{
27c868c2
MW
6875 asc_board_t *boardp;
6876 int leftlen;
6877 int totlen;
6878 int len;
6879 int i;
6880 ADV_DVC_VAR *v;
6881 ADV_DVC_CFG *c;
6882 AdvPortAddr iop_base;
6883 ushort chip_scsi_id;
6884 ushort lramword;
6885 uchar lrambyte;
6886 ushort tagqng_able;
6887 ushort sdtr_able, wdtr_able;
6888 ushort wdtr_done, sdtr_done;
6889 ushort period = 0;
6890 int renegotiate = 0;
6891
6892 boardp = ASC_BOARDP(shost);
6893 v = &boardp->dvc_var.adv_dvc_var;
6894 c = &boardp->dvc_cfg.adv_dvc_cfg;
6895 iop_base = v->iop_base;
6896 chip_scsi_id = v->chip_scsi_id;
6897
6898 leftlen = cplen;
6899 totlen = len = 0;
6900
6901 len = asc_prt_line(cp, leftlen,
6902 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6903 shost->host_no);
6904 ASC_PRT_NEXT();
6905
6906 len = asc_prt_line(cp, leftlen,
6907 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
6908 v->iop_base,
6909 AdvReadWordRegister(iop_base,
6910 IOPW_SCSI_CFG1) & CABLE_DETECT,
6911 v->err_code);
6912 ASC_PRT_NEXT();
6913
6914 len = asc_prt_line(cp, leftlen,
6915 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
6916 c->chip_version, c->lib_version, c->mcode_date,
6917 c->mcode_version);
6918 ASC_PRT_NEXT();
6919
6920 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
6921 len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
6922 ASC_PRT_NEXT();
6923 for (i = 0; i <= ADV_MAX_TID; i++) {
6924 if ((chip_scsi_id == i) ||
6925 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6926 continue;
6927 }
6928
6929 len = asc_prt_line(cp, leftlen, " %X:%c",
6930 i,
6931 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6932 'N');
6933 ASC_PRT_NEXT();
6934 }
6935 len = asc_prt_line(cp, leftlen, "\n");
6936 ASC_PRT_NEXT();
6937
6938 len = asc_prt_line(cp, leftlen, " Queue Limit:");
6939 ASC_PRT_NEXT();
6940 for (i = 0; i <= ADV_MAX_TID; i++) {
6941 if ((chip_scsi_id == i) ||
6942 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6943 continue;
6944 }
6945
6946 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
6947 lrambyte);
6948
6949 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
6950 ASC_PRT_NEXT();
6951 }
6952 len = asc_prt_line(cp, leftlen, "\n");
6953 ASC_PRT_NEXT();
6954
6955 len = asc_prt_line(cp, leftlen, " Command Pending:");
6956 ASC_PRT_NEXT();
6957 for (i = 0; i <= ADV_MAX_TID; i++) {
6958 if ((chip_scsi_id == i) ||
6959 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6960 continue;
6961 }
6962
6963 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
6964 lrambyte);
6965
6966 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
6967 ASC_PRT_NEXT();
6968 }
6969 len = asc_prt_line(cp, leftlen, "\n");
6970 ASC_PRT_NEXT();
6971
6972 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
6973 len = asc_prt_line(cp, leftlen, " Wide Enabled:");
6974 ASC_PRT_NEXT();
6975 for (i = 0; i <= ADV_MAX_TID; i++) {
6976 if ((chip_scsi_id == i) ||
6977 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6978 continue;
6979 }
6980
6981 len = asc_prt_line(cp, leftlen, " %X:%c",
6982 i,
6983 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6984 'N');
6985 ASC_PRT_NEXT();
6986 }
6987 len = asc_prt_line(cp, leftlen, "\n");
6988 ASC_PRT_NEXT();
6989
6990 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
6991 len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
6992 ASC_PRT_NEXT();
6993 for (i = 0; i <= ADV_MAX_TID; i++) {
6994 if ((chip_scsi_id == i) ||
6995 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6996 continue;
6997 }
6998
6999 AdvReadWordLram(iop_base,
7000 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7001 lramword);
7002
7003 len = asc_prt_line(cp, leftlen, " %X:%d",
7004 i, (lramword & 0x8000) ? 16 : 8);
7005 ASC_PRT_NEXT();
7006
7007 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
7008 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7009 len = asc_prt_line(cp, leftlen, "*");
7010 ASC_PRT_NEXT();
7011 renegotiate = 1;
7012 }
7013 }
7014 len = asc_prt_line(cp, leftlen, "\n");
7015 ASC_PRT_NEXT();
7016
7017 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7018 len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
7019 ASC_PRT_NEXT();
7020 for (i = 0; i <= ADV_MAX_TID; i++) {
7021 if ((chip_scsi_id == i) ||
7022 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7023 continue;
7024 }
7025
7026 len = asc_prt_line(cp, leftlen, " %X:%c",
7027 i,
7028 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7029 'N');
7030 ASC_PRT_NEXT();
7031 }
7032 len = asc_prt_line(cp, leftlen, "\n");
7033 ASC_PRT_NEXT();
7034
7035 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
7036 for (i = 0; i <= ADV_MAX_TID; i++) {
7037
7038 AdvReadWordLram(iop_base,
7039 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7040 lramword);
7041 lramword &= ~0x8000;
7042
7043 if ((chip_scsi_id == i) ||
7044 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
7045 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
7046 continue;
7047 }
7048
7049 len = asc_prt_line(cp, leftlen, " %X:", i);
7050 ASC_PRT_NEXT();
7051
7052 if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */
7053 len = asc_prt_line(cp, leftlen, " Asynchronous");
7054 ASC_PRT_NEXT();
7055 } else {
7056 len =
7057 asc_prt_line(cp, leftlen,
7058 " Transfer Period Factor: ");
7059 ASC_PRT_NEXT();
7060
7061 if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */
7062 len =
7063 asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
7064 ASC_PRT_NEXT();
7065 } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */
7066 len =
7067 asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
7068 ASC_PRT_NEXT();
7069 } else { /* 20 Mhz or below. */
7070
7071 period = (((lramword >> 8) * 25) + 50) / 4;
7072
7073 if (period == 0) { /* Should never happen. */
7074 len =
7075 asc_prt_line(cp, leftlen,
7076 "%d (? Mhz), ");
7077 ASC_PRT_NEXT();
7078 } else {
7079 len = asc_prt_line(cp, leftlen,
7080 "%d (%d.%d Mhz),",
7081 period, 250 / period,
7082 ASC_TENTHS(250,
7083 period));
7084 ASC_PRT_NEXT();
7085 }
7086 }
7087
7088 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
7089 lramword & 0x1F);
7090 ASC_PRT_NEXT();
7091 }
7092
7093 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7094 len = asc_prt_line(cp, leftlen, "*\n");
7095 renegotiate = 1;
7096 } else {
7097 len = asc_prt_line(cp, leftlen, "\n");
7098 }
7099 ASC_PRT_NEXT();
7100 }
1da177e4 7101
27c868c2
MW
7102 if (renegotiate) {
7103 len = asc_prt_line(cp, leftlen,
7104 " * = Re-negotiation pending before next command.\n");
7105 ASC_PRT_NEXT();
7106 }
1da177e4 7107
27c868c2 7108 return totlen;
1da177e4
LT
7109}
7110
7111/*
7112 * asc_proc_copy()
7113 *
7114 * Copy proc information to a read buffer taking into account the current
7115 * read offset in the file and the remaining space in the read buffer.
7116 */
27c868c2 7117static int
1da177e4 7118asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
27c868c2 7119 char *cp, int cplen)
1da177e4 7120{
27c868c2
MW
7121 int cnt = 0;
7122
7123 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
7124 (unsigned)offset, (unsigned)advoffset, cplen);
7125 if (offset <= advoffset) {
7126 /* Read offset below current offset, copy everything. */
7127 cnt = min(cplen, leftlen);
7128 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7129 (ulong)curbuf, (ulong)cp, cnt);
7130 memcpy(curbuf, cp, cnt);
7131 } else if (offset < advoffset + cplen) {
7132 /* Read offset within current range, partial copy. */
7133 cnt = (advoffset + cplen) - offset;
7134 cp = (cp + cplen) - cnt;
7135 cnt = min(cnt, leftlen);
7136 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7137 (ulong)curbuf, (ulong)cp, cnt);
7138 memcpy(curbuf, cp, cnt);
7139 }
7140 return cnt;
1da177e4
LT
7141}
7142
7143/*
7144 * asc_prt_line()
7145 *
7146 * If 'cp' is NULL print to the console, otherwise print to a buffer.
7147 *
7148 * Return 0 if printing to the console, otherwise return the number of
7149 * bytes written to the buffer.
7150 *
7151 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
7152 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
7153 */
27c868c2 7154static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
1da177e4 7155{
27c868c2
MW
7156 va_list args;
7157 int ret;
7158 char s[ASC_PRTLINE_SIZE];
7159
7160 va_start(args, fmt);
7161 ret = vsprintf(s, fmt, args);
7162 ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
7163 if (buf == NULL) {
7164 (void)printk(s);
7165 ret = 0;
7166 } else {
7167 ret = min(buflen, ret);
7168 memcpy(buf, s, ret);
7169 }
7170 va_end(args);
7171 return ret;
1da177e4
LT
7172}
7173#endif /* CONFIG_PROC_FS */
7174
1da177e4
LT
7175/*
7176 * --- Functions Required by the Asc Library
7177 */
7178
7179/*
7180 * Delay for 'n' milliseconds. Don't use the 'jiffies'
7181 * global variable which is incremented once every 5 ms
7182 * from a timer interrupt, because this function may be
7183 * called when interrupts are disabled.
7184 */
27c868c2 7185static void DvcSleepMilliSecond(ADV_DCNT n)
1da177e4 7186{
27c868c2
MW
7187 ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong)n);
7188 mdelay(n);
1da177e4
LT
7189}
7190
7191/*
7192 * Currently and inline noop but leave as a placeholder.
7193 * Leave DvcEnterCritical() as a noop placeholder.
7194 */
27c868c2 7195static inline ulong DvcEnterCritical(void)
1da177e4 7196{
27c868c2 7197 return 0;
1da177e4
LT
7198}
7199
7200/*
7201 * Critical sections are all protected by the board spinlock.
7202 * Leave DvcLeaveCritical() as a noop placeholder.
7203 */
27c868c2 7204static inline void DvcLeaveCritical(ulong flags)
1da177e4 7205{
27c868c2 7206 return;
1da177e4
LT
7207}
7208
7209/*
7210 * void
7211 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7212 *
7213 * Calling/Exit State:
7214 * none
7215 *
7216 * Description:
7217 * Output an ASC_SCSI_Q structure to the chip
7218 */
27c868c2 7219static void
1da177e4
LT
7220DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7221{
27c868c2
MW
7222 int i;
7223
7224 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
7225 AscSetChipLramAddr(iop_base, s_addr);
7226 for (i = 0; i < 2 * words; i += 2) {
7227 if (i == 4 || i == 20) {
7228 continue;
7229 }
7230 outpw(iop_base + IOP_RAM_DATA,
7231 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
7232 }
1da177e4
LT
7233}
7234
7235/*
7236 * void
7237 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7238 *
7239 * Calling/Exit State:
7240 * none
7241 *
7242 * Description:
7243 * Input an ASC_QDONE_INFO structure from the chip
7244 */
27c868c2 7245static void
1da177e4
LT
7246DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7247{
27c868c2
MW
7248 int i;
7249 ushort word;
7250
7251 AscSetChipLramAddr(iop_base, s_addr);
7252 for (i = 0; i < 2 * words; i += 2) {
7253 if (i == 10) {
7254 continue;
7255 }
7256 word = inpw(iop_base + IOP_RAM_DATA);
7257 inbuf[i] = word & 0xff;
7258 inbuf[i + 1] = (word >> 8) & 0xff;
7259 }
7260 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
1da177e4
LT
7261}
7262
1da177e4
LT
7263/*
7264 * Return the BIOS address of the adapter at the specified
7265 * I/O port and with the specified bus type.
7266 */
ecec1947
MW
7267static unsigned short __devinit
7268AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type)
1da177e4 7269{
ecec1947
MW
7270 unsigned short cfg_lsw;
7271 unsigned short bios_addr;
27c868c2
MW
7272
7273 /*
7274 * The PCI BIOS is re-located by the motherboard BIOS. Because
7275 * of this the driver can not determine where a PCI BIOS is
7276 * loaded and executes.
7277 */
ecec1947
MW
7278 if (bus_type & ASC_IS_PCI)
7279 return 0;
7280
1da177e4 7281#ifdef CONFIG_ISA
27c868c2
MW
7282 if ((bus_type & ASC_IS_EISA) != 0) {
7283 cfg_lsw = AscGetEisaChipCfg(iop_base);
7284 cfg_lsw &= 0x000F;
ecec1947
MW
7285 bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
7286 return bios_addr;
7287 }
1da177e4
LT
7288#endif /* CONFIG_ISA */
7289
27c868c2 7290 cfg_lsw = AscGetChipCfgLsw(iop_base);
1da177e4 7291
27c868c2
MW
7292 /*
7293 * ISA PnP uses the top bit as the 32K BIOS flag
7294 */
ecec1947 7295 if (bus_type == ASC_IS_ISAPNP)
27c868c2 7296 cfg_lsw &= 0x7FFF;
ecec1947
MW
7297 bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
7298 return bios_addr;
1da177e4
LT
7299}
7300
1da177e4
LT
7301/*
7302 * --- Functions Required by the Adv Library
7303 */
7304
7305/*
7306 * DvcGetPhyAddr()
7307 *
7308 * Return the physical address of 'vaddr' and set '*lenp' to the
7309 * number of physically contiguous bytes that follow 'vaddr'.
7310 * 'flag' indicates the type of structure whose physical address
7311 * is being translated.
7312 *
7313 * Note: Because Linux currently doesn't page the kernel and all
7314 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
7315 */
7316ADV_PADDR
7317DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
27c868c2 7318 uchar *vaddr, ADV_SDCNT *lenp, int flag)
1da177e4 7319{
27c868c2 7320 ADV_PADDR paddr;
1da177e4 7321
27c868c2 7322 paddr = virt_to_bus(vaddr);
1da177e4 7323
27c868c2
MW
7324 ASC_DBG4(4,
7325 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
7326 (ulong)vaddr, (ulong)lenp, (ulong)*((ulong *)lenp),
7327 (ulong)paddr);
1da177e4 7328
27c868c2 7329 return paddr;
1da177e4
LT
7330}
7331
1da177e4
LT
7332/*
7333 * --- Tracing and Debugging Functions
7334 */
7335
7336#ifdef ADVANSYS_STATS
7337#ifdef CONFIG_PROC_FS
7338/*
7339 * asc_prt_board_stats()
7340 *
7341 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7342 * cf. asc_prt_line().
7343 *
7344 * Return the number of characters copied into 'cp'. No more than
7345 * 'cplen' characters will be copied to 'cp'.
7346 */
27c868c2 7347static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 7348{
27c868c2
MW
7349 int leftlen;
7350 int totlen;
7351 int len;
7352 struct asc_stats *s;
7353 asc_board_t *boardp;
1da177e4 7354
27c868c2
MW
7355 leftlen = cplen;
7356 totlen = len = 0;
7357
7358 boardp = ASC_BOARDP(shost);
7359 s = &boardp->asc_stats;
7360
7361 len = asc_prt_line(cp, leftlen,
7362 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
7363 shost->host_no);
7364 ASC_PRT_NEXT();
7365
7366 len = asc_prt_line(cp, leftlen,
7367 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
7368 s->queuecommand, s->reset, s->biosparam,
7369 s->interrupt);
7370 ASC_PRT_NEXT();
7371
7372 len = asc_prt_line(cp, leftlen,
7373 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
7374 s->callback, s->done, s->build_error,
7375 s->adv_build_noreq, s->adv_build_nosg);
7376 ASC_PRT_NEXT();
7377
7378 len = asc_prt_line(cp, leftlen,
7379 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
7380 s->exe_noerror, s->exe_busy, s->exe_error,
7381 s->exe_unknown);
7382 ASC_PRT_NEXT();
7383
7384 /*
7385 * Display data transfer statistics.
7386 */
7387 if (s->cont_cnt > 0) {
7388 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
7389 ASC_PRT_NEXT();
7390
7391 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
7392 s->cont_xfer / 2,
7393 ASC_TENTHS(s->cont_xfer, 2));
7394 ASC_PRT_NEXT();
7395
7396 /* Contiguous transfer average size */
7397 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
7398 (s->cont_xfer / 2) / s->cont_cnt,
7399 ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
7400 ASC_PRT_NEXT();
7401 }
1da177e4 7402
27c868c2 7403 if (s->sg_cnt > 0) {
1da177e4 7404
27c868c2
MW
7405 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
7406 s->sg_cnt, s->sg_elem);
7407 ASC_PRT_NEXT();
1da177e4 7408
27c868c2
MW
7409 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
7410 s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
7411 ASC_PRT_NEXT();
1da177e4 7412
27c868c2
MW
7413 /* Scatter gather transfer statistics */
7414 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
7415 s->sg_elem / s->sg_cnt,
7416 ASC_TENTHS(s->sg_elem, s->sg_cnt));
7417 ASC_PRT_NEXT();
1da177e4 7418
27c868c2
MW
7419 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
7420 (s->sg_xfer / 2) / s->sg_elem,
7421 ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
7422 ASC_PRT_NEXT();
1da177e4 7423
27c868c2
MW
7424 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
7425 (s->sg_xfer / 2) / s->sg_cnt,
7426 ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
7427 ASC_PRT_NEXT();
7428 }
1da177e4 7429
27c868c2
MW
7430 /*
7431 * Display request queuing statistics.
7432 */
7433 len = asc_prt_line(cp, leftlen,
7434 " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
7435 HZ);
7436 ASC_PRT_NEXT();
1da177e4 7437
27c868c2 7438 return totlen;
1da177e4
LT
7439}
7440
7441/*
7442 * asc_prt_target_stats()
7443 *
7444 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7445 * cf. asc_prt_line().
7446 *
7447 * This is separated from asc_prt_board_stats because a full set
7448 * of targets will overflow ASC_PRTBUF_SIZE.
7449 *
7450 * Return the number of characters copied into 'cp'. No more than
7451 * 'cplen' characters will be copied to 'cp'.
7452 */
27c868c2
MW
7453static int
7454asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen)
1da177e4 7455{
27c868c2
MW
7456 int leftlen;
7457 int totlen;
7458 int len;
7459 struct asc_stats *s;
7460 ushort chip_scsi_id;
7461 asc_board_t *boardp;
7462 asc_queue_t *active;
7463 asc_queue_t *waiting;
1da177e4 7464
27c868c2
MW
7465 leftlen = cplen;
7466 totlen = len = 0;
7467
7468 boardp = ASC_BOARDP(shost);
7469 s = &boardp->asc_stats;
7470
7471 active = &ASC_BOARDP(shost)->active;
7472 waiting = &ASC_BOARDP(shost)->waiting;
7473
7474 if (ASC_NARROW_BOARD(boardp)) {
7475 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7476 } else {
7477 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7478 }
7479
7480 if ((chip_scsi_id == tgt_id) ||
7481 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
7482 return 0;
7483 }
1da177e4 7484
27c868c2
MW
7485 do {
7486 if (active->q_tot_cnt[tgt_id] > 0
7487 || waiting->q_tot_cnt[tgt_id] > 0) {
7488 len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
7489 ASC_PRT_NEXT();
7490
7491 len = asc_prt_line(cp, leftlen,
7492 " active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
7493 active->q_cur_cnt[tgt_id],
7494 active->q_max_cnt[tgt_id],
7495 active->q_tot_cnt[tgt_id],
7496 active->q_min_tim[tgt_id],
7497 active->q_max_tim[tgt_id],
7498 (active->q_tot_cnt[tgt_id] ==
7499 0) ? 0 : (active->
7500 q_tot_tim[tgt_id] /
7501 active->
7502 q_tot_cnt[tgt_id]),
7503 (active->q_tot_cnt[tgt_id] ==
7504 0) ? 0 : ASC_TENTHS(active->
7505 q_tot_tim
7506 [tgt_id],
7507 active->
7508 q_tot_cnt
7509 [tgt_id]));
7510 ASC_PRT_NEXT();
7511
7512 len = asc_prt_line(cp, leftlen,
7513 " waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
7514 waiting->q_cur_cnt[tgt_id],
7515 waiting->q_max_cnt[tgt_id],
7516 waiting->q_tot_cnt[tgt_id],
7517 waiting->q_min_tim[tgt_id],
7518 waiting->q_max_tim[tgt_id],
7519 (waiting->q_tot_cnt[tgt_id] ==
7520 0) ? 0 : (waiting->
7521 q_tot_tim[tgt_id] /
7522 waiting->
7523 q_tot_cnt[tgt_id]),
7524 (waiting->q_tot_cnt[tgt_id] ==
7525 0) ? 0 : ASC_TENTHS(waiting->
7526 q_tot_tim
7527 [tgt_id],
7528 waiting->
7529 q_tot_cnt
7530 [tgt_id]));
7531 ASC_PRT_NEXT();
7532 }
7533 } while (0);
7534
7535 return totlen;
1da177e4
LT
7536}
7537#endif /* CONFIG_PROC_FS */
7538#endif /* ADVANSYS_STATS */
7539
7540#ifdef ADVANSYS_DEBUG
7541/*
7542 * asc_prt_scsi_host()
7543 */
27c868c2 7544static void asc_prt_scsi_host(struct Scsi_Host *s)
1da177e4 7545{
27c868c2
MW
7546 asc_board_t *boardp;
7547
7548 boardp = ASC_BOARDP(s);
7549
7550 printk("Scsi_Host at addr 0x%lx\n", (ulong)s);
7551 printk(" host_busy %u, host_no %d, last_reset %d,\n",
7552 s->host_busy, s->host_no, (unsigned)s->last_reset);
7553
4a2d31c8
MW
7554 printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n",
7555 (ulong)s->base, (ulong)s->io_port, s->irq);
27c868c2
MW
7556
7557 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
7558 s->dma_channel, s->this_id, s->can_queue);
7559
7560 printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
7561 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
7562
7563 if (ASC_NARROW_BOARD(boardp)) {
7564 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
7565 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
7566 } else {
7567 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
7568 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
7569 }
1da177e4
LT
7570}
7571
7572/*
7573 * asc_prt_scsi_cmnd()
7574 */
27c868c2 7575static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
1da177e4 7576{
27c868c2 7577 printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s);
1da177e4 7578
27c868c2
MW
7579 printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
7580 (ulong)s->device->host, (ulong)s->device, s->device->id,
7581 s->device->lun, s->device->channel);
1da177e4 7582
27c868c2 7583 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
1da177e4 7584
27c868c2
MW
7585 printk("sc_data_direction %u, resid %d\n",
7586 s->sc_data_direction, s->resid);
1da177e4 7587
27c868c2 7588 printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len);
1da177e4 7589
27c868c2
MW
7590 printk(" serial_number 0x%x, retries %d, allowed %d\n",
7591 (unsigned)s->serial_number, s->retries, s->allowed);
1da177e4 7592
27c868c2 7593 printk(" timeout_per_command %d\n", s->timeout_per_command);
1da177e4 7594
ecec1947
MW
7595 printk(" scsi_done 0x%p, done 0x%p, host_scribble 0x%p, result 0x%x\n",
7596 s->scsi_done, s->done, s->host_scribble, s->result);
1da177e4 7597
27c868c2 7598 printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
1da177e4
LT
7599}
7600
7601/*
7602 * asc_prt_asc_dvc_var()
7603 */
27c868c2 7604static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
1da177e4 7605{
27c868c2
MW
7606 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
7607
ecec1947
MW
7608 printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl "
7609 "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
27c868c2 7610
895d6b4c
MW
7611 printk(" bus_type %d, init_sdtr 0x%x,\n", h->bus_type,
7612 (unsigned)h->init_sdtr);
27c868c2 7613
ecec1947
MW
7614 printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, "
7615 "chip_no 0x%x,\n", (unsigned)h->sdtr_done,
7616 (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready,
7617 (unsigned)h->chip_no);
27c868c2 7618
ecec1947
MW
7619 printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait "
7620 "%u,\n", (unsigned)h->queue_full_or_busy,
7621 (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
27c868c2 7622
ecec1947
MW
7623 printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, "
7624 "in_critical_cnt %u,\n", (unsigned)h->is_in_int,
7625 (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng,
7626 (unsigned)h->in_critical_cnt);
27c868c2 7627
ecec1947
MW
7628 printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, "
7629 "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage,
7630 (unsigned)h->init_state, (unsigned)h->no_scam,
7631 (unsigned)h->pci_fix_asyn_xfer);
27c868c2
MW
7632
7633 printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no);
1da177e4
LT
7634}
7635
7636/*
7637 * asc_prt_asc_dvc_cfg()
7638 */
27c868c2 7639static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
1da177e4 7640{
27c868c2
MW
7641 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
7642
7643 printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
7644 h->can_tagged_qng, h->cmd_qng_enabled);
7645 printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
7646 h->disc_enable, h->sdtr_enable);
7647
7648 printk
7649 (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
7650 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
7651 h->chip_version);
7652
7653 printk
7654 (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
7655 to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
7656 h->mcode_date);
7657
7658 printk(" mcode_version %d, overrun_buf 0x%lx\n",
7659 h->mcode_version, (ulong)h->overrun_buf);
1da177e4
LT
7660}
7661
7662/*
7663 * asc_prt_asc_scsi_q()
7664 */
27c868c2 7665static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
1da177e4 7666{
27c868c2
MW
7667 ASC_SG_HEAD *sgp;
7668 int i;
7669
7670 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
7671
7672 printk
7673 (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
7674 q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
7675 q->q2.tag_code);
7676
7677 printk
7678 (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7679 (ulong)le32_to_cpu(q->q1.data_addr),
7680 (ulong)le32_to_cpu(q->q1.data_cnt),
7681 (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
7682
7683 printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
7684 (ulong)q->cdbptr, q->q2.cdb_len,
7685 (ulong)q->sg_head, q->q1.sg_queue_cnt);
7686
7687 if (q->sg_head) {
7688 sgp = q->sg_head;
7689 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
7690 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
7691 sgp->queue_cnt);
7692 for (i = 0; i < sgp->entry_cnt; i++) {
7693 printk(" [%u]: addr 0x%lx, bytes %lu\n",
7694 i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
7695 (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
7696 }
1da177e4 7697
27c868c2 7698 }
1da177e4
LT
7699}
7700
7701/*
7702 * asc_prt_asc_qdone_info()
7703 */
27c868c2 7704static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
1da177e4 7705{
27c868c2
MW
7706 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
7707 printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
7708 (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
7709 q->d2.tag_code);
7710 printk
7711 (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
7712 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
1da177e4
LT
7713}
7714
7715/*
7716 * asc_prt_adv_dvc_var()
7717 *
7718 * Display an ADV_DVC_VAR structure.
7719 */
27c868c2 7720static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
1da177e4 7721{
27c868c2
MW
7722 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
7723
7724 printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
7725 (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
7726
7727 printk(" isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
7728 (ulong)h->isr_callback, (unsigned)h->sdtr_able,
7729 (unsigned)h->wdtr_able);
7730
7731 printk(" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
7732 (unsigned)h->start_motor,
7733 (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no);
7734
7735 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
7736 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
7737 (ulong)h->carr_freelist);
7738
7739 printk(" icq_sp 0x%lx, irq_sp 0x%lx\n",
7740 (ulong)h->icq_sp, (ulong)h->irq_sp);
7741
7742 printk(" no_scam 0x%x, tagqng_able 0x%x\n",
7743 (unsigned)h->no_scam, (unsigned)h->tagqng_able);
7744
7745 printk(" chip_scsi_id 0x%x, cfg 0x%lx\n",
7746 (unsigned)h->chip_scsi_id, (ulong)h->cfg);
1da177e4
LT
7747}
7748
7749/*
7750 * asc_prt_adv_dvc_cfg()
7751 *
7752 * Display an ADV_DVC_CFG structure.
7753 */
27c868c2 7754static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
1da177e4 7755{
27c868c2 7756 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
1da177e4 7757
27c868c2
MW
7758 printk(" disc_enable 0x%x, termination 0x%x\n",
7759 h->disc_enable, h->termination);
1da177e4 7760
27c868c2
MW
7761 printk(" chip_version 0x%x, mcode_date 0x%x\n",
7762 h->chip_version, h->mcode_date);
1da177e4 7763
27c868c2
MW
7764 printk(" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
7765 h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
1da177e4 7766
27c868c2
MW
7767 printk(" control_flag 0x%x, pci_slot_info 0x%x\n",
7768 h->control_flag, h->pci_slot_info);
1da177e4
LT
7769}
7770
7771/*
7772 * asc_prt_adv_scsi_req_q()
7773 *
7774 * Display an ADV_SCSI_REQ_Q structure.
7775 */
27c868c2 7776static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
1da177e4 7777{
27c868c2
MW
7778 int sg_blk_cnt;
7779 struct asc_sg_block *sg_ptr;
7780
7781 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
7782
7783 printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
7784 q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
7785
7786 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
7787 q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
7788
7789 printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7790 (ulong)le32_to_cpu(q->data_cnt),
7791 (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
7792
7793 printk
7794 (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
7795 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
7796
7797 printk(" sg_working_ix 0x%x, target_cmd %u\n",
7798 q->sg_working_ix, q->target_cmd);
7799
7800 printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
7801 (ulong)le32_to_cpu(q->scsiq_rptr),
7802 (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
7803
7804 /* Display the request's ADV_SG_BLOCK structures. */
7805 if (q->sg_list_ptr != NULL) {
7806 sg_blk_cnt = 0;
7807 while (1) {
7808 /*
7809 * 'sg_ptr' is a physical address. Convert it to a virtual
7810 * address by indexing 'sg_blk_cnt' into the virtual address
7811 * array 'sg_list_ptr'.
7812 *
7813 * XXX - Assumes all SG physical blocks are virtually contiguous.
7814 */
7815 sg_ptr =
7816 &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
7817 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
7818 if (sg_ptr->sg_ptr == 0) {
7819 break;
7820 }
7821 sg_blk_cnt++;
7822 }
7823 }
1da177e4
LT
7824}
7825
7826/*
7827 * asc_prt_adv_sgblock()
7828 *
7829 * Display an ADV_SG_BLOCK structure.
7830 */
27c868c2 7831static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
1da177e4 7832{
27c868c2
MW
7833 int i;
7834
7835 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
7836 (ulong)b, sgblockno);
7837 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
7838 b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
7839 ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
7840 if (b->sg_ptr != 0) {
7841 ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
7842 }
7843 for (i = 0; i < b->sg_cnt; i++) {
7844 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
7845 i, (ulong)b->sg_list[i].sg_addr,
7846 (ulong)b->sg_list[i].sg_count);
7847 }
1da177e4
LT
7848}
7849
7850/*
7851 * asc_prt_hex()
7852 *
7853 * Print hexadecimal output in 4 byte groupings 32 bytes
7854 * or 8 double-words per line.
7855 */
27c868c2 7856static void asc_prt_hex(char *f, uchar *s, int l)
1da177e4 7857{
27c868c2
MW
7858 int i;
7859 int j;
7860 int k;
7861 int m;
7862
7863 printk("%s: (%d bytes)\n", f, l);
7864
7865 for (i = 0; i < l; i += 32) {
7866
7867 /* Display a maximum of 8 double-words per line. */
7868 if ((k = (l - i) / 4) >= 8) {
7869 k = 8;
7870 m = 0;
7871 } else {
7872 m = (l - i) % 4;
7873 }
7874
7875 for (j = 0; j < k; j++) {
7876 printk(" %2.2X%2.2X%2.2X%2.2X",
7877 (unsigned)s[i + (j * 4)],
7878 (unsigned)s[i + (j * 4) + 1],
7879 (unsigned)s[i + (j * 4) + 2],
7880 (unsigned)s[i + (j * 4) + 3]);
7881 }
7882
7883 switch (m) {
7884 case 0:
7885 default:
7886 break;
7887 case 1:
7888 printk(" %2.2X", (unsigned)s[i + (j * 4)]);
7889 break;
7890 case 2:
7891 printk(" %2.2X%2.2X",
7892 (unsigned)s[i + (j * 4)],
7893 (unsigned)s[i + (j * 4) + 1]);
7894 break;
7895 case 3:
7896 printk(" %2.2X%2.2X%2.2X",
7897 (unsigned)s[i + (j * 4) + 1],
7898 (unsigned)s[i + (j * 4) + 2],
7899 (unsigned)s[i + (j * 4) + 3]);
7900 break;
7901 }
7902
7903 printk("\n");
7904 }
1da177e4
LT
7905}
7906#endif /* ADVANSYS_DEBUG */
7907
7908/*
7909 * --- Asc Library Functions
7910 */
7911
78e77d8b 7912static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
1da177e4 7913{
27c868c2 7914 PortAddr eisa_cfg_iop;
1da177e4 7915
27c868c2
MW
7916 eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
7917 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
7918 return (inpw(eisa_cfg_iop));
1da177e4
LT
7919}
7920
78e77d8b 7921static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
1da177e4 7922{
27c868c2 7923 ushort cfg_lsw;
1da177e4 7924
27c868c2
MW
7925 if (AscGetChipScsiID(iop_base) == new_host_id) {
7926 return (new_host_id);
7927 }
7928 cfg_lsw = AscGetChipCfgLsw(iop_base);
7929 cfg_lsw &= 0xF8FF;
7930 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
7931 AscSetChipCfgLsw(iop_base, cfg_lsw);
7932 return (AscGetChipScsiID(iop_base));
1da177e4
LT
7933}
7934
ecec1947 7935static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base)
1da177e4 7936{
ecec1947 7937 unsigned char sc;
1da177e4 7938
27c868c2
MW
7939 AscSetBank(iop_base, 1);
7940 sc = inp(iop_base + IOP_REG_SC);
7941 AscSetBank(iop_base, 0);
ecec1947 7942 return sc;
1da177e4
LT
7943}
7944
ecec1947
MW
7945static unsigned char __devinit
7946AscGetChipVersion(PortAddr iop_base, unsigned short bus_type)
1da177e4 7947{
ecec1947 7948 if (bus_type & ASC_IS_EISA) {
27c868c2 7949 PortAddr eisa_iop;
ecec1947 7950 unsigned char revision;
27c868c2
MW
7951 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
7952 (PortAddr) ASC_EISA_REV_IOP_MASK;
7953 revision = inp(eisa_iop);
ecec1947 7954 return ASC_CHIP_MIN_VER_EISA - 1 + revision;
27c868c2 7955 }
ecec1947 7956 return AscGetChipVerNo(iop_base);
1da177e4
LT
7957}
7958
27c868c2
MW
7959static ASC_DCNT
7960AscLoadMicroCode(PortAddr iop_base,
7961 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
1da177e4 7962{
27c868c2
MW
7963 ASC_DCNT chksum;
7964 ushort mcode_word_size;
7965 ushort mcode_chksum;
7966
7967 /* Write the microcode buffer starting at LRAM address 0. */
7968 mcode_word_size = (ushort)(mcode_size >> 1);
7969 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
7970 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
7971
7972 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
7973 ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum);
7974 mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
7975 (ushort)ASC_CODE_SEC_BEG,
7976 (ushort)((mcode_size -
7977 s_addr - (ushort)
7978 ASC_CODE_SEC_BEG) /
7979 2));
7980 ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
7981 (ulong)mcode_chksum);
7982 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
7983 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
7984 return (chksum);
1da177e4
LT
7985}
7986
27c868c2 7987static int AscFindSignature(PortAddr iop_base)
1da177e4 7988{
27c868c2
MW
7989 ushort sig_word;
7990
7991 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
7992 iop_base, AscGetChipSignatureByte(iop_base));
7993 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
7994 ASC_DBG2(1,
7995 "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
7996 iop_base, AscGetChipSignatureWord(iop_base));
7997 sig_word = AscGetChipSignatureWord(iop_base);
7998 if ((sig_word == (ushort)ASC_1000_ID0W) ||
7999 (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
8000 return (1);
8001 }
8002 }
8003 return (0);
1da177e4
LT
8004}
8005
78e77d8b 8006static void __devinit AscToggleIRQAct(PortAddr iop_base)
1da177e4 8007{
27c868c2
MW
8008 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
8009 AscSetChipStatus(iop_base, 0);
8010 return;
1da177e4
LT
8011}
8012
78e77d8b 8013static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
1da177e4 8014{
27c868c2
MW
8015 ushort cfg_lsw;
8016 uchar chip_irq;
8017
8018 if ((bus_type & ASC_IS_EISA) != 0) {
8019 cfg_lsw = AscGetEisaChipCfg(iop_base);
8020 chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10);
8021 if ((chip_irq == 13) || (chip_irq > 15)) {
8022 return (0);
8023 }
8024 return (chip_irq);
8025 }
8026 if ((bus_type & ASC_IS_VL) != 0) {
8027 cfg_lsw = AscGetChipCfgLsw(iop_base);
8028 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07));
8029 if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) {
8030 return (0);
8031 }
8032 return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1)));
8033 }
8034 cfg_lsw = AscGetChipCfgLsw(iop_base);
8035 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03));
8036 if (chip_irq == 3)
8037 chip_irq += (uchar)2;
8038 return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
1da177e4
LT
8039}
8040
78e77d8b 8041static uchar __devinit
27c868c2 8042AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
1da177e4 8043{
27c868c2
MW
8044 ushort cfg_lsw;
8045
8046 if ((bus_type & ASC_IS_VL) != 0) {
8047 if (irq_no != 0) {
8048 if ((irq_no < ASC_MIN_IRQ_NO)
8049 || (irq_no > ASC_MAX_IRQ_NO)) {
8050 irq_no = 0;
8051 } else {
8052 irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1));
8053 }
8054 }
8055 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3);
8056 cfg_lsw |= (ushort)0x0010;
8057 AscSetChipCfgLsw(iop_base, cfg_lsw);
8058 AscToggleIRQAct(iop_base);
8059 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0);
8060 cfg_lsw |= (ushort)((irq_no & 0x07) << 2);
8061 AscSetChipCfgLsw(iop_base, cfg_lsw);
8062 AscToggleIRQAct(iop_base);
8063 return (AscGetChipIRQ(iop_base, bus_type));
8064 }
8065 if ((bus_type & (ASC_IS_ISA)) != 0) {
8066 if (irq_no == 15)
8067 irq_no -= (uchar)2;
8068 irq_no -= (uchar)ASC_MIN_IRQ_NO;
8069 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3);
8070 cfg_lsw |= (ushort)((irq_no & 0x03) << 2);
8071 AscSetChipCfgLsw(iop_base, cfg_lsw);
8072 return (AscGetChipIRQ(iop_base, bus_type));
8073 }
8074 return (0);
1da177e4
LT
8075}
8076
8077#ifdef CONFIG_ISA
78e77d8b 8078static void __devinit AscEnableIsaDma(uchar dma_channel)
1da177e4 8079{
27c868c2
MW
8080 if (dma_channel < 4) {
8081 outp(0x000B, (ushort)(0xC0 | dma_channel));
8082 outp(0x000A, dma_channel);
8083 } else if (dma_channel < 8) {
8084 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
8085 outp(0x00D4, (ushort)(dma_channel - 4));
8086 }
8087 return;
1da177e4
LT
8088}
8089#endif /* CONFIG_ISA */
8090
27c868c2 8091static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
1da177e4 8092{
27c868c2
MW
8093 EXT_MSG ext_msg;
8094 EXT_MSG out_msg;
8095 ushort halt_q_addr;
8096 int sdtr_accept;
8097 ushort int_halt_code;
8098 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8099 ASC_SCSI_BIT_ID_TYPE target_id;
8100 PortAddr iop_base;
8101 uchar tag_code;
8102 uchar q_status;
8103 uchar halt_qp;
8104 uchar sdtr_data;
8105 uchar target_ix;
8106 uchar q_cntl, tid_no;
8107 uchar cur_dvc_qng;
8108 uchar asyn_sdtr;
8109 uchar scsi_status;
8110 asc_board_t *boardp;
8111
8112 ASC_ASSERT(asc_dvc->drv_ptr != NULL);
8113 boardp = asc_dvc->drv_ptr;
8114
8115 iop_base = asc_dvc->iop_base;
8116 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
8117
8118 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
8119 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
8120 target_ix = AscReadLramByte(iop_base,
8121 (ushort)(halt_q_addr +
8122 (ushort)ASC_SCSIQ_B_TARGET_IX));
8123 q_cntl =
8124 AscReadLramByte(iop_base,
8125 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8126 tid_no = ASC_TIX_TO_TID(target_ix);
8127 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
8128 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8129 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
8130 } else {
8131 asyn_sdtr = 0;
8132 }
8133 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
8134 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8135 AscSetChipSDTR(iop_base, 0, tid_no);
8136 boardp->sdtr_data[tid_no] = 0;
8137 }
8138 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8139 return (0);
8140 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
8141 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8142 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8143 boardp->sdtr_data[tid_no] = asyn_sdtr;
8144 }
8145 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8146 return (0);
8147 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
8148
8149 AscMemWordCopyPtrFromLram(iop_base,
8150 ASCV_MSGIN_BEG,
8151 (uchar *)&ext_msg,
8152 sizeof(EXT_MSG) >> 1);
8153
47d853cc
MW
8154 if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8155 ext_msg.msg_req == EXTENDED_SDTR &&
27c868c2
MW
8156 ext_msg.msg_len == MS_SDTR_LEN) {
8157 sdtr_accept = TRUE;
8158 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
8159
8160 sdtr_accept = FALSE;
8161 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
8162 }
8163 if ((ext_msg.xfer_period <
8164 asc_dvc->sdtr_period_tbl[asc_dvc->
8165 host_init_sdtr_index])
8166 || (ext_msg.xfer_period >
8167 asc_dvc->sdtr_period_tbl[asc_dvc->
8168 max_sdtr_index])) {
8169 sdtr_accept = FALSE;
8170 ext_msg.xfer_period =
8171 asc_dvc->sdtr_period_tbl[asc_dvc->
8172 host_init_sdtr_index];
8173 }
8174 if (sdtr_accept) {
8175 sdtr_data =
8176 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
8177 ext_msg.req_ack_offset);
8178 if ((sdtr_data == 0xFF)) {
8179
8180 q_cntl |= QC_MSG_OUT;
8181 asc_dvc->init_sdtr &= ~target_id;
8182 asc_dvc->sdtr_done &= ~target_id;
8183 AscSetChipSDTR(iop_base, asyn_sdtr,
8184 tid_no);
8185 boardp->sdtr_data[tid_no] = asyn_sdtr;
8186 }
8187 }
8188 if (ext_msg.req_ack_offset == 0) {
8189
8190 q_cntl &= ~QC_MSG_OUT;
8191 asc_dvc->init_sdtr &= ~target_id;
8192 asc_dvc->sdtr_done &= ~target_id;
8193 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8194 } else {
8195 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
8196
8197 q_cntl &= ~QC_MSG_OUT;
8198 asc_dvc->sdtr_done |= target_id;
8199 asc_dvc->init_sdtr |= target_id;
8200 asc_dvc->pci_fix_asyn_xfer &=
8201 ~target_id;
8202 sdtr_data =
8203 AscCalSDTRData(asc_dvc,
8204 ext_msg.xfer_period,
8205 ext_msg.
8206 req_ack_offset);
8207 AscSetChipSDTR(iop_base, sdtr_data,
8208 tid_no);
8209 boardp->sdtr_data[tid_no] = sdtr_data;
8210 } else {
8211
8212 q_cntl |= QC_MSG_OUT;
8213 AscMsgOutSDTR(asc_dvc,
8214 ext_msg.xfer_period,
8215 ext_msg.req_ack_offset);
8216 asc_dvc->pci_fix_asyn_xfer &=
8217 ~target_id;
8218 sdtr_data =
8219 AscCalSDTRData(asc_dvc,
8220 ext_msg.xfer_period,
8221 ext_msg.
8222 req_ack_offset);
8223 AscSetChipSDTR(iop_base, sdtr_data,
8224 tid_no);
8225 boardp->sdtr_data[tid_no] = sdtr_data;
8226 asc_dvc->sdtr_done |= target_id;
8227 asc_dvc->init_sdtr |= target_id;
8228 }
8229 }
8230
8231 AscWriteLramByte(iop_base,
8232 (ushort)(halt_q_addr +
8233 (ushort)ASC_SCSIQ_B_CNTL),
8234 q_cntl);
8235 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8236 return (0);
47d853cc
MW
8237 } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8238 ext_msg.msg_req == EXTENDED_WDTR &&
27c868c2
MW
8239 ext_msg.msg_len == MS_WDTR_LEN) {
8240
8241 ext_msg.wdtr_width = 0;
8242 AscMemWordCopyPtrToLram(iop_base,
8243 ASCV_MSGOUT_BEG,
8244 (uchar *)&ext_msg,
8245 sizeof(EXT_MSG) >> 1);
8246 q_cntl |= QC_MSG_OUT;
8247 AscWriteLramByte(iop_base,
8248 (ushort)(halt_q_addr +
8249 (ushort)ASC_SCSIQ_B_CNTL),
8250 q_cntl);
8251 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8252 return (0);
8253 } else {
8254
8255 ext_msg.msg_type = MESSAGE_REJECT;
8256 AscMemWordCopyPtrToLram(iop_base,
8257 ASCV_MSGOUT_BEG,
8258 (uchar *)&ext_msg,
8259 sizeof(EXT_MSG) >> 1);
8260 q_cntl |= QC_MSG_OUT;
8261 AscWriteLramByte(iop_base,
8262 (ushort)(halt_q_addr +
8263 (ushort)ASC_SCSIQ_B_CNTL),
8264 q_cntl);
8265 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8266 return (0);
8267 }
8268 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
8269
8270 q_cntl |= QC_REQ_SENSE;
8271
8272 if ((asc_dvc->init_sdtr & target_id) != 0) {
8273
8274 asc_dvc->sdtr_done &= ~target_id;
8275
8276 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8277 q_cntl |= QC_MSG_OUT;
8278 AscMsgOutSDTR(asc_dvc,
8279 asc_dvc->
8280 sdtr_period_tbl[(sdtr_data >> 4) &
8281 (uchar)(asc_dvc->
8282 max_sdtr_index -
8283 1)],
8284 (uchar)(sdtr_data & (uchar)
8285 ASC_SYN_MAX_OFFSET));
8286 }
8287
8288 AscWriteLramByte(iop_base,
8289 (ushort)(halt_q_addr +
8290 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8291
8292 tag_code = AscReadLramByte(iop_base,
8293 (ushort)(halt_q_addr + (ushort)
8294 ASC_SCSIQ_B_TAG_CODE));
8295 tag_code &= 0xDC;
8296 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
8297 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
8298 ) {
8299
8300 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
8301 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
8302
8303 }
8304 AscWriteLramByte(iop_base,
8305 (ushort)(halt_q_addr +
8306 (ushort)ASC_SCSIQ_B_TAG_CODE),
8307 tag_code);
8308
8309 q_status = AscReadLramByte(iop_base,
8310 (ushort)(halt_q_addr + (ushort)
8311 ASC_SCSIQ_B_STATUS));
8312 q_status |= (QS_READY | QS_BUSY);
8313 AscWriteLramByte(iop_base,
8314 (ushort)(halt_q_addr +
8315 (ushort)ASC_SCSIQ_B_STATUS),
8316 q_status);
8317
8318 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
8319 scsi_busy &= ~target_id;
8320 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8321
8322 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8323 return (0);
8324 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
8325
8326 AscMemWordCopyPtrFromLram(iop_base,
8327 ASCV_MSGOUT_BEG,
8328 (uchar *)&out_msg,
8329 sizeof(EXT_MSG) >> 1);
8330
47d853cc 8331 if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
27c868c2 8332 (out_msg.msg_len == MS_SDTR_LEN) &&
47d853cc 8333 (out_msg.msg_req == EXTENDED_SDTR)) {
27c868c2
MW
8334
8335 asc_dvc->init_sdtr &= ~target_id;
8336 asc_dvc->sdtr_done &= ~target_id;
8337 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8338 boardp->sdtr_data[tid_no] = asyn_sdtr;
8339 }
8340 q_cntl &= ~QC_MSG_OUT;
8341 AscWriteLramByte(iop_base,
8342 (ushort)(halt_q_addr +
8343 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8344 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8345 return (0);
8346 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
8347
8348 scsi_status = AscReadLramByte(iop_base,
8349 (ushort)((ushort)halt_q_addr +
8350 (ushort)
8351 ASC_SCSIQ_SCSI_STATUS));
8352 cur_dvc_qng =
8353 AscReadLramByte(iop_base,
8354 (ushort)((ushort)ASC_QADR_BEG +
8355 (ushort)target_ix));
8356 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
8357
8358 scsi_busy = AscReadLramByte(iop_base,
8359 (ushort)ASCV_SCSIBUSY_B);
8360 scsi_busy |= target_id;
8361 AscWriteLramByte(iop_base,
8362 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8363 asc_dvc->queue_full_or_busy |= target_id;
8364
8365 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
8366 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
8367 cur_dvc_qng -= 1;
8368 asc_dvc->max_dvc_qng[tid_no] =
8369 cur_dvc_qng;
8370
8371 AscWriteLramByte(iop_base,
8372 (ushort)((ushort)
8373 ASCV_MAX_DVC_QNG_BEG
8374 + (ushort)
8375 tid_no),
8376 cur_dvc_qng);
8377
8378 /*
8379 * Set the device queue depth to the number of
8380 * active requests when the QUEUE FULL condition
8381 * was encountered.
8382 */
8383 boardp->queue_full |= target_id;
8384 boardp->queue_full_cnt[tid_no] =
8385 cur_dvc_qng;
8386 }
8387 }
8388 }
8389 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8390 return (0);
8391 }
1da177e4 8392#if CC_VERY_LONG_SG_LIST
27c868c2
MW
8393 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
8394 uchar q_no;
8395 ushort q_addr;
8396 uchar sg_wk_q_no;
8397 uchar first_sg_wk_q_no;
8398 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
8399 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
8400 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
8401 ushort sg_list_dwords;
8402 ushort sg_entry_cnt;
8403 uchar next_qp;
8404 int i;
8405
8406 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
8407 if (q_no == ASC_QLINK_END) {
8408 return (0);
8409 }
8410
8411 q_addr = ASC_QNO_TO_QADDR(q_no);
8412
8413 /*
8414 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
8415 * structure pointer using a macro provided by the driver.
8416 * The ASC_SCSI_REQ pointer provides a pointer to the
8417 * host ASC_SG_HEAD structure.
8418 */
8419 /* Read request's SRB pointer. */
8420 scsiq = (ASC_SCSI_Q *)
8421 ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
8422 (ushort)
8423 (q_addr +
8424 ASC_SCSIQ_D_SRBPTR))));
8425
8426 /*
8427 * Get request's first and working SG queue.
8428 */
8429 sg_wk_q_no = AscReadLramByte(iop_base,
8430 (ushort)(q_addr +
8431 ASC_SCSIQ_B_SG_WK_QP));
8432
8433 first_sg_wk_q_no = AscReadLramByte(iop_base,
8434 (ushort)(q_addr +
8435 ASC_SCSIQ_B_FIRST_SG_WK_QP));
8436
8437 /*
8438 * Reset request's working SG queue back to the
8439 * first SG queue.
8440 */
8441 AscWriteLramByte(iop_base,
8442 (ushort)(q_addr +
8443 (ushort)ASC_SCSIQ_B_SG_WK_QP),
8444 first_sg_wk_q_no);
8445
8446 sg_head = scsiq->sg_head;
8447
8448 /*
8449 * Set sg_entry_cnt to the number of SG elements
8450 * that will be completed on this interrupt.
8451 *
8452 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
8453 * SG elements. The data_cnt and data_addr fields which
8454 * add 1 to the SG element capacity are not used when
8455 * restarting SG handling after a halt.
8456 */
8457 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
8458 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
8459
8460 /*
8461 * Keep track of remaining number of SG elements that will
8462 * need to be handled on the next interrupt.
8463 */
8464 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
8465 } else {
8466 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
8467 scsiq->remain_sg_entry_cnt = 0;
8468 }
8469
8470 /*
8471 * Copy SG elements into the list of allocated SG queues.
8472 *
8473 * Last index completed is saved in scsiq->next_sg_index.
8474 */
8475 next_qp = first_sg_wk_q_no;
8476 q_addr = ASC_QNO_TO_QADDR(next_qp);
8477 scsi_sg_q.sg_head_qp = q_no;
8478 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
8479 for (i = 0; i < sg_head->queue_cnt; i++) {
8480 scsi_sg_q.seq_no = i + 1;
8481 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
8482 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
8483 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
8484 /*
8485 * After very first SG queue RISC FW uses next
8486 * SG queue first element then checks sg_list_cnt
8487 * against zero and then decrements, so set
8488 * sg_list_cnt 1 less than number of SG elements
8489 * in each SG queue.
8490 */
8491 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
8492 scsi_sg_q.sg_cur_list_cnt =
8493 ASC_SG_LIST_PER_Q - 1;
8494 } else {
8495 /*
8496 * This is the last SG queue in the list of
8497 * allocated SG queues. If there are more
8498 * SG elements than will fit in the allocated
8499 * queues, then set the QCSG_SG_XFER_MORE flag.
8500 */
8501 if (scsiq->remain_sg_entry_cnt != 0) {
8502 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
8503 } else {
8504 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
8505 }
8506 /* equals sg_entry_cnt * 2 */
8507 sg_list_dwords = sg_entry_cnt << 1;
8508 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
8509 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
8510 sg_entry_cnt = 0;
8511 }
8512
8513 scsi_sg_q.q_no = next_qp;
8514 AscMemWordCopyPtrToLram(iop_base,
8515 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
8516 (uchar *)&scsi_sg_q,
8517 sizeof(ASC_SG_LIST_Q) >> 1);
8518
8519 AscMemDWordCopyPtrToLram(iop_base,
8520 q_addr + ASC_SGQ_LIST_BEG,
8521 (uchar *)&sg_head->
8522 sg_list[scsiq->next_sg_index],
8523 sg_list_dwords);
8524
8525 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
8526
8527 /*
8528 * If the just completed SG queue contained the
8529 * last SG element, then no more SG queues need
8530 * to be written.
8531 */
8532 if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
8533 break;
8534 }
8535
8536 next_qp = AscReadLramByte(iop_base,
8537 (ushort)(q_addr +
8538 ASC_SCSIQ_B_FWD));
8539 q_addr = ASC_QNO_TO_QADDR(next_qp);
8540 }
8541
8542 /*
8543 * Clear the halt condition so the RISC will be restarted
8544 * after the return.
8545 */
8546 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8547 return (0);
8548 }
1da177e4 8549#endif /* CC_VERY_LONG_SG_LIST */
27c868c2 8550 return (0);
1da177e4
LT
8551}
8552
27c868c2
MW
8553static uchar
8554_AscCopyLramScsiDoneQ(PortAddr iop_base,
8555 ushort q_addr,
8556 ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
1da177e4 8557{
27c868c2
MW
8558 ushort _val;
8559 uchar sg_queue_cnt;
8560
8561 DvcGetQinfo(iop_base,
8562 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
8563 (uchar *)scsiq,
8564 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
8565
8566 _val = AscReadLramWord(iop_base,
8567 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
8568 scsiq->q_status = (uchar)_val;
8569 scsiq->q_no = (uchar)(_val >> 8);
8570 _val = AscReadLramWord(iop_base,
8571 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8572 scsiq->cntl = (uchar)_val;
8573 sg_queue_cnt = (uchar)(_val >> 8);
8574 _val = AscReadLramWord(iop_base,
8575 (ushort)(q_addr +
8576 (ushort)ASC_SCSIQ_B_SENSE_LEN));
8577 scsiq->sense_len = (uchar)_val;
8578 scsiq->extra_bytes = (uchar)(_val >> 8);
8579
8580 /*
8581 * Read high word of remain bytes from alternate location.
8582 */
8583 scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
8584 (ushort)(q_addr +
8585 (ushort)
8586 ASC_SCSIQ_W_ALT_DC1)))
8587 << 16);
8588 /*
8589 * Read low word of remain bytes from original location.
8590 */
8591 scsiq->remain_bytes += AscReadLramWord(iop_base,
8592 (ushort)(q_addr + (ushort)
8593 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
8594
8595 scsiq->remain_bytes &= max_dma_count;
8596 return (sg_queue_cnt);
1da177e4
LT
8597}
8598
27c868c2 8599static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
1da177e4 8600{
27c868c2
MW
8601 uchar next_qp;
8602 uchar n_q_used;
8603 uchar sg_list_qp;
8604 uchar sg_queue_cnt;
8605 uchar q_cnt;
8606 uchar done_q_tail;
8607 uchar tid_no;
8608 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8609 ASC_SCSI_BIT_ID_TYPE target_id;
8610 PortAddr iop_base;
8611 ushort q_addr;
8612 ushort sg_q_addr;
8613 uchar cur_target_qng;
8614 ASC_QDONE_INFO scsiq_buf;
8615 ASC_QDONE_INFO *scsiq;
8616 int false_overrun;
27c868c2
MW
8617
8618 iop_base = asc_dvc->iop_base;
27c868c2
MW
8619 n_q_used = 1;
8620 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
8621 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
8622 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
8623 next_qp = AscReadLramByte(iop_base,
8624 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
8625 if (next_qp != ASC_QLINK_END) {
8626 AscPutVarDoneQTail(iop_base, next_qp);
8627 q_addr = ASC_QNO_TO_QADDR(next_qp);
8628 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
8629 asc_dvc->max_dma_count);
8630 AscWriteLramByte(iop_base,
8631 (ushort)(q_addr +
8632 (ushort)ASC_SCSIQ_B_STATUS),
8633 (uchar)(scsiq->
8634 q_status & (uchar)~(QS_READY |
8635 QS_ABORTED)));
8636 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
8637 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
8638 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
8639 sg_q_addr = q_addr;
8640 sg_list_qp = next_qp;
8641 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
8642 sg_list_qp = AscReadLramByte(iop_base,
8643 (ushort)(sg_q_addr
8644 + (ushort)
8645 ASC_SCSIQ_B_FWD));
8646 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
8647 if (sg_list_qp == ASC_QLINK_END) {
8648 AscSetLibErrorCode(asc_dvc,
8649 ASCQ_ERR_SG_Q_LINKS);
8650 scsiq->d3.done_stat = QD_WITH_ERROR;
8651 scsiq->d3.host_stat =
8652 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
8653 goto FATAL_ERR_QDONE;
8654 }
8655 AscWriteLramByte(iop_base,
8656 (ushort)(sg_q_addr + (ushort)
8657 ASC_SCSIQ_B_STATUS),
8658 QS_FREE);
8659 }
8660 n_q_used = sg_queue_cnt + 1;
8661 AscPutVarDoneQTail(iop_base, sg_list_qp);
8662 }
8663 if (asc_dvc->queue_full_or_busy & target_id) {
8664 cur_target_qng = AscReadLramByte(iop_base,
8665 (ushort)((ushort)
8666 ASC_QADR_BEG
8667 + (ushort)
8668 scsiq->d2.
8669 target_ix));
8670 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
8671 scsi_busy = AscReadLramByte(iop_base, (ushort)
8672 ASCV_SCSIBUSY_B);
8673 scsi_busy &= ~target_id;
8674 AscWriteLramByte(iop_base,
8675 (ushort)ASCV_SCSIBUSY_B,
8676 scsi_busy);
8677 asc_dvc->queue_full_or_busy &= ~target_id;
8678 }
8679 }
8680 if (asc_dvc->cur_total_qng >= n_q_used) {
8681 asc_dvc->cur_total_qng -= n_q_used;
8682 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
8683 asc_dvc->cur_dvc_qng[tid_no]--;
8684 }
8685 } else {
8686 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
8687 scsiq->d3.done_stat = QD_WITH_ERROR;
8688 goto FATAL_ERR_QDONE;
8689 }
8690 if ((scsiq->d2.srb_ptr == 0UL) ||
8691 ((scsiq->q_status & QS_ABORTED) != 0)) {
8692 return (0x11);
8693 } else if (scsiq->q_status == QS_DONE) {
8694 false_overrun = FALSE;
8695 if (scsiq->extra_bytes != 0) {
8696 scsiq->remain_bytes +=
8697 (ADV_DCNT)scsiq->extra_bytes;
8698 }
8699 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
8700 if (scsiq->d3.host_stat ==
8701 QHSTA_M_DATA_OVER_RUN) {
8702 if ((scsiq->
8703 cntl & (QC_DATA_IN | QC_DATA_OUT))
8704 == 0) {
8705 scsiq->d3.done_stat =
8706 QD_NO_ERROR;
8707 scsiq->d3.host_stat =
8708 QHSTA_NO_ERROR;
8709 } else if (false_overrun) {
8710 scsiq->d3.done_stat =
8711 QD_NO_ERROR;
8712 scsiq->d3.host_stat =
8713 QHSTA_NO_ERROR;
8714 }
8715 } else if (scsiq->d3.host_stat ==
8716 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
8717 AscStopChip(iop_base);
8718 AscSetChipControl(iop_base,
8719 (uchar)(CC_SCSI_RESET
8720 | CC_HALT));
8721 DvcDelayNanoSecond(asc_dvc, 60000);
8722 AscSetChipControl(iop_base, CC_HALT);
8723 AscSetChipStatus(iop_base,
8724 CIW_CLR_SCSI_RESET_INT);
8725 AscSetChipStatus(iop_base, 0);
8726 AscSetChipControl(iop_base, 0);
8727 }
8728 }
8729 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
895d6b4c 8730 asc_isr_callback(asc_dvc, scsiq);
27c868c2
MW
8731 } else {
8732 if ((AscReadLramByte(iop_base,
8733 (ushort)(q_addr + (ushort)
8734 ASC_SCSIQ_CDB_BEG))
8735 == START_STOP)) {
8736 asc_dvc->unit_not_ready &= ~target_id;
8737 if (scsiq->d3.done_stat != QD_NO_ERROR) {
8738 asc_dvc->start_motor &=
8739 ~target_id;
8740 }
8741 }
8742 }
8743 return (1);
8744 } else {
8745 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
8746 FATAL_ERR_QDONE:
8747 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
895d6b4c 8748 asc_isr_callback(asc_dvc, scsiq);
27c868c2
MW
8749 }
8750 return (0x80);
8751 }
8752 }
8753 return (0);
1da177e4
LT
8754}
8755
27c868c2 8756static int AscISR(ASC_DVC_VAR *asc_dvc)
1da177e4 8757{
27c868c2
MW
8758 ASC_CS_TYPE chipstat;
8759 PortAddr iop_base;
8760 ushort saved_ram_addr;
8761 uchar ctrl_reg;
8762 uchar saved_ctrl_reg;
8763 int int_pending;
8764 int status;
8765 uchar host_flag;
8766
8767 iop_base = asc_dvc->iop_base;
8768 int_pending = FALSE;
8769
8770 if (AscIsIntPending(iop_base) == 0) {
8771 return int_pending;
8772 }
1da177e4 8773
895d6b4c 8774 if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) {
27c868c2
MW
8775 return (ERR);
8776 }
8777 if (asc_dvc->in_critical_cnt != 0) {
8778 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
8779 return (ERR);
8780 }
8781 if (asc_dvc->is_in_int) {
8782 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
8783 return (ERR);
8784 }
8785 asc_dvc->is_in_int = TRUE;
8786 ctrl_reg = AscGetChipControl(iop_base);
8787 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
8788 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
8789 chipstat = AscGetChipStatus(iop_base);
8790 if (chipstat & CSW_SCSI_RESET_LATCH) {
8791 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
8792 int i = 10;
8793 int_pending = TRUE;
8794 asc_dvc->sdtr_done = 0;
8795 saved_ctrl_reg &= (uchar)(~CC_HALT);
8796 while ((AscGetChipStatus(iop_base) &
8797 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
8798 DvcSleepMilliSecond(100);
8799 }
8800 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
8801 AscSetChipControl(iop_base, CC_HALT);
8802 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
8803 AscSetChipStatus(iop_base, 0);
8804 chipstat = AscGetChipStatus(iop_base);
8805 }
8806 }
8807 saved_ram_addr = AscGetChipLramAddr(iop_base);
8808 host_flag = AscReadLramByte(iop_base,
8809 ASCV_HOST_FLAG_B) &
8810 (uchar)(~ASC_HOST_FLAG_IN_ISR);
8811 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
8812 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
8813 if ((chipstat & CSW_INT_PENDING)
8814 || (int_pending)
8815 ) {
8816 AscAckInterrupt(iop_base);
8817 int_pending = TRUE;
8818 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
8819 if (AscIsrChipHalted(asc_dvc) == ERR) {
8820 goto ISR_REPORT_QDONE_FATAL_ERROR;
8821 } else {
8822 saved_ctrl_reg &= (uchar)(~CC_HALT);
8823 }
8824 } else {
8825 ISR_REPORT_QDONE_FATAL_ERROR:
8826 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
8827 while (((status =
8828 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
8829 }
8830 } else {
8831 do {
8832 if ((status =
8833 AscIsrQDone(asc_dvc)) == 1) {
8834 break;
8835 }
8836 } while (status == 0x11);
8837 }
8838 if ((status & 0x80) != 0)
8839 int_pending = ERR;
8840 }
8841 }
8842 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
8843 AscSetChipLramAddr(iop_base, saved_ram_addr);
8844 AscSetChipControl(iop_base, saved_ctrl_reg);
8845 asc_dvc->is_in_int = FALSE;
8846 return (int_pending);
1da177e4
LT
8847}
8848
8849/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
8850static uchar _asc_mcode_buf[] = {
8851 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8852 0x00, 0x00, 0x00, 0x00,
8853 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00,
8854 0x00, 0x00, 0x00, 0x00,
8855 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8856 0x00, 0x00, 0x00, 0x00,
8857 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8858 0x00, 0x00, 0x00, 0x00,
8859 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00,
8860 0x00, 0xFF, 0x00, 0x00,
8861 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00,
8862 0x00, 0x00, 0x00, 0x00,
8863 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
8864 0x00, 0x00, 0x00, 0x00,
8865 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88,
8866 0x00, 0x00, 0x00, 0x00,
8867 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73,
8868 0x03, 0x23, 0x36, 0x40,
8869 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
8870 0xC2, 0x00, 0x92, 0x80,
8871 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60,
8872 0xB6, 0x00, 0x92, 0x80,
8873 0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00,
8874 0x92, 0x80, 0x80, 0x62,
8875 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
8876 0xCD, 0x04, 0x4D, 0x00,
8877 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01,
8878 0xE6, 0x84, 0xD2, 0xC1,
8879 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97,
8880 0xC6, 0x81, 0xC2, 0x88,
8881 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
8882 0x84, 0x97, 0x07, 0xA6,
8883 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE,
8884 0xC2, 0x88, 0xCE, 0x00,
8885 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01,
8886 0x80, 0x63, 0x07, 0xA6,
8887 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
8888 0x34, 0x01, 0x00, 0x33,
8889 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23,
8890 0x68, 0x98, 0x4D, 0x04,
8891 0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23,
8892 0xF8, 0x88, 0xFB, 0x23,
8893 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
8894 0x00, 0x33, 0x0A, 0x00,
8895 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00,
8896 0xC2, 0x88, 0xCD, 0x04,
8897 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81,
8898 0x06, 0xAB, 0x82, 0x01,
8899 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
8900 0x3C, 0x01, 0x00, 0x05,
8901 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01,
8902 0x15, 0x23, 0xA1, 0x01,
8903 0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00,
8904 0x06, 0x61, 0x00, 0xA0,
8905 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
8906 0xC2, 0x88, 0x06, 0x23,
8907 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01,
8908 0x57, 0x60, 0x00, 0xA0,
8909 0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73,
8910 0x4B, 0x00, 0x06, 0x61,
8911 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
8912 0x4F, 0x00, 0x84, 0x97,
8913 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97,
8914 0x48, 0x04, 0x84, 0x80,
8915 0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00,
8916 0x81, 0x73, 0x06, 0x29,
8917 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
8918 0x04, 0x98, 0xF0, 0x80,
8919 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6,
8920 0x34, 0x02, 0x03, 0xA6,
8921 0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96,
8922 0x46, 0x82, 0xFE, 0x95,
8923 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
8924 0x07, 0xA6, 0x5A, 0x02,
8925 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95,
8926 0x48, 0x82, 0x60, 0x96,
8927 0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84,
8928 0x04, 0x01, 0x0C, 0xDC,
8929 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
8930 0x6F, 0x00, 0xA5, 0x01,
8931 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01,
8932 0x02, 0xA6, 0xAA, 0x02,
8933 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04,
8934 0x01, 0xA6, 0xB4, 0x02,
8935 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
8936 0x80, 0x63, 0x00, 0x43,
8937 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23,
8938 0x04, 0x61, 0x84, 0x01,
8939 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F,
8940 0x00, 0x00, 0xEA, 0x82,
8941 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
8942 0x00, 0x33, 0x1F, 0x00,
8943 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98,
8944 0xB6, 0x2D, 0x01, 0xA6,
8945 0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6,
8946 0x10, 0x03, 0x03, 0xA6,
8947 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
8948 0x7C, 0x95, 0xEE, 0x82,
8949 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4,
8950 0x04, 0x01, 0x2D, 0xC8,
8951 0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01,
8952 0x05, 0x05, 0x86, 0x98,
8953 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
8954 0x3C, 0x04, 0x06, 0xA6,
8955 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88,
8956 0x7C, 0x95, 0x32, 0x83,
8957 0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05,
8958 0xEB, 0x04, 0x00, 0x33,
8959 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
8960 0xFF, 0xA2, 0x7A, 0x03,
8961 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01,
8962 0x00, 0xA2, 0x9A, 0x03,
8963 0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00,
8964 0x01, 0xA6, 0x96, 0x03,
8965 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
8966 0xA4, 0x03, 0x00, 0xA6,
8967 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03,
8968 0x07, 0xA6, 0xB2, 0x03,
8969 0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88,
8970 0xA8, 0x98, 0x80, 0x42,
8971 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
8972 0xC0, 0x83, 0x00, 0x33,
8973 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23,
8974 0xA0, 0x01, 0x12, 0x23,
8975 0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B,
8976 0x80, 0x67, 0x05, 0x23,
8977 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
8978 0x06, 0xA6, 0x0A, 0x04,
8979 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96,
8980 0xF4, 0x83, 0x20, 0x84,
8981 0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
8982 0x83, 0x03, 0x80, 0x63,
8983 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
8984 0x38, 0x04, 0x00, 0x33,
8985 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84,
8986 0x1D, 0x01, 0x06, 0xCC,
8987 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62,
8988 0xA2, 0x0D, 0x80, 0x63,
8989 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
8990 0x80, 0x63, 0xA3, 0x01,
8991 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0,
8992 0x76, 0x04, 0xE0, 0x00,
8993 0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00,
8994 0x00, 0x33, 0x1E, 0x00,
8995 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
8996 0x08, 0x23, 0x22, 0xA3,
8997 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3,
8998 0xC4, 0x04, 0x42, 0x23,
8999 0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23,
9000 0xF8, 0x88, 0x04, 0x98,
9001 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
9002 0x81, 0x62, 0xE8, 0x81,
9003 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98,
9004 0x00, 0x33, 0x00, 0x81,
9005 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23,
9006 0xF8, 0x88, 0x04, 0x23,
9007 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
9008 0xF4, 0x04, 0x00, 0x33,
9009 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01,
9010 0x04, 0x23, 0xA0, 0x01,
9011 0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00,
9012 0x00, 0xA3, 0x22, 0x05,
9013 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
9014 0x46, 0x97, 0xCD, 0x04,
9015 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23,
9016 0x82, 0x01, 0x34, 0x85,
9017 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05,
9018 0x1D, 0x01, 0x04, 0xD6,
9019 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
9020 0x49, 0x00, 0x81, 0x01,
9021 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01,
9022 0x49, 0x04, 0x80, 0x01,
9023 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04,
9024 0x01, 0x23, 0xEA, 0x00,
9025 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
9026 0x07, 0xA4, 0xF8, 0x05,
9027 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00,
9028 0xC2, 0x88, 0x04, 0xA0,
9029 0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61,
9030 0x00, 0xA2, 0xA4, 0x05,
9031 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
9032 0x62, 0x97, 0x04, 0x85,
9033 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05,
9034 0xF4, 0x85, 0x03, 0xA0,
9035 0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63,
9036 0xCC, 0x86, 0x07, 0xA0,
9037 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
9038 0x80, 0x67, 0x80, 0x63,
9039 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23,
9040 0xF8, 0x88, 0x07, 0x23,
9041 0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00,
9042 0x00, 0x63, 0x4A, 0x00,
9043 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
9044 0x07, 0x41, 0x83, 0x03,
9045 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88,
9046 0x1D, 0x01, 0x01, 0xD6,
9047 0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00,
9048 0x07, 0xA6, 0x7C, 0x05,
9049 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
9050 0x52, 0x00, 0x06, 0x61,
9051 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41,
9052 0x00, 0x63, 0x1D, 0x01,
9053 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23,
9054 0x07, 0x41, 0x00, 0x63,
9055 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
9056 0xDF, 0x00, 0x06, 0xA6,
9057 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33,
9058 0x00, 0x40, 0xC0, 0x20,
9059 0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63,
9060 0x06, 0xA6, 0x94, 0x06,
9061 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
9062 0x40, 0x0E, 0x80, 0x63,
9063 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E,
9064 0x80, 0x63, 0x00, 0x43,
9065 0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05,
9066 0x80, 0x67, 0x40, 0x0E,
9067 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
9068 0x07, 0xA6, 0xD6, 0x06,
9069 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00,
9070 0x0A, 0x2B, 0x07, 0xA6,
9071 0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2,
9072 0xF4, 0x06, 0xC0, 0x0E,
9073 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
9074 0x81, 0x62, 0x04, 0x01,
9075 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6,
9076 0x8C, 0x06, 0x00, 0x33,
9077 0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03,
9078 0x80, 0x63, 0x06, 0xA6,
9079 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
9080 0x00, 0x00, 0x80, 0x67,
9081 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05,
9082 0xBF, 0x23, 0x04, 0x61,
9083 0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00,
9084 0x00, 0x01, 0xF2, 0x00,
9085 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
9086 0x80, 0x05, 0x81, 0x05,
9087 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00,
9088 0x70, 0x00, 0x81, 0x01,
9089 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04,
9090 0x70, 0x00, 0x80, 0x01,
9091 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
9092 0xF1, 0x00, 0x70, 0x00,
9093 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01,
9094 0x71, 0x04, 0x70, 0x00,
9095 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05,
9096 0xA3, 0x01, 0xA2, 0x01,
9097 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
9098 0xC4, 0x07, 0x00, 0x33,
9099 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8,
9100 0x48, 0x00, 0xB0, 0x01,
9101 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43,
9102 0x00, 0xA2, 0xE4, 0x07,
9103 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
9104 0x05, 0x05, 0x00, 0x63,
9105 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43,
9106 0x76, 0x08, 0x80, 0x02,
9107 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
9108 0x00, 0x02, 0x00, 0xA0,
9109 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
9110 0x00, 0x63, 0xF3, 0x04,
9111 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40,
9112 0x00, 0xA2, 0x44, 0x08,
9113 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1,
9114 0x24, 0x08, 0x04, 0x98,
9115 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
9116 0x5A, 0x88, 0x02, 0x01,
9117 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00,
9118 0x00, 0xA3, 0x64, 0x08,
9119 0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63,
9120 0x06, 0xA6, 0x76, 0x08,
9121 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
9122 0x00, 0x63, 0x38, 0x2B,
9123 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98,
9124 0x05, 0x05, 0xB2, 0x09,
9125 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63,
9126 0x80, 0x32, 0x80, 0x36,
9127 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
9128 0x40, 0x36, 0x40, 0x3A,
9129 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08,
9130 0x5D, 0x00, 0xFE, 0xC3,
9131 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73,
9132 0xFF, 0xFD, 0x80, 0x73,
9133 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
9134 0xA1, 0x23, 0xA1, 0x01,
9135 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2,
9136 0x80, 0x00, 0x03, 0xC2,
9137 0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23,
9138 0xA0, 0x01, 0xE6, 0x84,
1da177e4
LT
9139};
9140
27c868c2
MW
9141static ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
9142static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
1da177e4
LT
9143
9144#define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
27c868c2
MW
9145static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
9146 INQUIRY,
9147 REQUEST_SENSE,
9148 READ_CAPACITY,
9149 READ_TOC,
9150 MODE_SELECT,
9151 MODE_SENSE,
9152 MODE_SELECT_10,
9153 MODE_SENSE_10,
9154 0xFF,
9155 0xFF,
9156 0xFF,
9157 0xFF,
9158 0xFF,
9159 0xFF,
9160 0xFF,
9161 0xFF
1da177e4
LT
9162};
9163
27c868c2 9164static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
1da177e4 9165{
27c868c2
MW
9166 PortAddr iop_base;
9167 ulong last_int_level;
9168 int sta;
9169 int n_q_required;
9170 int disable_syn_offset_one_fix;
9171 int i;
9172 ASC_PADDR addr;
27c868c2
MW
9173 ushort sg_entry_cnt = 0;
9174 ushort sg_entry_cnt_minus_one = 0;
9175 uchar target_ix;
9176 uchar tid_no;
9177 uchar sdtr_data;
9178 uchar extra_bytes;
9179 uchar scsi_cmd;
9180 uchar disable_cmd;
9181 ASC_SG_HEAD *sg_head;
9182 ASC_DCNT data_cnt;
9183
9184 iop_base = asc_dvc->iop_base;
9185 sg_head = scsiq->sg_head;
27c868c2
MW
9186 if (asc_dvc->err_code != 0)
9187 return (ERR);
9188 if (scsiq == (ASC_SCSI_Q *)0L) {
9189 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
9190 return (ERR);
9191 }
9192 scsiq->q1.q_no = 0;
9193 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
9194 scsiq->q1.extra_bytes = 0;
9195 }
9196 sta = 0;
9197 target_ix = scsiq->q2.target_ix;
9198 tid_no = ASC_TIX_TO_TID(target_ix);
9199 n_q_required = 1;
9200 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
9201 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
9202 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
9203 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9204 AscMsgOutSDTR(asc_dvc,
9205 asc_dvc->
9206 sdtr_period_tbl[(sdtr_data >> 4) &
9207 (uchar)(asc_dvc->
9208 max_sdtr_index -
9209 1)],
9210 (uchar)(sdtr_data & (uchar)
9211 ASC_SYN_MAX_OFFSET));
9212 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
9213 }
9214 }
9215 last_int_level = DvcEnterCritical();
9216 if (asc_dvc->in_critical_cnt != 0) {
9217 DvcLeaveCritical(last_int_level);
9218 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
9219 return (ERR);
9220 }
9221 asc_dvc->in_critical_cnt++;
9222 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9223 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
9224 asc_dvc->in_critical_cnt--;
9225 DvcLeaveCritical(last_int_level);
9226 return (ERR);
9227 }
1da177e4 9228#if !CC_VERY_LONG_SG_LIST
27c868c2
MW
9229 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9230 asc_dvc->in_critical_cnt--;
9231 DvcLeaveCritical(last_int_level);
9232 return (ERR);
9233 }
1da177e4 9234#endif /* !CC_VERY_LONG_SG_LIST */
27c868c2
MW
9235 if (sg_entry_cnt == 1) {
9236 scsiq->q1.data_addr =
9237 (ADV_PADDR)sg_head->sg_list[0].addr;
9238 scsiq->q1.data_cnt =
9239 (ADV_DCNT)sg_head->sg_list[0].bytes;
9240 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
9241 }
9242 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
9243 }
9244 scsi_cmd = scsiq->cdbptr[0];
9245 disable_syn_offset_one_fix = FALSE;
9246 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
9247 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
9248 if (scsiq->q1.cntl & QC_SG_HEAD) {
9249 data_cnt = 0;
9250 for (i = 0; i < sg_entry_cnt; i++) {
9251 data_cnt +=
9252 (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
9253 bytes);
9254 }
9255 } else {
9256 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
9257 }
9258 if (data_cnt != 0UL) {
9259 if (data_cnt < 512UL) {
9260 disable_syn_offset_one_fix = TRUE;
9261 } else {
9262 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
9263 i++) {
9264 disable_cmd =
9265 _syn_offset_one_disable_cmd[i];
9266 if (disable_cmd == 0xFF) {
9267 break;
9268 }
9269 if (scsi_cmd == disable_cmd) {
9270 disable_syn_offset_one_fix =
9271 TRUE;
9272 break;
9273 }
9274 }
9275 }
9276 }
9277 }
9278 if (disable_syn_offset_one_fix) {
9279 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9280 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
9281 ASC_TAG_FLAG_DISABLE_DISCONNECT);
9282 } else {
9283 scsiq->q2.tag_code &= 0x27;
9284 }
9285 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9286 if (asc_dvc->bug_fix_cntl) {
9287 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9288 if ((scsi_cmd == READ_6) ||
9289 (scsi_cmd == READ_10)) {
9290 addr =
9291 (ADV_PADDR)le32_to_cpu(sg_head->
9292 sg_list
9293 [sg_entry_cnt_minus_one].
9294 addr) +
9295 (ADV_DCNT)le32_to_cpu(sg_head->
9296 sg_list
9297 [sg_entry_cnt_minus_one].
9298 bytes);
9299 extra_bytes =
9300 (uchar)((ushort)addr & 0x0003);
9301 if ((extra_bytes != 0)
9302 &&
9303 ((scsiq->q2.
9304 tag_code &
9305 ASC_TAG_FLAG_EXTRA_BYTES)
9306 == 0)) {
9307 scsiq->q2.tag_code |=
9308 ASC_TAG_FLAG_EXTRA_BYTES;
9309 scsiq->q1.extra_bytes =
9310 extra_bytes;
9311 data_cnt =
9312 le32_to_cpu(sg_head->
9313 sg_list
9314 [sg_entry_cnt_minus_one].
9315 bytes);
9316 data_cnt -=
9317 (ASC_DCNT) extra_bytes;
9318 sg_head->
9319 sg_list
9320 [sg_entry_cnt_minus_one].
9321 bytes =
9322 cpu_to_le32(data_cnt);
9323 }
9324 }
9325 }
9326 }
9327 sg_head->entry_to_copy = sg_head->entry_cnt;
1da177e4 9328#if CC_VERY_LONG_SG_LIST
27c868c2
MW
9329 /*
9330 * Set the sg_entry_cnt to the maximum possible. The rest of
9331 * the SG elements will be copied when the RISC completes the
9332 * SG elements that fit and halts.
9333 */
9334 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9335 sg_entry_cnt = ASC_MAX_SG_LIST;
9336 }
1da177e4 9337#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
9338 n_q_required = AscSgListToQueue(sg_entry_cnt);
9339 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
9340 (uint) n_q_required)
9341 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9342 if ((sta =
9343 AscSendScsiQueue(asc_dvc, scsiq,
9344 n_q_required)) == 1) {
9345 asc_dvc->in_critical_cnt--;
27c868c2
MW
9346 DvcLeaveCritical(last_int_level);
9347 return (sta);
9348 }
9349 }
9350 } else {
9351 if (asc_dvc->bug_fix_cntl) {
9352 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9353 if ((scsi_cmd == READ_6) ||
9354 (scsi_cmd == READ_10)) {
9355 addr =
9356 le32_to_cpu(scsiq->q1.data_addr) +
9357 le32_to_cpu(scsiq->q1.data_cnt);
9358 extra_bytes =
9359 (uchar)((ushort)addr & 0x0003);
9360 if ((extra_bytes != 0)
9361 &&
9362 ((scsiq->q2.
9363 tag_code &
9364 ASC_TAG_FLAG_EXTRA_BYTES)
9365 == 0)) {
9366 data_cnt =
9367 le32_to_cpu(scsiq->q1.
9368 data_cnt);
9369 if (((ushort)data_cnt & 0x01FF)
9370 == 0) {
9371 scsiq->q2.tag_code |=
9372 ASC_TAG_FLAG_EXTRA_BYTES;
9373 data_cnt -= (ASC_DCNT)
9374 extra_bytes;
9375 scsiq->q1.data_cnt =
9376 cpu_to_le32
9377 (data_cnt);
9378 scsiq->q1.extra_bytes =
9379 extra_bytes;
9380 }
9381 }
9382 }
9383 }
9384 }
9385 n_q_required = 1;
9386 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
9387 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9388 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
9389 n_q_required)) == 1) {
9390 asc_dvc->in_critical_cnt--;
27c868c2
MW
9391 DvcLeaveCritical(last_int_level);
9392 return (sta);
9393 }
9394 }
9395 }
9396 asc_dvc->in_critical_cnt--;
9397 DvcLeaveCritical(last_int_level);
9398 return (sta);
1da177e4
LT
9399}
9400
27c868c2
MW
9401static int
9402AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
1da177e4 9403{
27c868c2
MW
9404 PortAddr iop_base;
9405 uchar free_q_head;
9406 uchar next_qp;
9407 uchar tid_no;
9408 uchar target_ix;
9409 int sta;
9410
9411 iop_base = asc_dvc->iop_base;
9412 target_ix = scsiq->q2.target_ix;
9413 tid_no = ASC_TIX_TO_TID(target_ix);
9414 sta = 0;
9415 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
9416 if (n_q_required > 1) {
9417 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
9418 free_q_head, (uchar)
9419 (n_q_required)))
9420 != (uchar)ASC_QLINK_END) {
9421 asc_dvc->last_q_shortage = 0;
9422 scsiq->sg_head->queue_cnt = n_q_required - 1;
9423 scsiq->q1.q_no = free_q_head;
9424 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
9425 free_q_head)) == 1) {
9426 AscPutVarFreeQHead(iop_base, next_qp);
9427 asc_dvc->cur_total_qng += (uchar)(n_q_required);
9428 asc_dvc->cur_dvc_qng[tid_no]++;
9429 }
9430 return (sta);
9431 }
9432 } else if (n_q_required == 1) {
9433 if ((next_qp = AscAllocFreeQueue(iop_base,
9434 free_q_head)) !=
9435 ASC_QLINK_END) {
9436 scsiq->q1.q_no = free_q_head;
9437 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
9438 free_q_head)) == 1) {
9439 AscPutVarFreeQHead(iop_base, next_qp);
9440 asc_dvc->cur_total_qng++;
9441 asc_dvc->cur_dvc_qng[tid_no]++;
9442 }
9443 return (sta);
9444 }
9445 }
9446 return (sta);
1da177e4
LT
9447}
9448
27c868c2 9449static int AscSgListToQueue(int sg_list)
1da177e4 9450{
27c868c2 9451 int n_sg_list_qs;
1da177e4 9452
27c868c2
MW
9453 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
9454 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
9455 n_sg_list_qs++;
9456 return (n_sg_list_qs + 1);
1da177e4
LT
9457}
9458
27c868c2
MW
9459static uint
9460AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
1da177e4 9461{
27c868c2
MW
9462 uint cur_used_qs;
9463 uint cur_free_qs;
9464 ASC_SCSI_BIT_ID_TYPE target_id;
9465 uchar tid_no;
9466
9467 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
9468 tid_no = ASC_TIX_TO_TID(target_ix);
9469 if ((asc_dvc->unit_not_ready & target_id) ||
9470 (asc_dvc->queue_full_or_busy & target_id)) {
9471 return (0);
9472 }
9473 if (n_qs == 1) {
9474 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9475 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
9476 } else {
9477 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9478 (uint) ASC_MIN_FREE_Q;
9479 }
9480 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
9481 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
9482 if (asc_dvc->cur_dvc_qng[tid_no] >=
9483 asc_dvc->max_dvc_qng[tid_no]) {
9484 return (0);
9485 }
9486 return (cur_free_qs);
9487 }
9488 if (n_qs > 1) {
9489 if ((n_qs > asc_dvc->last_q_shortage)
9490 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
9491 asc_dvc->last_q_shortage = n_qs;
9492 }
9493 }
9494 return (0);
1da177e4
LT
9495}
9496
27c868c2 9497static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
1da177e4 9498{
27c868c2
MW
9499 ushort q_addr;
9500 uchar tid_no;
9501 uchar sdtr_data;
9502 uchar syn_period_ix;
9503 uchar syn_offset;
9504 PortAddr iop_base;
9505
9506 iop_base = asc_dvc->iop_base;
9507 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
9508 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
9509 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
9510 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9511 syn_period_ix =
9512 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
9513 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
9514 AscMsgOutSDTR(asc_dvc,
9515 asc_dvc->sdtr_period_tbl[syn_period_ix],
9516 syn_offset);
9517 scsiq->q1.cntl |= QC_MSG_OUT;
9518 }
9519 q_addr = ASC_QNO_TO_QADDR(q_no);
9520 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
9521 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9522 }
9523 scsiq->q1.status = QS_FREE;
9524 AscMemWordCopyPtrToLram(iop_base,
9525 q_addr + ASC_SCSIQ_CDB_BEG,
9526 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
9527
9528 DvcPutScsiQ(iop_base,
9529 q_addr + ASC_SCSIQ_CPY_BEG,
9530 (uchar *)&scsiq->q1.cntl,
9531 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
9532 AscWriteLramWord(iop_base,
9533 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
9534 (ushort)(((ushort)scsiq->q1.
9535 q_no << 8) | (ushort)QS_READY));
9536 return (1);
1da177e4
LT
9537}
9538
27c868c2
MW
9539static int
9540AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
1da177e4 9541{
27c868c2
MW
9542 int sta;
9543 int i;
9544 ASC_SG_HEAD *sg_head;
9545 ASC_SG_LIST_Q scsi_sg_q;
9546 ASC_DCNT saved_data_addr;
9547 ASC_DCNT saved_data_cnt;
9548 PortAddr iop_base;
9549 ushort sg_list_dwords;
9550 ushort sg_index;
9551 ushort sg_entry_cnt;
9552 ushort q_addr;
9553 uchar next_qp;
9554
9555 iop_base = asc_dvc->iop_base;
9556 sg_head = scsiq->sg_head;
9557 saved_data_addr = scsiq->q1.data_addr;
9558 saved_data_cnt = scsiq->q1.data_cnt;
9559 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
9560 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
1da177e4 9561#if CC_VERY_LONG_SG_LIST
27c868c2
MW
9562 /*
9563 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
9564 * then not all SG elements will fit in the allocated queues.
9565 * The rest of the SG elements will be copied when the RISC
9566 * completes the SG elements that fit and halts.
9567 */
9568 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9569 /*
9570 * Set sg_entry_cnt to be the number of SG elements that
9571 * will fit in the allocated SG queues. It is minus 1, because
9572 * the first SG element is handled above. ASC_MAX_SG_LIST is
9573 * already inflated by 1 to account for this. For example it
9574 * may be 50 which is 1 + 7 queues * 7 SG elements.
9575 */
9576 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
9577
9578 /*
9579 * Keep track of remaining number of SG elements that will
9580 * need to be handled from a_isr.c.
9581 */
9582 scsiq->remain_sg_entry_cnt =
9583 sg_head->entry_cnt - ASC_MAX_SG_LIST;
9584 } else {
1da177e4 9585#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
9586 /*
9587 * Set sg_entry_cnt to be the number of SG elements that
9588 * will fit in the allocated SG queues. It is minus 1, because
9589 * the first SG element is handled above.
9590 */
9591 sg_entry_cnt = sg_head->entry_cnt - 1;
1da177e4 9592#if CC_VERY_LONG_SG_LIST
27c868c2 9593 }
1da177e4 9594#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
9595 if (sg_entry_cnt != 0) {
9596 scsiq->q1.cntl |= QC_SG_HEAD;
9597 q_addr = ASC_QNO_TO_QADDR(q_no);
9598 sg_index = 1;
9599 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
9600 scsi_sg_q.sg_head_qp = q_no;
9601 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
9602 for (i = 0; i < sg_head->queue_cnt; i++) {
9603 scsi_sg_q.seq_no = i + 1;
9604 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
9605 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
9606 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
9607 if (i == 0) {
9608 scsi_sg_q.sg_list_cnt =
9609 ASC_SG_LIST_PER_Q;
9610 scsi_sg_q.sg_cur_list_cnt =
9611 ASC_SG_LIST_PER_Q;
9612 } else {
9613 scsi_sg_q.sg_list_cnt =
9614 ASC_SG_LIST_PER_Q - 1;
9615 scsi_sg_q.sg_cur_list_cnt =
9616 ASC_SG_LIST_PER_Q - 1;
9617 }
9618 } else {
1da177e4 9619#if CC_VERY_LONG_SG_LIST
27c868c2
MW
9620 /*
9621 * This is the last SG queue in the list of
9622 * allocated SG queues. If there are more
9623 * SG elements than will fit in the allocated
9624 * queues, then set the QCSG_SG_XFER_MORE flag.
9625 */
9626 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9627 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
9628 } else {
1da177e4 9629#endif /* CC_VERY_LONG_SG_LIST */
27c868c2 9630 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
1da177e4 9631#if CC_VERY_LONG_SG_LIST
27c868c2 9632 }
1da177e4 9633#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
9634 sg_list_dwords = sg_entry_cnt << 1;
9635 if (i == 0) {
9636 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
9637 scsi_sg_q.sg_cur_list_cnt =
9638 sg_entry_cnt;
9639 } else {
9640 scsi_sg_q.sg_list_cnt =
9641 sg_entry_cnt - 1;
9642 scsi_sg_q.sg_cur_list_cnt =
9643 sg_entry_cnt - 1;
9644 }
9645 sg_entry_cnt = 0;
9646 }
9647 next_qp = AscReadLramByte(iop_base,
9648 (ushort)(q_addr +
9649 ASC_SCSIQ_B_FWD));
9650 scsi_sg_q.q_no = next_qp;
9651 q_addr = ASC_QNO_TO_QADDR(next_qp);
9652 AscMemWordCopyPtrToLram(iop_base,
9653 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
9654 (uchar *)&scsi_sg_q,
9655 sizeof(ASC_SG_LIST_Q) >> 1);
9656 AscMemDWordCopyPtrToLram(iop_base,
9657 q_addr + ASC_SGQ_LIST_BEG,
9658 (uchar *)&sg_head->
9659 sg_list[sg_index],
9660 sg_list_dwords);
9661 sg_index += ASC_SG_LIST_PER_Q;
9662 scsiq->next_sg_index = sg_index;
9663 }
9664 } else {
9665 scsiq->q1.cntl &= ~QC_SG_HEAD;
9666 }
9667 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
9668 scsiq->q1.data_addr = saved_data_addr;
9669 scsiq->q1.data_cnt = saved_data_cnt;
9670 return (sta);
1da177e4
LT
9671}
9672
27c868c2
MW
9673static int
9674AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
1da177e4 9675{
27c868c2 9676 int sta = FALSE;
1da177e4 9677
27c868c2
MW
9678 if (AscHostReqRiscHalt(iop_base)) {
9679 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9680 AscStartChip(iop_base);
9681 return (sta);
9682 }
9683 return (sta);
1da177e4
LT
9684}
9685
27c868c2 9686static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
1da177e4 9687{
27c868c2
MW
9688 ASC_SCSI_BIT_ID_TYPE org_id;
9689 int i;
9690 int sta = TRUE;
9691
9692 AscSetBank(iop_base, 1);
9693 org_id = AscReadChipDvcID(iop_base);
9694 for (i = 0; i <= ASC_MAX_TID; i++) {
9695 if (org_id == (0x01 << i))
9696 break;
9697 }
9698 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
9699 AscWriteChipDvcID(iop_base, id);
9700 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
9701 AscSetBank(iop_base, 0);
9702 AscSetChipSyn(iop_base, sdtr_data);
9703 if (AscGetChipSyn(iop_base) != sdtr_data) {
9704 sta = FALSE;
9705 }
9706 } else {
9707 sta = FALSE;
9708 }
9709 AscSetBank(iop_base, 1);
9710 AscWriteChipDvcID(iop_base, org_id);
9711 AscSetBank(iop_base, 0);
9712 return (sta);
9713}
1da177e4 9714
27c868c2 9715static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
1da177e4 9716{
27c868c2
MW
9717 uchar i;
9718 ushort s_addr;
9719 PortAddr iop_base;
9720 ushort warn_code;
9721
9722 iop_base = asc_dvc->iop_base;
9723 warn_code = 0;
9724 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
9725 (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
9726 64) >> 1)
9727 );
9728 i = ASC_MIN_ACTIVE_QNO;
9729 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
9730 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9731 (uchar)(i + 1));
9732 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9733 (uchar)(asc_dvc->max_total_qng));
9734 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9735 (uchar)i);
9736 i++;
9737 s_addr += ASC_QBLK_SIZE;
9738 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
9739 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9740 (uchar)(i + 1));
9741 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9742 (uchar)(i - 1));
9743 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9744 (uchar)i);
9745 }
9746 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9747 (uchar)ASC_QLINK_END);
9748 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9749 (uchar)(asc_dvc->max_total_qng - 1));
9750 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9751 (uchar)asc_dvc->max_total_qng);
9752 i++;
9753 s_addr += ASC_QBLK_SIZE;
9754 for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
9755 i++, s_addr += ASC_QBLK_SIZE) {
9756 AscWriteLramByte(iop_base,
9757 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
9758 AscWriteLramByte(iop_base,
9759 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
9760 AscWriteLramByte(iop_base,
9761 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
9762 }
9763 return (warn_code);
1da177e4
LT
9764}
9765
27c868c2 9766static ushort AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
1da177e4 9767{
27c868c2
MW
9768 PortAddr iop_base;
9769 int i;
9770 ushort lram_addr;
9771
9772 iop_base = asc_dvc->iop_base;
9773 AscPutRiscVarFreeQHead(iop_base, 1);
9774 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
9775 AscPutVarFreeQHead(iop_base, 1);
9776 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
9777 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
9778 (uchar)((int)asc_dvc->max_total_qng + 1));
9779 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
9780 (uchar)((int)asc_dvc->max_total_qng + 2));
9781 AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
9782 asc_dvc->max_total_qng);
9783 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
9784 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9785 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
9786 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
9787 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
9788 AscPutQDoneInProgress(iop_base, 0);
9789 lram_addr = ASC_QADR_BEG;
9790 for (i = 0; i < 32; i++, lram_addr += 2) {
9791 AscWriteLramWord(iop_base, lram_addr, 0);
9792 }
9793 return (0);
1da177e4
LT
9794}
9795
27c868c2 9796static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
1da177e4 9797{
27c868c2
MW
9798 if (asc_dvc->err_code == 0) {
9799 asc_dvc->err_code = err_code;
9800 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
9801 err_code);
9802 }
9803 return (err_code);
1da177e4
LT
9804}
9805
27c868c2
MW
9806static uchar
9807AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
1da177e4 9808{
27c868c2
MW
9809 EXT_MSG sdtr_buf;
9810 uchar sdtr_period_index;
9811 PortAddr iop_base;
9812
9813 iop_base = asc_dvc->iop_base;
47d853cc 9814 sdtr_buf.msg_type = EXTENDED_MESSAGE;
27c868c2 9815 sdtr_buf.msg_len = MS_SDTR_LEN;
47d853cc 9816 sdtr_buf.msg_req = EXTENDED_SDTR;
27c868c2
MW
9817 sdtr_buf.xfer_period = sdtr_period;
9818 sdtr_offset &= ASC_SYN_MAX_OFFSET;
9819 sdtr_buf.req_ack_offset = sdtr_offset;
9820 if ((sdtr_period_index =
9821 AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
9822 asc_dvc->max_sdtr_index) {
9823 AscMemWordCopyPtrToLram(iop_base,
9824 ASCV_MSGOUT_BEG,
9825 (uchar *)&sdtr_buf,
9826 sizeof(EXT_MSG) >> 1);
9827 return ((sdtr_period_index << 4) | sdtr_offset);
9828 } else {
9829
9830 sdtr_buf.req_ack_offset = 0;
9831 AscMemWordCopyPtrToLram(iop_base,
9832 ASCV_MSGOUT_BEG,
9833 (uchar *)&sdtr_buf,
9834 sizeof(EXT_MSG) >> 1);
9835 return (0);
9836 }
1da177e4
LT
9837}
9838
27c868c2
MW
9839static uchar
9840AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
1da177e4 9841{
27c868c2
MW
9842 uchar byte;
9843 uchar sdtr_period_ix;
9844
9845 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
9846 if ((sdtr_period_ix > asc_dvc->max_sdtr_index)
9847 ) {
9848 return (0xFF);
9849 }
9850 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
9851 return (byte);
1da177e4
LT
9852}
9853
27c868c2 9854static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
1da177e4 9855{
27c868c2
MW
9856 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9857 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
9858 return;
1da177e4
LT
9859}
9860
27c868c2 9861static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
1da177e4 9862{
27c868c2
MW
9863 uchar *period_table;
9864 int max_index;
9865 int min_index;
9866 int i;
9867
9868 period_table = asc_dvc->sdtr_period_tbl;
9869 max_index = (int)asc_dvc->max_sdtr_index;
9870 min_index = (int)asc_dvc->host_init_sdtr_index;
9871 if ((syn_time <= period_table[max_index])) {
9872 for (i = min_index; i < (max_index - 1); i++) {
9873 if (syn_time <= period_table[i]) {
9874 return ((uchar)i);
9875 }
9876 }
9877 return ((uchar)max_index);
9878 } else {
9879 return ((uchar)(max_index + 1));
9880 }
1da177e4
LT
9881}
9882
27c868c2 9883static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
1da177e4 9884{
27c868c2
MW
9885 ushort q_addr;
9886 uchar next_qp;
9887 uchar q_status;
9888
9889 q_addr = ASC_QNO_TO_QADDR(free_q_head);
9890 q_status = (uchar)AscReadLramByte(iop_base,
9891 (ushort)(q_addr +
9892 ASC_SCSIQ_B_STATUS));
9893 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
9894 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
9895 return (next_qp);
9896 }
9897 return (ASC_QLINK_END);
1da177e4
LT
9898}
9899
27c868c2
MW
9900static uchar
9901AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
1da177e4 9902{
27c868c2 9903 uchar i;
1da177e4 9904
27c868c2
MW
9905 for (i = 0; i < n_free_q; i++) {
9906 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
9907 == ASC_QLINK_END) {
9908 return (ASC_QLINK_END);
9909 }
9910 }
9911 return (free_q_head);
1da177e4
LT
9912}
9913
27c868c2 9914static int AscHostReqRiscHalt(PortAddr iop_base)
1da177e4 9915{
27c868c2
MW
9916 int count = 0;
9917 int sta = 0;
9918 uchar saved_stop_code;
9919
9920 if (AscIsChipHalted(iop_base))
9921 return (1);
9922 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
9923 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
9924 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
9925 do {
9926 if (AscIsChipHalted(iop_base)) {
9927 sta = 1;
9928 break;
9929 }
9930 DvcSleepMilliSecond(100);
9931 } while (count++ < 20);
9932 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
9933 return (sta);
1da177e4
LT
9934}
9935
27c868c2 9936static int AscStopQueueExe(PortAddr iop_base)
1da177e4 9937{
27c868c2
MW
9938 int count = 0;
9939
9940 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
9941 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
9942 ASC_STOP_REQ_RISC_STOP);
9943 do {
9944 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
9945 ASC_STOP_ACK_RISC_STOP) {
9946 return (1);
9947 }
9948 DvcSleepMilliSecond(100);
9949 } while (count++ < 20);
9950 }
9951 return (0);
1da177e4
LT
9952}
9953
27c868c2 9954static void DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
1da177e4 9955{
27c868c2 9956 udelay(micro_sec);
1da177e4
LT
9957}
9958
27c868c2 9959static void DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
1da177e4 9960{
27c868c2 9961 udelay((nano_sec + 999) / 1000);
1da177e4
LT
9962}
9963
27c868c2 9964static int AscStartChip(PortAddr iop_base)
1da177e4 9965{
27c868c2
MW
9966 AscSetChipControl(iop_base, 0);
9967 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
9968 return (0);
9969 }
9970 return (1);
1da177e4
LT
9971}
9972
27c868c2 9973static int AscStopChip(PortAddr iop_base)
1da177e4 9974{
27c868c2
MW
9975 uchar cc_val;
9976
9977 cc_val =
9978 AscGetChipControl(iop_base) &
9979 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
9980 AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
9981 AscSetChipIH(iop_base, INS_HALT);
9982 AscSetChipIH(iop_base, INS_RFLAG_WTM);
9983 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
9984 return (0);
9985 }
9986 return (1);
1da177e4
LT
9987}
9988
27c868c2 9989static int AscIsChipHalted(PortAddr iop_base)
1da177e4 9990{
27c868c2
MW
9991 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
9992 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
9993 return (1);
9994 }
9995 }
9996 return (0);
1da177e4
LT
9997}
9998
27c868c2 9999static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
1da177e4 10000{
27c868c2
MW
10001 AscSetBank(iop_base, 1);
10002 AscWriteChipIH(iop_base, ins_code);
10003 AscSetBank(iop_base, 0);
10004 return;
1da177e4
LT
10005}
10006
27c868c2 10007static void AscAckInterrupt(PortAddr iop_base)
1da177e4 10008{
27c868c2
MW
10009 uchar host_flag;
10010 uchar risc_flag;
10011 ushort loop;
10012
10013 loop = 0;
10014 do {
10015 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
10016 if (loop++ > 0x7FFF) {
10017 break;
10018 }
10019 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
10020 host_flag =
10021 AscReadLramByte(iop_base,
10022 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
10023 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10024 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
10025 AscSetChipStatus(iop_base, CIW_INT_ACK);
10026 loop = 0;
10027 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
10028 AscSetChipStatus(iop_base, CIW_INT_ACK);
10029 if (loop++ > 3) {
10030 break;
10031 }
10032 }
10033 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10034 return;
1da177e4
LT
10035}
10036
27c868c2 10037static void AscDisableInterrupt(PortAddr iop_base)
1da177e4 10038{
27c868c2 10039 ushort cfg;
1da177e4 10040
27c868c2
MW
10041 cfg = AscGetChipCfgLsw(iop_base);
10042 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
10043 return;
1da177e4
LT
10044}
10045
27c868c2 10046static void AscEnableInterrupt(PortAddr iop_base)
1da177e4 10047{
27c868c2 10048 ushort cfg;
1da177e4 10049
27c868c2
MW
10050 cfg = AscGetChipCfgLsw(iop_base);
10051 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
10052 return;
1da177e4
LT
10053}
10054
27c868c2 10055static void AscSetBank(PortAddr iop_base, uchar bank)
1da177e4 10056{
27c868c2
MW
10057 uchar val;
10058
10059 val = AscGetChipControl(iop_base) &
10060 (~
10061 (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
10062 CC_CHIP_RESET));
10063 if (bank == 1) {
10064 val |= CC_BANK_ONE;
10065 } else if (bank == 2) {
10066 val |= CC_DIAG | CC_BANK_ONE;
10067 } else {
10068 val &= ~CC_BANK_ONE;
10069 }
10070 AscSetChipControl(iop_base, val);
10071 return;
1da177e4
LT
10072}
10073
27c868c2 10074static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
1da177e4 10075{
27c868c2
MW
10076 PortAddr iop_base;
10077 int i = 10;
1da177e4 10078
27c868c2
MW
10079 iop_base = asc_dvc->iop_base;
10080 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
10081 && (i-- > 0)) {
10082 DvcSleepMilliSecond(100);
10083 }
10084 AscStopChip(iop_base);
10085 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
10086 DvcDelayNanoSecond(asc_dvc, 60000);
10087 AscSetChipIH(iop_base, INS_RFLAG_WTM);
10088 AscSetChipIH(iop_base, INS_HALT);
10089 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
10090 AscSetChipControl(iop_base, CC_HALT);
10091 DvcSleepMilliSecond(200);
10092 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10093 AscSetChipStatus(iop_base, 0);
10094 return (AscIsChipHalted(iop_base));
1da177e4
LT
10095}
10096
78e77d8b 10097static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
1da177e4 10098{
27c868c2
MW
10099 if (bus_type & ASC_IS_ISA)
10100 return (ASC_MAX_ISA_DMA_COUNT);
10101 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
10102 return (ASC_MAX_VL_DMA_COUNT);
10103 return (ASC_MAX_PCI_DMA_COUNT);
1da177e4
LT
10104}
10105
10106#ifdef CONFIG_ISA
78e77d8b 10107static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
1da177e4 10108{
27c868c2
MW
10109 ushort channel;
10110
10111 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
10112 if (channel == 0x03)
10113 return (0);
10114 else if (channel == 0x00)
10115 return (7);
10116 return (channel + 4);
1da177e4
LT
10117}
10118
78e77d8b 10119static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
1da177e4 10120{
27c868c2
MW
10121 ushort cfg_lsw;
10122 uchar value;
10123
10124 if ((dma_channel >= 5) && (dma_channel <= 7)) {
10125 if (dma_channel == 7)
10126 value = 0x00;
10127 else
10128 value = dma_channel - 4;
10129 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
10130 cfg_lsw |= value;
10131 AscSetChipCfgLsw(iop_base, cfg_lsw);
10132 return (AscGetIsaDmaChannel(iop_base));
10133 }
10134 return (0);
1da177e4
LT
10135}
10136
78e77d8b 10137static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
1da177e4 10138{
27c868c2
MW
10139 speed_value &= 0x07;
10140 AscSetBank(iop_base, 1);
10141 AscWriteChipDmaSpeed(iop_base, speed_value);
10142 AscSetBank(iop_base, 0);
10143 return (AscGetIsaDmaSpeed(iop_base));
1da177e4
LT
10144}
10145
78e77d8b 10146static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
1da177e4 10147{
27c868c2 10148 uchar speed_value;
1da177e4 10149
27c868c2
MW
10150 AscSetBank(iop_base, 1);
10151 speed_value = AscReadChipDmaSpeed(iop_base);
10152 speed_value &= 0x07;
10153 AscSetBank(iop_base, 0);
10154 return (speed_value);
1da177e4
LT
10155}
10156#endif /* CONFIG_ISA */
10157
78e77d8b 10158static ushort __devinit AscInitGetConfig(ASC_DVC_VAR *asc_dvc)
1da177e4 10159{
9649af39 10160 unsigned short warn_code = 0;
27c868c2 10161
27c868c2 10162 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
9649af39 10163 if (asc_dvc->err_code != 0)
27c868c2 10164 return (UW_ERR);
27c868c2 10165
9649af39 10166 if (AscFindSignature(asc_dvc->iop_base)) {
27c868c2
MW
10167 warn_code |= AscInitAscDvcVar(asc_dvc);
10168 warn_code |= AscInitFromEEP(asc_dvc);
10169 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
ecec1947 10170 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
27c868c2 10171 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
27c868c2
MW
10172 } else {
10173 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10174 }
ecec1947 10175 return warn_code;
1da177e4
LT
10176}
10177
394dbf3f
MW
10178static unsigned short __devinit
10179AscInitSetConfig(struct pci_dev *pdev, ASC_DVC_VAR *asc_dvc)
1da177e4 10180{
394dbf3f
MW
10181 PortAddr iop_base = asc_dvc->iop_base;
10182 unsigned short cfg_msw;
10183 unsigned short warn_code = 0;
27c868c2
MW
10184
10185 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
10186 if (asc_dvc->err_code != 0)
394dbf3f
MW
10187 return UW_ERR;
10188 if (!AscFindSignature(asc_dvc->iop_base)) {
27c868c2 10189 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
394dbf3f 10190 return 0;
27c868c2 10191 }
1da177e4 10192
27c868c2
MW
10193 cfg_msw = AscGetChipCfgMsw(iop_base);
10194 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10195 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10196 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10197 AscSetChipCfgMsw(iop_base, cfg_msw);
10198 }
10199 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
10200 asc_dvc->cfg->cmd_qng_enabled) {
10201 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
10202 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10203 }
10204 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10205 warn_code |= ASC_WARN_AUTO_CONFIG;
10206 }
10207 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
10208 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
10209 != asc_dvc->irq_no) {
10210 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
10211 }
10212 }
9649af39 10213#ifdef CONFIG_PCI
27c868c2
MW
10214 if (asc_dvc->bus_type & ASC_IS_PCI) {
10215 cfg_msw &= 0xFFC0;
10216 AscSetChipCfgMsw(iop_base, cfg_msw);
10217 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
10218 } else {
9649af39
MW
10219 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
10220 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
27c868c2
MW
10221 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
10222 asc_dvc->bug_fix_cntl |=
10223 ASC_BUG_FIX_ASYN_USE_SYN;
10224 }
10225 }
9649af39
MW
10226 } else
10227#endif /* CONFIG_PCI */
10228 if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
27c868c2
MW
10229 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
10230 == ASC_CHIP_VER_ASYN_BUG) {
10231 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
10232 }
10233 }
10234 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
10235 asc_dvc->cfg->chip_scsi_id) {
10236 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
10237 }
1da177e4 10238#ifdef CONFIG_ISA
27c868c2
MW
10239 if (asc_dvc->bus_type & ASC_IS_ISA) {
10240 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
10241 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
10242 }
1da177e4 10243#endif /* CONFIG_ISA */
394dbf3f
MW
10244
10245 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
10246 return warn_code;
1da177e4
LT
10247}
10248
27c868c2 10249static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
1da177e4 10250{
27c868c2
MW
10251 ushort warn_code;
10252 PortAddr iop_base;
10253
10254 iop_base = asc_dvc->iop_base;
10255 warn_code = 0;
10256 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
10257 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
10258 AscResetChipAndScsiBus(asc_dvc);
10259 DvcSleepMilliSecond((ASC_DCNT)
10260 ((ushort)asc_dvc->scsi_reset_wait * 1000));
10261 }
10262 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
10263 if (asc_dvc->err_code != 0)
10264 return (UW_ERR);
10265 if (!AscFindSignature(asc_dvc->iop_base)) {
10266 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10267 return (warn_code);
10268 }
10269 AscDisableInterrupt(iop_base);
10270 warn_code |= AscInitLram(asc_dvc);
10271 if (asc_dvc->err_code != 0)
10272 return (UW_ERR);
10273 ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
10274 (ulong)_asc_mcode_chksum);
10275 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
10276 _asc_mcode_size) != _asc_mcode_chksum) {
10277 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
10278 return (warn_code);
10279 }
10280 warn_code |= AscInitMicroCodeVar(asc_dvc);
10281 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
10282 AscEnableInterrupt(iop_base);
10283 return (warn_code);
1da177e4
LT
10284}
10285
78e77d8b 10286static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
1da177e4 10287{
27c868c2
MW
10288 int i;
10289 PortAddr iop_base;
10290 ushort warn_code;
10291 uchar chip_version;
10292
10293 iop_base = asc_dvc->iop_base;
10294 warn_code = 0;
10295 asc_dvc->err_code = 0;
10296 if ((asc_dvc->bus_type &
10297 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
10298 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
10299 }
10300 AscSetChipControl(iop_base, CC_HALT);
10301 AscSetChipStatus(iop_base, 0);
10302 asc_dvc->bug_fix_cntl = 0;
10303 asc_dvc->pci_fix_asyn_xfer = 0;
10304 asc_dvc->pci_fix_asyn_xfer_always = 0;
10305 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
10306 asc_dvc->sdtr_done = 0;
10307 asc_dvc->cur_total_qng = 0;
10308 asc_dvc->is_in_int = 0;
10309 asc_dvc->in_critical_cnt = 0;
10310 asc_dvc->last_q_shortage = 0;
10311 asc_dvc->use_tagged_qng = 0;
10312 asc_dvc->no_scam = 0;
10313 asc_dvc->unit_not_ready = 0;
10314 asc_dvc->queue_full_or_busy = 0;
10315 asc_dvc->redo_scam = 0;
10316 asc_dvc->res2 = 0;
10317 asc_dvc->host_init_sdtr_index = 0;
10318 asc_dvc->cfg->can_tagged_qng = 0;
10319 asc_dvc->cfg->cmd_qng_enabled = 0;
10320 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
10321 asc_dvc->init_sdtr = 0;
10322 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
10323 asc_dvc->scsi_reset_wait = 3;
10324 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
10325 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
10326 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
10327 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
10328 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
10329 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
10330 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
10331 ASC_LIB_VERSION_MINOR;
10332 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
10333 asc_dvc->cfg->chip_version = chip_version;
10334 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
10335 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
10336 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
10337 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
10338 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
10339 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
10340 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
10341 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
10342 asc_dvc->max_sdtr_index = 7;
10343 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
10344 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
10345 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
10346 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
10347 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
10348 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
10349 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
10350 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
10351 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
10352 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
10353 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
10354 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
10355 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
10356 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
10357 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
10358 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
10359 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
10360 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
10361 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
10362 asc_dvc->max_sdtr_index = 15;
10363 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
10364 AscSetExtraControl(iop_base,
10365 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10366 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
10367 AscSetExtraControl(iop_base,
10368 (SEC_ACTIVE_NEGATE |
10369 SEC_ENABLE_FILTER));
10370 }
10371 }
10372 if (asc_dvc->bus_type == ASC_IS_PCI) {
10373 AscSetExtraControl(iop_base,
10374 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10375 }
1da177e4 10376
27c868c2 10377 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
1da177e4 10378#ifdef CONFIG_ISA
27c868c2 10379 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
59fcf844
MW
10380 if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) {
10381 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
10382 asc_dvc->bus_type = ASC_IS_ISAPNP;
10383 }
27c868c2
MW
10384 asc_dvc->cfg->isa_dma_channel =
10385 (uchar)AscGetIsaDmaChannel(iop_base);
10386 }
1da177e4 10387#endif /* CONFIG_ISA */
27c868c2
MW
10388 for (i = 0; i <= ASC_MAX_TID; i++) {
10389 asc_dvc->cur_dvc_qng[i] = 0;
10390 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
10391 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
10392 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
10393 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
10394 }
10395 return (warn_code);
1da177e4
LT
10396}
10397
78e77d8b 10398static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
1da177e4 10399{
27c868c2
MW
10400 ASCEEP_CONFIG eep_config_buf;
10401 ASCEEP_CONFIG *eep_config;
10402 PortAddr iop_base;
10403 ushort chksum;
10404 ushort warn_code;
10405 ushort cfg_msw, cfg_lsw;
10406 int i;
10407 int write_eep = 0;
10408
10409 iop_base = asc_dvc->iop_base;
10410 warn_code = 0;
10411 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
10412 AscStopQueueExe(iop_base);
10413 if ((AscStopChip(iop_base) == FALSE) ||
10414 (AscGetChipScsiCtrl(iop_base) != 0)) {
10415 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
10416 AscResetChipAndScsiBus(asc_dvc);
10417 DvcSleepMilliSecond((ASC_DCNT)
10418 ((ushort)asc_dvc->scsi_reset_wait * 1000));
10419 }
10420 if (AscIsChipHalted(iop_base) == FALSE) {
10421 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10422 return (warn_code);
10423 }
10424 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10425 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10426 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10427 return (warn_code);
10428 }
10429 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
10430 cfg_msw = AscGetChipCfgMsw(iop_base);
10431 cfg_lsw = AscGetChipCfgLsw(iop_base);
10432 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10433 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10434 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10435 AscSetChipCfgMsw(iop_base, cfg_msw);
10436 }
10437 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
10438 ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
10439 if (chksum == 0) {
10440 chksum = 0xaa55;
10441 }
10442 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10443 warn_code |= ASC_WARN_AUTO_CONFIG;
10444 if (asc_dvc->cfg->chip_version == 3) {
10445 if (eep_config->cfg_lsw != cfg_lsw) {
10446 warn_code |= ASC_WARN_EEPROM_RECOVER;
10447 eep_config->cfg_lsw =
10448 AscGetChipCfgLsw(iop_base);
10449 }
10450 if (eep_config->cfg_msw != cfg_msw) {
10451 warn_code |= ASC_WARN_EEPROM_RECOVER;
10452 eep_config->cfg_msw =
10453 AscGetChipCfgMsw(iop_base);
10454 }
10455 }
10456 }
10457 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
10458 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
10459 ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
10460 eep_config->chksum);
10461 if (chksum != eep_config->chksum) {
10462 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
10463 ASC_CHIP_VER_PCI_ULTRA_3050) {
10464 ASC_DBG(1,
10465 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
10466 eep_config->init_sdtr = 0xFF;
10467 eep_config->disc_enable = 0xFF;
10468 eep_config->start_motor = 0xFF;
10469 eep_config->use_cmd_qng = 0;
10470 eep_config->max_total_qng = 0xF0;
10471 eep_config->max_tag_qng = 0x20;
10472 eep_config->cntl = 0xBFFF;
10473 ASC_EEP_SET_CHIP_ID(eep_config, 7);
10474 eep_config->no_scam = 0;
10475 eep_config->adapter_info[0] = 0;
10476 eep_config->adapter_info[1] = 0;
10477 eep_config->adapter_info[2] = 0;
10478 eep_config->adapter_info[3] = 0;
10479 eep_config->adapter_info[4] = 0;
10480 /* Indicate EEPROM-less board. */
10481 eep_config->adapter_info[5] = 0xBB;
10482 } else {
10483 ASC_PRINT
10484 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
10485 write_eep = 1;
10486 warn_code |= ASC_WARN_EEPROM_CHKSUM;
10487 }
10488 }
10489 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
10490 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
10491 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
10492 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
10493 asc_dvc->start_motor = eep_config->start_motor;
10494 asc_dvc->dvc_cntl = eep_config->cntl;
10495 asc_dvc->no_scam = eep_config->no_scam;
10496 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
10497 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
10498 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
10499 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
10500 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
10501 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
10502 if (!AscTestExternalLram(asc_dvc)) {
10503 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
10504 ASC_IS_PCI_ULTRA)) {
10505 eep_config->max_total_qng =
10506 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
10507 eep_config->max_tag_qng =
10508 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
10509 } else {
10510 eep_config->cfg_msw |= 0x0800;
10511 cfg_msw |= 0x0800;
10512 AscSetChipCfgMsw(iop_base, cfg_msw);
10513 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
10514 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
10515 }
10516 } else {
10517 }
10518 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
10519 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
10520 }
10521 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
10522 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
10523 }
10524 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
10525 eep_config->max_tag_qng = eep_config->max_total_qng;
10526 }
10527 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
10528 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
10529 }
10530 asc_dvc->max_total_qng = eep_config->max_total_qng;
10531 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
10532 eep_config->use_cmd_qng) {
10533 eep_config->disc_enable = eep_config->use_cmd_qng;
10534 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10535 }
10536 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
10537 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
10538 }
10539 ASC_EEP_SET_CHIP_ID(eep_config,
10540 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
10541 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
10542 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
10543 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
10544 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
10545 }
1da177e4 10546
27c868c2
MW
10547 for (i = 0; i <= ASC_MAX_TID; i++) {
10548 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
10549 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
10550 asc_dvc->cfg->sdtr_period_offset[i] =
10551 (uchar)(ASC_DEF_SDTR_OFFSET |
10552 (asc_dvc->host_init_sdtr_index << 4));
10553 }
10554 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
10555 if (write_eep) {
10556 if ((i =
10557 AscSetEEPConfig(iop_base, eep_config,
10558 asc_dvc->bus_type)) != 0) {
10559 ASC_PRINT1
10560 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
10561 i);
10562 } else {
10563 ASC_PRINT
10564 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
10565 }
10566 }
10567 return (warn_code);
1da177e4
LT
10568}
10569
27c868c2 10570static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
1da177e4 10571{
27c868c2
MW
10572 int i;
10573 ushort warn_code;
10574 PortAddr iop_base;
10575 ASC_PADDR phy_addr;
10576 ASC_DCNT phy_size;
10577
10578 iop_base = asc_dvc->iop_base;
10579 warn_code = 0;
10580 for (i = 0; i <= ASC_MAX_TID; i++) {
10581 AscPutMCodeInitSDTRAtID(iop_base, i,
10582 asc_dvc->cfg->sdtr_period_offset[i]
10583 );
10584 }
1da177e4 10585
27c868c2
MW
10586 AscInitQLinkVar(asc_dvc);
10587 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
10588 asc_dvc->cfg->disc_enable);
10589 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
10590 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
10591
10592 /* Align overrun buffer on an 8 byte boundary. */
10593 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
10594 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
10595 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
10596 (uchar *)&phy_addr, 1);
10597 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
10598 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
10599 (uchar *)&phy_size, 1);
10600
10601 asc_dvc->cfg->mcode_date =
10602 AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
10603 asc_dvc->cfg->mcode_version =
10604 AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
10605
10606 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10607 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10608 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10609 return (warn_code);
10610 }
10611 if (AscStartChip(iop_base) != 1) {
10612 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10613 return (warn_code);
10614 }
1da177e4 10615
27c868c2 10616 return (warn_code);
1da177e4
LT
10617}
10618
78e77d8b 10619static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
1da177e4 10620{
27c868c2
MW
10621 PortAddr iop_base;
10622 ushort q_addr;
10623 ushort saved_word;
10624 int sta;
10625
10626 iop_base = asc_dvc->iop_base;
10627 sta = 0;
10628 q_addr = ASC_QNO_TO_QADDR(241);
10629 saved_word = AscReadLramWord(iop_base, q_addr);
10630 AscSetChipLramAddr(iop_base, q_addr);
10631 AscSetChipLramData(iop_base, 0x55AA);
10632 DvcSleepMilliSecond(10);
10633 AscSetChipLramAddr(iop_base, q_addr);
10634 if (AscGetChipLramData(iop_base) == 0x55AA) {
10635 sta = 1;
10636 AscWriteLramWord(iop_base, q_addr, saved_word);
10637 }
10638 return (sta);
1da177e4
LT
10639}
10640
78e77d8b 10641static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
1da177e4 10642{
27c868c2
MW
10643 uchar read_back;
10644 int retry;
10645
10646 retry = 0;
10647 while (TRUE) {
10648 AscSetChipEEPCmd(iop_base, cmd_reg);
10649 DvcSleepMilliSecond(1);
10650 read_back = AscGetChipEEPCmd(iop_base);
10651 if (read_back == cmd_reg) {
10652 return (1);
10653 }
10654 if (retry++ > ASC_EEP_MAX_RETRY) {
10655 return (0);
10656 }
10657 }
1da177e4
LT
10658}
10659
78e77d8b 10660static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
1da177e4 10661{
27c868c2
MW
10662 ushort read_back;
10663 int retry;
10664
10665 retry = 0;
10666 while (TRUE) {
10667 AscSetChipEEPData(iop_base, data_reg);
10668 DvcSleepMilliSecond(1);
10669 read_back = AscGetChipEEPData(iop_base);
10670 if (read_back == data_reg) {
10671 return (1);
10672 }
10673 if (retry++ > ASC_EEP_MAX_RETRY) {
10674 return (0);
10675 }
10676 }
1da177e4
LT
10677}
10678
78e77d8b 10679static void __devinit AscWaitEEPRead(void)
1da177e4 10680{
27c868c2
MW
10681 DvcSleepMilliSecond(1);
10682 return;
1da177e4
LT
10683}
10684
78e77d8b 10685static void __devinit AscWaitEEPWrite(void)
1da177e4 10686{
27c868c2
MW
10687 DvcSleepMilliSecond(20);
10688 return;
1da177e4
LT
10689}
10690
78e77d8b 10691static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
1da177e4 10692{
27c868c2
MW
10693 ushort read_wval;
10694 uchar cmd_reg;
10695
10696 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
10697 AscWaitEEPRead();
10698 cmd_reg = addr | ASC_EEP_CMD_READ;
10699 AscWriteEEPCmdReg(iop_base, cmd_reg);
10700 AscWaitEEPRead();
10701 read_wval = AscGetChipEEPData(iop_base);
10702 AscWaitEEPRead();
10703 return (read_wval);
1da177e4
LT
10704}
10705
78e77d8b 10706static ushort __devinit
27c868c2 10707AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
1da177e4 10708{
27c868c2
MW
10709 ushort read_wval;
10710
10711 read_wval = AscReadEEPWord(iop_base, addr);
10712 if (read_wval != word_val) {
10713 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
10714 AscWaitEEPRead();
10715 AscWriteEEPDataReg(iop_base, word_val);
10716 AscWaitEEPRead();
10717 AscWriteEEPCmdReg(iop_base,
10718 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
10719 AscWaitEEPWrite();
10720 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
10721 AscWaitEEPRead();
10722 return (AscReadEEPWord(iop_base, addr));
10723 }
10724 return (read_wval);
1da177e4
LT
10725}
10726
78e77d8b 10727static ushort __devinit
27c868c2 10728AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 10729{
27c868c2
MW
10730 ushort wval;
10731 ushort sum;
10732 ushort *wbuf;
10733 int cfg_beg;
10734 int cfg_end;
10735 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
10736 int s_addr;
10737
10738 wbuf = (ushort *)cfg_buf;
10739 sum = 0;
10740 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
10741 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10742 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
10743 sum += *wbuf;
10744 }
10745 if (bus_type & ASC_IS_VL) {
10746 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10747 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10748 } else {
10749 cfg_beg = ASC_EEP_DVC_CFG_BEG;
10750 cfg_end = ASC_EEP_MAX_DVC_ADDR;
10751 }
10752 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
10753 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
10754 if (s_addr <= uchar_end_in_config) {
10755 /*
10756 * Swap all char fields - must unswap bytes already swapped
10757 * by AscReadEEPWord().
10758 */
10759 *wbuf = le16_to_cpu(wval);
10760 } else {
10761 /* Don't swap word field at the end - cntl field. */
10762 *wbuf = wval;
10763 }
10764 sum += wval; /* Checksum treats all EEPROM data as words. */
10765 }
10766 /*
10767 * Read the checksum word which will be compared against 'sum'
10768 * by the caller. Word field already swapped.
10769 */
10770 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
10771 return (sum);
1da177e4
LT
10772}
10773
78e77d8b 10774static int __devinit
27c868c2 10775AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 10776{
27c868c2
MW
10777 int n_error;
10778 ushort *wbuf;
10779 ushort word;
10780 ushort sum;
10781 int s_addr;
10782 int cfg_beg;
10783 int cfg_end;
10784 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
10785
10786 wbuf = (ushort *)cfg_buf;
10787 n_error = 0;
10788 sum = 0;
10789 /* Write two config words; AscWriteEEPWord() will swap bytes. */
10790 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10791 sum += *wbuf;
10792 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
10793 n_error++;
10794 }
10795 }
10796 if (bus_type & ASC_IS_VL) {
10797 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10798 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10799 } else {
10800 cfg_beg = ASC_EEP_DVC_CFG_BEG;
10801 cfg_end = ASC_EEP_MAX_DVC_ADDR;
10802 }
10803 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
10804 if (s_addr <= uchar_end_in_config) {
10805 /*
10806 * This is a char field. Swap char fields before they are
10807 * swapped again by AscWriteEEPWord().
10808 */
10809 word = cpu_to_le16(*wbuf);
10810 if (word !=
10811 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
10812 n_error++;
10813 }
10814 } else {
10815 /* Don't swap word field at the end - cntl field. */
10816 if (*wbuf !=
10817 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
10818 n_error++;
10819 }
10820 }
10821 sum += *wbuf; /* Checksum calculated from word values. */
10822 }
10823 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
10824 *wbuf = sum;
10825 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
10826 n_error++;
10827 }
1da177e4 10828
27c868c2
MW
10829 /* Read EEPROM back again. */
10830 wbuf = (ushort *)cfg_buf;
10831 /*
10832 * Read two config words; Byte-swapping done by AscReadEEPWord().
10833 */
10834 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10835 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
10836 n_error++;
10837 }
10838 }
10839 if (bus_type & ASC_IS_VL) {
10840 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10841 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10842 } else {
10843 cfg_beg = ASC_EEP_DVC_CFG_BEG;
10844 cfg_end = ASC_EEP_MAX_DVC_ADDR;
10845 }
10846 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
10847 if (s_addr <= uchar_end_in_config) {
10848 /*
10849 * Swap all char fields. Must unswap bytes already swapped
10850 * by AscReadEEPWord().
10851 */
10852 word =
10853 le16_to_cpu(AscReadEEPWord
10854 (iop_base, (uchar)s_addr));
10855 } else {
10856 /* Don't swap word field at the end - cntl field. */
10857 word = AscReadEEPWord(iop_base, (uchar)s_addr);
10858 }
10859 if (*wbuf != word) {
10860 n_error++;
10861 }
10862 }
10863 /* Read checksum; Byte swapping not needed. */
10864 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
10865 n_error++;
10866 }
10867 return (n_error);
1da177e4
LT
10868}
10869
78e77d8b 10870static int __devinit
27c868c2 10871AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 10872{
27c868c2
MW
10873 int retry;
10874 int n_error;
10875
10876 retry = 0;
10877 while (TRUE) {
10878 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
10879 bus_type)) == 0) {
10880 break;
10881 }
10882 if (++retry > ASC_EEP_MAX_RETRY) {
10883 break;
10884 }
10885 }
10886 return (n_error);
1da177e4
LT
10887}
10888
47d853cc 10889static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
1da177e4 10890{
47d853cc
MW
10891 char type = sdev->type;
10892 ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
27c868c2
MW
10893
10894 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
10895 if (!(asc_dvc->init_sdtr & tid_bits)) {
47d853cc
MW
10896 if ((type == TYPE_ROM) &&
10897 (strncmp(sdev->vendor, "HP ", 3) == 0)) {
27c868c2
MW
10898 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
10899 }
10900 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
47d853cc
MW
10901 if ((type == TYPE_PROCESSOR) ||
10902 (type == TYPE_SCANNER) || (type == TYPE_ROM) ||
10903 (type == TYPE_TAPE)) {
27c868c2
MW
10904 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
10905 }
10906
10907 if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
10908 AscSetRunChipSynRegAtID(asc_dvc->iop_base,
47d853cc
MW
10909 sdev->id,
10910 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
27c868c2
MW
10911 }
10912 }
10913 }
1da177e4
LT
10914}
10915
27c868c2 10916static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
1da177e4 10917{
27c868c2
MW
10918 uchar byte_data;
10919 ushort word_data;
10920
10921 if (isodd_word(addr)) {
10922 AscSetChipLramAddr(iop_base, addr - 1);
10923 word_data = AscGetChipLramData(iop_base);
10924 byte_data = (uchar)((word_data >> 8) & 0xFF);
10925 } else {
10926 AscSetChipLramAddr(iop_base, addr);
10927 word_data = AscGetChipLramData(iop_base);
10928 byte_data = (uchar)(word_data & 0xFF);
10929 }
10930 return (byte_data);
1da177e4 10931}
27c868c2
MW
10932
10933static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
1da177e4 10934{
27c868c2 10935 ushort word_data;
1da177e4 10936
27c868c2
MW
10937 AscSetChipLramAddr(iop_base, addr);
10938 word_data = AscGetChipLramData(iop_base);
10939 return (word_data);
1da177e4
LT
10940}
10941
10942#if CC_VERY_LONG_SG_LIST
27c868c2 10943static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
1da177e4 10944{
27c868c2
MW
10945 ushort val_low, val_high;
10946 ASC_DCNT dword_data;
10947
10948 AscSetChipLramAddr(iop_base, addr);
10949 val_low = AscGetChipLramData(iop_base);
10950 val_high = AscGetChipLramData(iop_base);
10951 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
10952 return (dword_data);
1da177e4
LT
10953}
10954#endif /* CC_VERY_LONG_SG_LIST */
10955
27c868c2 10956static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
1da177e4 10957{
27c868c2
MW
10958 AscSetChipLramAddr(iop_base, addr);
10959 AscSetChipLramData(iop_base, word_val);
10960 return;
1da177e4
LT
10961}
10962
27c868c2 10963static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
1da177e4 10964{
27c868c2
MW
10965 ushort word_data;
10966
10967 if (isodd_word(addr)) {
10968 addr--;
10969 word_data = AscReadLramWord(iop_base, addr);
10970 word_data &= 0x00FF;
10971 word_data |= (((ushort)byte_val << 8) & 0xFF00);
10972 } else {
10973 word_data = AscReadLramWord(iop_base, addr);
10974 word_data &= 0xFF00;
10975 word_data |= ((ushort)byte_val & 0x00FF);
10976 }
10977 AscWriteLramWord(iop_base, addr, word_data);
10978 return;
1da177e4
LT
10979}
10980
10981/*
10982 * Copy 2 bytes to LRAM.
10983 *
10984 * The source data is assumed to be in little-endian order in memory
10985 * and is maintained in little-endian order when written to LRAM.
10986 */
27c868c2
MW
10987static void
10988AscMemWordCopyPtrToLram(PortAddr iop_base,
10989 ushort s_addr, uchar *s_buffer, int words)
1da177e4 10990{
27c868c2
MW
10991 int i;
10992
10993 AscSetChipLramAddr(iop_base, s_addr);
10994 for (i = 0; i < 2 * words; i += 2) {
10995 /*
10996 * On a little-endian system the second argument below
10997 * produces a little-endian ushort which is written to
10998 * LRAM in little-endian order. On a big-endian system
10999 * the second argument produces a big-endian ushort which
11000 * is "transparently" byte-swapped by outpw() and written
11001 * in little-endian order to LRAM.
11002 */
11003 outpw(iop_base + IOP_RAM_DATA,
11004 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
11005 }
11006 return;
1da177e4
LT
11007}
11008
11009/*
11010 * Copy 4 bytes to LRAM.
11011 *
11012 * The source data is assumed to be in little-endian order in memory
11013 * and is maintained in little-endian order when writen to LRAM.
11014 */
27c868c2
MW
11015static void
11016AscMemDWordCopyPtrToLram(PortAddr iop_base,
11017 ushort s_addr, uchar *s_buffer, int dwords)
1da177e4 11018{
27c868c2
MW
11019 int i;
11020
11021 AscSetChipLramAddr(iop_base, s_addr);
11022 for (i = 0; i < 4 * dwords; i += 4) {
11023 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
11024 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
11025 }
11026 return;
1da177e4
LT
11027}
11028
11029/*
11030 * Copy 2 bytes from LRAM.
11031 *
11032 * The source data is assumed to be in little-endian order in LRAM
11033 * and is maintained in little-endian order when written to memory.
11034 */
27c868c2
MW
11035static void
11036AscMemWordCopyPtrFromLram(PortAddr iop_base,
11037 ushort s_addr, uchar *d_buffer, int words)
1da177e4 11038{
27c868c2
MW
11039 int i;
11040 ushort word;
11041
11042 AscSetChipLramAddr(iop_base, s_addr);
11043 for (i = 0; i < 2 * words; i += 2) {
11044 word = inpw(iop_base + IOP_RAM_DATA);
11045 d_buffer[i] = word & 0xff;
11046 d_buffer[i + 1] = (word >> 8) & 0xff;
11047 }
11048 return;
1da177e4
LT
11049}
11050
27c868c2 11051static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
1da177e4 11052{
27c868c2
MW
11053 ASC_DCNT sum;
11054 int i;
1da177e4 11055
27c868c2
MW
11056 sum = 0L;
11057 for (i = 0; i < words; i++, s_addr += 2) {
11058 sum += AscReadLramWord(iop_base, s_addr);
11059 }
11060 return (sum);
1da177e4
LT
11061}
11062
27c868c2
MW
11063static void
11064AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
1da177e4 11065{
27c868c2 11066 int i;
1da177e4 11067
27c868c2
MW
11068 AscSetChipLramAddr(iop_base, s_addr);
11069 for (i = 0; i < words; i++) {
11070 AscSetChipLramData(iop_base, set_wval);
11071 }
11072 return;
1da177e4
LT
11073}
11074
1da177e4
LT
11075/*
11076 * --- Adv Library Functions
11077 */
11078
11079/* a_mcode.h */
11080
11081/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
11082static unsigned char _adv_asc3550_buf[] = {
11083 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
11084 0x01, 0x00, 0x48, 0xe4,
11085 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff,
11086 0x28, 0x0e, 0x9e, 0xe7,
11087 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7,
11088 0x55, 0xf0, 0x01, 0xf6,
11089 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
11090 0x00, 0xec, 0x85, 0xf0,
11091 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0,
11092 0x86, 0xf0, 0xb4, 0x00,
11093 0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00,
11094 0xaa, 0x18, 0x02, 0x80,
11095 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
11096 0x00, 0x57, 0x01, 0xea,
11097 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80,
11098 0x03, 0xe6, 0xb6, 0x00,
11099 0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12,
11100 0x02, 0x4a, 0xb9, 0x54,
11101 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
11102 0x3e, 0x00, 0x80, 0x00,
11103 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
11104 0x74, 0x01, 0x76, 0x01,
11105 0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13,
11106 0x4c, 0x1c, 0xbb, 0x55,
11107 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
11108 0x03, 0xf7, 0x06, 0xf7,
11109 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08,
11110 0x30, 0x13, 0x64, 0x15,
11111 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c,
11112 0x04, 0xea, 0x5d, 0xf0,
11113 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
11114 0xcc, 0x00, 0x20, 0x01,
11115 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13,
11116 0x40, 0x13, 0x30, 0x1c,
11117 0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
11118 0x59, 0xf0, 0xa7, 0xf0,
11119 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
11120 0xa4, 0x00, 0xb5, 0x00,
11121 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a,
11122 0x14, 0x0e, 0x02, 0x10,
11123 0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13,
11124 0x10, 0x15, 0x14, 0x15,
11125 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
11126 0x91, 0x44, 0x0a, 0x45,
11127 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58,
11128 0x83, 0x59, 0x05, 0xe6,
11129 0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8,
11130 0x02, 0xfa, 0x03, 0xfa,
11131 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
11132 0x9e, 0x00, 0xa8, 0x00,
11133 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01,
11134 0x7a, 0x01, 0xc0, 0x01,
11135 0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08,
11136 0x69, 0x08, 0xba, 0x08,
11137 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
11138 0xf1, 0x10, 0x06, 0x12,
11139 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14,
11140 0x8a, 0x15, 0xc6, 0x17,
11141 0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
11142 0x0e, 0x47, 0x48, 0x47,
11143 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
11144 0x14, 0x56, 0x77, 0x57,
11145 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c,
11146 0xf0, 0x29, 0x02, 0xfe,
11147 0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf,
11148 0xfe, 0x80, 0x01, 0xff,
11149 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
11150 0x00, 0xfe, 0x57, 0x24,
11151 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09,
11152 0x00, 0x00, 0xff, 0x08,
11153 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
11154 0xff, 0xff, 0xff, 0x0f,
11155 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
11156 0xfe, 0x04, 0xf7, 0xcf,
11157 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67,
11158 0x0b, 0x3c, 0x2a, 0xfe,
11159 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0,
11160 0xfe, 0xf0, 0x01, 0xfe,
11161 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
11162 0x02, 0xfe, 0xd4, 0x0c,
11163 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
11164 0x1c, 0x05, 0xfe, 0xa6,
11165 0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48,
11166 0xf0, 0xfe, 0x86, 0x02,
11167 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
11168 0xfe, 0x46, 0xf0, 0xfe,
11169 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
11170 0x44, 0x02, 0xfe, 0x44,
11171 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b,
11172 0xa0, 0x17, 0x06, 0x18,
11173 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
11174 0x1e, 0x1c, 0xfe, 0xe9,
11175 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7,
11176 0x0a, 0x6b, 0x01, 0x9e,
11177 0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b,
11178 0x01, 0x82, 0xfe, 0xbd,
11179 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
11180 0x58, 0x1c, 0x17, 0x06,
11181 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21,
11182 0xfe, 0x94, 0x02, 0xfe,
11183 0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97,
11184 0x01, 0xfe, 0x54, 0x0f,
11185 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
11186 0x69, 0x10, 0x17, 0x06,
11187 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05,
11188 0xf6, 0xc7, 0x01, 0xfe,
11189 0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6,
11190 0x02, 0x29, 0x0a, 0x40,
11191 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
11192 0x58, 0x0a, 0x99, 0x01,
11193 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29,
11194 0x2a, 0x46, 0xfe, 0x02,
11195 0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc,
11196 0x01, 0xfe, 0x07, 0x4b,
11197 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
11198 0xfe, 0x56, 0x03, 0xfe,
11199 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10,
11200 0xfe, 0x9f, 0xf0, 0xfe,
11201 0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48,
11202 0x1c, 0xeb, 0x09, 0x04,
11203 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
11204 0x01, 0x0e, 0xac, 0x75,
11205 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2,
11206 0xfe, 0x82, 0xf0, 0xfe,
11207 0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25,
11208 0x32, 0x1f, 0xfe, 0xb4,
11209 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
11210 0x0a, 0xf0, 0xfe, 0x7a,
11211 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c,
11212 0x01, 0x33, 0x8f, 0xfe,
11213 0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8,
11214 0xf7, 0xfe, 0x48, 0x1c,
11215 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
11216 0x0a, 0xca, 0x01, 0x0e,
11217 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14,
11218 0x2c, 0x01, 0x33, 0x8f,
11219 0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65,
11220 0xfe, 0x3c, 0x04, 0x1f,
11221 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
11222 0x12, 0x2b, 0xff, 0x02,
11223 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f,
11224 0x22, 0x30, 0x2e, 0xd5,
11225 0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c,
11226 0xfe, 0x4c, 0x54, 0x64,
11227 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
11228 0xfe, 0x2a, 0x13, 0x2f,
11229 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
11230 0xd3, 0xfa, 0xef, 0x86,
11231 0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04,
11232 0x1d, 0xfe, 0x1c, 0x12,
11233 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
11234 0x70, 0x0c, 0x02, 0x22,
11235 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92,
11236 0x01, 0x33, 0x02, 0x29,
11237 0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87,
11238 0x80, 0xfe, 0x31, 0xe4,
11239 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
11240 0xfe, 0x70, 0x12, 0x49,
11241 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe,
11242 0x80, 0x05, 0xfe, 0x31,
11243 0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00,
11244 0x28, 0xfe, 0x42, 0x12,
11245 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
11246 0x11, 0xfe, 0xe3, 0x00,
11247 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
11248 0x64, 0x05, 0x83, 0x24,
11249 0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe,
11250 0x09, 0x48, 0x01, 0x08,
11251 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
11252 0x86, 0x24, 0x06, 0x12,
11253 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47,
11254 0x01, 0xa7, 0x14, 0x92,
11255 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c,
11256 0x02, 0x22, 0x05, 0xfe,
11257 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
11258 0x47, 0x01, 0xa7, 0x26,
11259 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f,
11260 0x01, 0xfe, 0xaa, 0x14,
11261 0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00,
11262 0x05, 0x50, 0xb4, 0x0c,
11263 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
11264 0x13, 0x01, 0xfe, 0x14,
11265 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c,
11266 0xff, 0x02, 0x00, 0x57,
11267 0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe,
11268 0x72, 0x06, 0x49, 0x04,
11269 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
11270 0x06, 0x11, 0x9a, 0x01,
11271 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06,
11272 0x01, 0xa7, 0xec, 0x72,
11273 0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32,
11274 0xfe, 0x0a, 0xf0, 0xfe,
11275 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
11276 0x8d, 0x81, 0x02, 0x22,
11277 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00,
11278 0x01, 0x08, 0x15, 0x00,
11279 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15,
11280 0x00, 0x02, 0xfe, 0x32,
11281 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
11282 0xfe, 0x1b, 0x00, 0x01,
11283 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
11284 0x08, 0x15, 0x06, 0x01,
11285 0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe,
11286 0x9a, 0x81, 0x4b, 0x1d,
11287 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
11288 0x45, 0xfe, 0x32, 0x12,
11289 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0,
11290 0xfe, 0x32, 0x07, 0x8d,
11291 0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a,
11292 0x06, 0x15, 0x19, 0x02,
11293 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
11294 0x90, 0x77, 0xfe, 0xca,
11295 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07,
11296 0x10, 0xfe, 0x0e, 0x12,
11297 0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe,
11298 0x83, 0xe7, 0xc4, 0xa1,
11299 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
11300 0x40, 0x12, 0x58, 0x01,
11301 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6,
11302 0x51, 0x83, 0xfb, 0xfe,
11303 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90,
11304 0xfe, 0x40, 0x50, 0xfe,
11305 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
11306 0xfe, 0x2a, 0x12, 0xfe,
11307 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f,
11308 0x85, 0x01, 0xa8, 0xfe,
11309 0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56,
11310 0x18, 0x57, 0xfb, 0xfe,
11311 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
11312 0x0c, 0x39, 0x18, 0x3a,
11313 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e,
11314 0x11, 0x65, 0xfe, 0x48,
11315 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73,
11316 0xdd, 0xb8, 0xfe, 0x80,
11317 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
11318 0xfe, 0x7a, 0x08, 0x8d,
11319 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9,
11320 0x10, 0x61, 0x04, 0x06,
11321 0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68,
11322 0x12, 0xfe, 0x2e, 0x1c,
11323 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
11324 0x52, 0x12, 0xfe, 0x2c,
11325 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe,
11326 0x08, 0xfe, 0x8a, 0x10,
11327 0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe,
11328 0x24, 0x0a, 0xab, 0xfe,
11329 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
11330 0x1c, 0x12, 0xb5, 0xfe,
11331 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb,
11332 0x1c, 0x06, 0x16, 0x9d,
11333 0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b,
11334 0x14, 0x92, 0x01, 0x33,
11335 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
11336 0xfe, 0x74, 0x18, 0x1c,
11337 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b,
11338 0x01, 0xe6, 0x1e, 0x27,
11339 0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a,
11340 0x09, 0x04, 0x6a, 0xfe,
11341 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
11342 0xfe, 0x83, 0x80, 0xfe,
11343 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63,
11344 0x27, 0xfe, 0x40, 0x59,
11345 0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18,
11346 0x7c, 0xbe, 0x54, 0xbf,
11347 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
11348 0x79, 0x56, 0x68, 0x57,
11349 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5,
11350 0xa2, 0x23, 0x0c, 0x7b,
11351 0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19,
11352 0x16, 0xd7, 0x79, 0x39,
11353 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
11354 0xfe, 0x10, 0x58, 0xfe,
11355 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04,
11356 0x19, 0x16, 0xd7, 0x09,
11357 0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f,
11358 0xfe, 0x10, 0x90, 0xfe,
11359 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
11360 0x11, 0x9b, 0x09, 0x04,
11361 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08,
11362 0xfe, 0x0c, 0x58, 0xfe,
11363 0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04,
11364 0x0b, 0xfe, 0x1a, 0x12,
11365 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
11366 0x14, 0x7a, 0x01, 0x33,
11367 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39,
11368 0xfe, 0xed, 0x19, 0xbf,
11369 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff,
11370 0x34, 0xfe, 0x74, 0x10,
11371 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
11372 0x84, 0x05, 0xcb, 0x1c,
11373 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1,
11374 0xf0, 0xfe, 0xc4, 0x0a,
11375 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe,
11376 0xce, 0xf0, 0xfe, 0xca,
11377 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
11378 0x22, 0x00, 0x02, 0x5a,
11379 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a,
11380 0xfe, 0xd0, 0xf0, 0xfe,
11381 0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f,
11382 0x4c, 0xfe, 0x10, 0x10,
11383 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
11384 0x2a, 0x13, 0xfe, 0x4e,
11385 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1,
11386 0x16, 0x32, 0x2a, 0x73,
11387 0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25,
11388 0x32, 0x8c, 0xfe, 0x48,
11389 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
11390 0xdb, 0x10, 0x11, 0xfe,
11391 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0,
11392 0x22, 0x30, 0x2e, 0xd8,
11393 0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1,
11394 0x45, 0x0f, 0xfe, 0x42,
11395 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
11396 0x09, 0x04, 0x0b, 0xfe,
11397 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28,
11398 0x00, 0x21, 0xfe, 0xa6,
11399 0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00,
11400 0xfe, 0xe2, 0x10, 0x01,
11401 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
11402 0x01, 0x6f, 0x02, 0x29,
11403 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10,
11404 0x01, 0x86, 0x3e, 0x0b,
11405 0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3,
11406 0x3e, 0x0b, 0x0f, 0xfe,
11407 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
11408 0xe8, 0x59, 0x11, 0x2d,
11409 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09,
11410 0x04, 0x0b, 0x84, 0x3e,
11411 0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12,
11412 0x09, 0x04, 0x1b, 0xfe,
11413 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
11414 0x1c, 0x1c, 0xfe, 0x9d,
11415 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f,
11416 0xfe, 0x15, 0x00, 0xfe,
11417 0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10,
11418 0x0f, 0xfe, 0x47, 0x00,
11419 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
11420 0xab, 0x70, 0x05, 0x6b,
11421 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe,
11422 0x1c, 0x42, 0x59, 0x01,
11423 0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31,
11424 0x00, 0x37, 0x97, 0x01,
11425 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
11426 0x1d, 0xfe, 0xce, 0x45,
11427 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75,
11428 0x57, 0x05, 0x51, 0xfe,
11429 0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48,
11430 0x46, 0x09, 0x04, 0x1d,
11431 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
11432 0x99, 0x01, 0x0e, 0xfe,
11433 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51,
11434 0xfe, 0xee, 0x14, 0xee,
11435 0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad,
11436 0x13, 0x02, 0x29, 0x1e,
11437 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
11438 0xce, 0x1e, 0x2d, 0x47,
11439 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06,
11440 0x12, 0x4d, 0x01, 0xfe,
11441 0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe,
11442 0xf0, 0x0d, 0xfe, 0x02,
11443 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
11444 0xf6, 0xfe, 0x34, 0x01,
11445 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13,
11446 0xaf, 0xfe, 0x02, 0xea,
11447 0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c,
11448 0x05, 0xfe, 0x38, 0x01,
11449 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
11450 0x0c, 0xfe, 0x62, 0x01,
11451 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06,
11452 0x03, 0x23, 0x03, 0x1e,
11453 0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe,
11454 0x71, 0x13, 0xfe, 0x24,
11455 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
11456 0xdc, 0xfe, 0x73, 0x57,
11457 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe,
11458 0x80, 0x5d, 0x03, 0xfe,
11459 0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6,
11460 0x75, 0x03, 0x09, 0x04,
11461 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
11462 0xfe, 0x1e, 0x80, 0xe1,
11463 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e,
11464 0x90, 0xa3, 0xfe, 0x3c,
11465 0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82,
11466 0x16, 0x2f, 0x07, 0x2d,
11467 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
11468 0xe8, 0x11, 0xfe, 0xe9,
11469 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe,
11470 0x1e, 0x1c, 0xfe, 0x14,
11471 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01,
11472 0x09, 0x04, 0x4f, 0xfe,
11473 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
11474 0x40, 0x12, 0x20, 0x63,
11475 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08,
11476 0x1c, 0x05, 0xfe, 0xac,
11477 0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05,
11478 0xfe, 0xb0, 0x00, 0xfe,
11479 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
11480 0x24, 0x69, 0x12, 0xc9,
11481 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe,
11482 0x90, 0x4d, 0xfe, 0x91,
11483 0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c,
11484 0xfe, 0x90, 0x4d, 0xfe,
11485 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
11486 0x46, 0x1e, 0x20, 0xed,
11487 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea,
11488 0x70, 0xfe, 0x14, 0x1c,
11489 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee,
11490 0xfe, 0x07, 0xe6, 0x1d,
11491 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
11492 0xfa, 0xef, 0xfe, 0x42,
11493 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0,
11494 0xfe, 0x36, 0x12, 0xf0,
11495 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
11496 0x3d, 0x75, 0x07, 0x10,
11497 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
11498 0x10, 0x07, 0x7e, 0x45,
11499 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74,
11500 0xfe, 0x01, 0xec, 0x97,
11501 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76,
11502 0x27, 0x01, 0xda, 0xfe,
11503 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
11504 0xfe, 0x48, 0x12, 0x07,
11505 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16,
11506 0xfe, 0x3e, 0x11, 0x07,
11507 0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8,
11508 0x11, 0x07, 0x19, 0xfe,
11509 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
11510 0x01, 0x08, 0x8c, 0x43,
11511 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11,
11512 0x7e, 0x02, 0x29, 0x2b,
11513 0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe,
11514 0xfc, 0x10, 0x09, 0x04,
11515 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
11516 0xc6, 0x10, 0x1e, 0x58,
11517 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c,
11518 0x54, 0x18, 0x55, 0x23,
11519 0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01,
11520 0xa5, 0xc0, 0x38, 0xc1,
11521 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
11522 0x05, 0xfa, 0x4e, 0xfe,
11523 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56,
11524 0x0c, 0x56, 0x18, 0x57,
11525 0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe,
11526 0x00, 0x56, 0xfe, 0xa1,
11527 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
11528 0x58, 0xfe, 0x1f, 0x40,
11529 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56,
11530 0x31, 0x57, 0xfe, 0x44,
11531 0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe,
11532 0x8a, 0x50, 0x05, 0x39,
11533 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
11534 0x12, 0xcd, 0x02, 0x5b,
11535 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44,
11536 0x2f, 0x07, 0x9b, 0x21,
11537 0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79,
11538 0x39, 0x68, 0x3a, 0xfe,
11539 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
11540 0x51, 0xfe, 0x8e, 0x51,
11541 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b,
11542 0x01, 0x08, 0x25, 0x32,
11543 0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b,
11544 0x3b, 0x02, 0x44, 0x01,
11545 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
11546 0x01, 0x08, 0x1f, 0xa2,
11547 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c,
11548 0x00, 0x28, 0x84, 0x49,
11549 0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06,
11550 0x78, 0x3d, 0xfe, 0xda,
11551 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
11552 0x05, 0xc6, 0x28, 0x84,
11553 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8,
11554 0x14, 0xfe, 0x03, 0x17,
11555 0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01,
11556 0xfe, 0xaa, 0x14, 0x02,
11557 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
11558 0x21, 0x44, 0x01, 0xfe,
11559 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87,
11560 0xfe, 0x4a, 0xf4, 0x0b,
11561 0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a,
11562 0x85, 0x02, 0x5b, 0x05,
11563 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
11564 0xd8, 0x14, 0x02, 0x5c,
11565 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1,
11566 0x01, 0x08, 0x23, 0x72,
11567 0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca,
11568 0x12, 0x5e, 0x2b, 0x01,
11569 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
11570 0x1c, 0xfe, 0xff, 0x7f,
11571 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00,
11572 0x57, 0x48, 0x8b, 0x1c,
11573 0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02,
11574 0x00, 0x57, 0x48, 0x8b,
11575 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
11576 0x03, 0x0a, 0x50, 0x01,
11577 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00,
11578 0x54, 0xfe, 0x00, 0xf4,
11579 0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe,
11580 0x03, 0x7c, 0x63, 0x27,
11581 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
11582 0xfe, 0x82, 0x4a, 0xfe,
11583 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe,
11584 0x42, 0x48, 0x5f, 0x60,
11585 0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08,
11586 0x1f, 0xfe, 0xa2, 0x14,
11587 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
11588 0xcc, 0x12, 0x49, 0x04,
11589 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe,
11590 0xe8, 0x13, 0x3b, 0x13,
11591 0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55,
11592 0xa1, 0xff, 0x02, 0x83,
11593 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
11594 0x13, 0x06, 0xfe, 0x56,
11595 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe,
11596 0x64, 0x00, 0x17, 0x93,
11597 0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe,
11598 0xc8, 0x00, 0x8e, 0xe4,
11599 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
11600 0x01, 0xba, 0xfe, 0x4e,
11601 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0,
11602 0xfe, 0x60, 0x14, 0xfe,
11603 0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01,
11604 0xfe, 0x22, 0x13, 0x1c,
11605 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
11606 0xfe, 0x9c, 0x14, 0xb7,
11607 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba,
11608 0xfe, 0x9c, 0x14, 0xb7,
11609 0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06,
11610 0xfe, 0xb4, 0x56, 0xfe,
11611 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
11612 0xe5, 0x15, 0x0b, 0x01,
11613 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89,
11614 0x49, 0x01, 0x08, 0x03,
11615 0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6,
11616 0x15, 0x06, 0x01, 0x08,
11617 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
11618 0x4a, 0x01, 0x08, 0x03,
11619 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc,
11620 0xfe, 0x49, 0xf4, 0x00,
11621 0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01,
11622 0x08, 0x2f, 0x07, 0xfe,
11623 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
11624 0x01, 0x43, 0x1e, 0xcd,
11625 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e,
11626 0xed, 0x88, 0x07, 0x10,
11627 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a,
11628 0x80, 0x01, 0x0e, 0x88,
11629 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
11630 0x88, 0x03, 0x0a, 0x42,
11631 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e,
11632 0xfe, 0x80, 0x80, 0xf2,
11633 0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51,
11634 0x01, 0x82, 0x03, 0x17,
11635 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
11636 0xfe, 0x24, 0x1c, 0xfe,
11637 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0,
11638 0x91, 0x1d, 0x66, 0xfe,
11639 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe,
11640 0xda, 0x10, 0x17, 0x10,
11641 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
11642 0x05, 0xfe, 0x66, 0x01,
11643 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06,
11644 0xfe, 0x3c, 0x50, 0x66,
11645 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe,
11646 0x40, 0x16, 0xfe, 0xb6,
11647 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
11648 0x10, 0x71, 0xfe, 0x83,
11649 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90,
11650 0xfe, 0x62, 0x16, 0xfe,
11651 0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19,
11652 0xfe, 0x98, 0xe7, 0x00,
11653 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
11654 0xfe, 0x30, 0xbc, 0xfe,
11655 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
11656 0xc5, 0x90, 0xfe, 0x9a,
11657 0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe,
11658 0x42, 0x10, 0xfe, 0x02,
11659 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
11660 0xfe, 0x1d, 0xf7, 0x4f,
11661 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f,
11662 0x47, 0xfe, 0x83, 0x58,
11663 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11,
11664 0xfe, 0xdd, 0x00, 0x63,
11665 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
11666 0x06, 0x37, 0x95, 0xa9,
11667 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e,
11668 0x18, 0x1c, 0x1a, 0x5d,
11669 0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe,
11670 0xe1, 0x10, 0x78, 0x2c,
11671 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
11672 0x13, 0x3c, 0x8a, 0x0a,
11673 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
11674 0xe3, 0xfe, 0x00, 0xcc,
11675 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01,
11676 0x0e, 0xf2, 0x01, 0x6f,
11677 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
11678 0xf6, 0xfe, 0xd6, 0xf0,
11679 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe,
11680 0x15, 0x00, 0x59, 0x76,
11681 0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35,
11682 0x11, 0x2d, 0x01, 0x6f,
11683 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
11684 0xc8, 0xfe, 0x48, 0x55,
11685 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a,
11686 0x99, 0x01, 0x0e, 0xf0,
11687 0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73,
11688 0x75, 0x03, 0x0a, 0x42,
11689 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
11690 0x0e, 0x73, 0x75, 0x03,
11691 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00,
11692 0xfe, 0x3a, 0x45, 0x5b,
11693 0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00,
11694 0xfe, 0x02, 0xe6, 0x1b,
11695 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
11696 0xfe, 0x94, 0x00, 0xfe,
11697 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02,
11698 0xe6, 0x2c, 0xfe, 0x4e,
11699 0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69,
11700 0x03, 0x07, 0x7a, 0xfe,
11701 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
11702 0x07, 0x1b, 0xfe, 0x5a,
11703 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d,
11704 0x24, 0x2c, 0xdc, 0x07,
11705 0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d,
11706 0x9f, 0xad, 0x03, 0x14,
11707 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
11708 0x03, 0x25, 0xfe, 0xca,
11709 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a,
11710 0x00, 0x00,
1da177e4
LT
11711};
11712
27c868c2
MW
11713static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
11714static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
1da177e4
LT
11715
11716/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
11717static unsigned char _adv_asc38C0800_buf[] = {
11718 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
11719 0x01, 0x00, 0x48, 0xe4,
11720 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff,
11721 0x1c, 0x0f, 0x00, 0xf6,
11722 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6,
11723 0x09, 0xe7, 0x55, 0xf0,
11724 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
11725 0x18, 0xf4, 0x08, 0x00,
11726 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6,
11727 0x86, 0xf0, 0xb1, 0xf0,
11728 0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c,
11729 0x3c, 0x00, 0xbb, 0x00,
11730 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
11731 0xba, 0x13, 0x18, 0x40,
11732 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01,
11733 0x6e, 0x01, 0x74, 0x01,
11734 0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00,
11735 0xc0, 0x00, 0x01, 0x01,
11736 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
11737 0x08, 0x12, 0x02, 0x4a,
11738 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4,
11739 0x5d, 0xf0, 0x02, 0xfa,
11740 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01,
11741 0x68, 0x01, 0x6a, 0x01,
11742 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
11743 0x06, 0x13, 0x4c, 0x1c,
11744 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00,
11745 0x0f, 0x00, 0x47, 0x00,
11746 0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c,
11747 0x4e, 0x1c, 0x10, 0x44,
11748 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
11749 0x05, 0x00, 0x34, 0x00,
11750 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b,
11751 0x42, 0x0c, 0x12, 0x0f,
11752 0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48,
11753 0x00, 0x4e, 0x42, 0x54,
11754 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
11755 0x59, 0xf0, 0xb8, 0xf0,
11756 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00,
11757 0x19, 0x00, 0x33, 0x00,
11758 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00,
11759 0xe7, 0x00, 0xe2, 0x03,
11760 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
11761 0x12, 0x13, 0x24, 0x14,
11762 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c,
11763 0x36, 0x1c, 0x08, 0x44,
11764 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54,
11765 0x3a, 0x55, 0x83, 0x55,
11766 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
11767 0x0c, 0xf0, 0x04, 0xf8,
11768 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00,
11769 0xa8, 0x00, 0xaa, 0x00,
11770 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01,
11771 0xc4, 0x01, 0xc6, 0x01,
11772 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
11773 0x68, 0x08, 0x69, 0x08,
11774 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10,
11775 0xed, 0x10, 0xf1, 0x10,
11776 0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13,
11777 0x1e, 0x13, 0x46, 0x14,
11778 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
11779 0xca, 0x18, 0xe6, 0x19,
11780 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c,
11781 0xf0, 0x2b, 0x02, 0xfe,
11782 0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6,
11783 0xfe, 0x84, 0x01, 0xff,
11784 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
11785 0x00, 0xfe, 0x57, 0x24,
11786 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09,
11787 0x00, 0x00, 0xff, 0x08,
11788 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
11789 0xff, 0xff, 0xff, 0x11,
11790 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
11791 0xfe, 0x04, 0xf7, 0xd6,
11792 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99,
11793 0x0a, 0x42, 0x2c, 0xfe,
11794 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0,
11795 0xfe, 0xf4, 0x01, 0xfe,
11796 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
11797 0x02, 0xfe, 0xc8, 0x0d,
11798 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
11799 0x1c, 0x03, 0xfe, 0xa6,
11800 0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48,
11801 0xf0, 0xfe, 0x8a, 0x02,
11802 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
11803 0xfe, 0x46, 0xf0, 0xfe,
11804 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
11805 0x48, 0x02, 0xfe, 0x44,
11806 0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a,
11807 0xaa, 0x18, 0x06, 0x14,
11808 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
11809 0x1e, 0x1c, 0xfe, 0xe9,
11810 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce,
11811 0x09, 0x70, 0x01, 0xa8,
11812 0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70,
11813 0x01, 0x87, 0xfe, 0xbd,
11814 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
11815 0x58, 0x1c, 0x18, 0x06,
11816 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23,
11817 0xfe, 0x98, 0x02, 0xfe,
11818 0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2,
11819 0x01, 0xfe, 0x48, 0x10,
11820 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
11821 0x69, 0x10, 0x18, 0x06,
11822 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05,
11823 0xf6, 0xce, 0x01, 0xfe,
11824 0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe,
11825 0x82, 0x16, 0x02, 0x2b,
11826 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
11827 0xfe, 0x41, 0x58, 0x09,
11828 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe,
11829 0x82, 0x16, 0x02, 0x2b,
11830 0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43,
11831 0xfe, 0x77, 0x57, 0xfe,
11832 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
11833 0xfe, 0x40, 0x1c, 0x1c,
11834 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48,
11835 0x03, 0xfe, 0x11, 0xf0,
11836 0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10,
11837 0xfe, 0x11, 0x00, 0x02,
11838 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
11839 0x21, 0x22, 0xa3, 0xb7,
11840 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16,
11841 0x12, 0xd1, 0x1c, 0xd9,
11842 0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12,
11843 0xfe, 0xe4, 0x00, 0x27,
11844 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
11845 0x06, 0xf0, 0xfe, 0xc8,
11846 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03,
11847 0x70, 0x28, 0x17, 0xfe,
11848 0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8,
11849 0xf9, 0x2c, 0x99, 0x19,
11850 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
11851 0x74, 0x01, 0xaf, 0x8c,
11852 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e,
11853 0x8d, 0x51, 0x64, 0x79,
11854 0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b,
11855 0xfe, 0x6a, 0x02, 0x02,
11856 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
11857 0xfe, 0x3c, 0x04, 0x3b,
11858 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02,
11859 0x00, 0x10, 0x01, 0x0b,
11860 0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde,
11861 0xfe, 0x4c, 0x44, 0xfe,
11862 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
11863 0xda, 0x4f, 0x79, 0x2a,
11864 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b,
11865 0xfe, 0x2a, 0x13, 0x32,
11866 0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c,
11867 0x54, 0x6b, 0xda, 0xfe,
11868 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
11869 0x08, 0x13, 0x32, 0x07,
11870 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d,
11871 0x08, 0x05, 0x06, 0x4d,
11872 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24,
11873 0x2d, 0x12, 0xfe, 0xe6,
11874 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
11875 0x02, 0x2b, 0xfe, 0x42,
11876 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
11877 0xfe, 0x87, 0x80, 0xfe,
11878 0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80,
11879 0x07, 0x19, 0xfe, 0x7c,
11880 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
11881 0x17, 0xfe, 0x90, 0x05,
11882 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe,
11883 0xa0, 0x00, 0x28, 0xfe,
11884 0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c,
11885 0x34, 0xfe, 0x89, 0x48,
11886 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
11887 0x12, 0xfe, 0xe3, 0x00,
11888 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
11889 0x70, 0x05, 0x88, 0x25,
11890 0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe,
11891 0x09, 0x48, 0xff, 0x02,
11892 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
11893 0x08, 0x53, 0x05, 0xcb,
11894 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08,
11895 0x05, 0x1b, 0xfe, 0x22,
11896 0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe,
11897 0x0d, 0x00, 0x01, 0x36,
11898 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
11899 0x03, 0x5c, 0x28, 0xfe,
11900 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53,
11901 0x05, 0x1f, 0xfe, 0x02,
11902 0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5,
11903 0x01, 0x4b, 0x12, 0xfe,
11904 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
11905 0x12, 0x03, 0x45, 0x28,
11906 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe,
11907 0x43, 0x48, 0xc4, 0xcc,
11908 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4,
11909 0x6e, 0x41, 0x01, 0xb2,
11910 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
11911 0xfe, 0xcc, 0x15, 0x1d,
11912 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03,
11913 0x45, 0xc1, 0x0c, 0x45,
11914 0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe,
11915 0xe2, 0x00, 0x27, 0xdb,
11916 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
11917 0xfe, 0x06, 0xf0, 0xfe,
11918 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12,
11919 0x16, 0x19, 0x01, 0x0b,
11920 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
11921 0xfe, 0x99, 0xa4, 0x01,
11922 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
11923 0x12, 0x08, 0x05, 0x1a,
11924 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
11925 0x0b, 0x16, 0x00, 0x01,
11926 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02,
11927 0xe2, 0x6c, 0x58, 0xbe,
11928 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
11929 0xfe, 0x09, 0x6f, 0xba,
11930 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27,
11931 0xfe, 0x54, 0x07, 0x1c,
11932 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c,
11933 0x07, 0x02, 0x24, 0x01,
11934 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
11935 0x2c, 0x90, 0xfe, 0xae,
11936 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a,
11937 0x37, 0x22, 0x20, 0x07,
11938 0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a,
11939 0xfe, 0x06, 0x10, 0xfe,
11940 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
11941 0x37, 0x01, 0xb3, 0xb8,
11942 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a,
11943 0x50, 0xfe, 0x44, 0x51,
11944 0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e,
11945 0x14, 0x5f, 0xfe, 0x0c,
11946 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
11947 0x14, 0x3e, 0xfe, 0x4a,
11948 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
11949 0x90, 0x0c, 0x60, 0x14,
11950 0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62,
11951 0xfe, 0x44, 0x90, 0xfe,
11952 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
11953 0x0c, 0x5e, 0x14, 0x5f,
11954 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e,
11955 0x14, 0x3c, 0x21, 0x0c,
11956 0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11,
11957 0x27, 0xdd, 0xfe, 0x9e,
11958 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
11959 0x9a, 0x08, 0xc6, 0xfe,
11960 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08,
11961 0x95, 0x86, 0x02, 0x24,
11962 0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05,
11963 0x06, 0xfe, 0x10, 0x12,
11964 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
11965 0x1c, 0x02, 0xfe, 0x18,
11966 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe,
11967 0x2c, 0x1c, 0xfe, 0xaa,
11968 0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe,
11969 0xde, 0x09, 0xfe, 0xb7,
11970 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
11971 0xfe, 0xf1, 0x18, 0xfe,
11972 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe,
11973 0x14, 0x59, 0xfe, 0x95,
11974 0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0,
11975 0xfe, 0xf0, 0x08, 0xb5,
11976 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
11977 0x0b, 0xb6, 0xfe, 0xbf,
11978 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c,
11979 0x12, 0xc2, 0xfe, 0xd2,
11980 0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e,
11981 0x06, 0x17, 0x85, 0xc5,
11982 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
11983 0x9d, 0x01, 0x36, 0x10,
11984 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe,
11985 0x98, 0x80, 0xfe, 0x19,
11986 0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18,
11987 0xfe, 0x44, 0x54, 0xbe,
11988 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
11989 0x02, 0x4a, 0x08, 0x05,
11990 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e,
11991 0x9c, 0x3c, 0xfe, 0x6c,
11992 0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f,
11993 0x3b, 0x40, 0x03, 0x49,
11994 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
11995 0x8f, 0xfe, 0xe3, 0x54,
11996 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe,
11997 0xda, 0x09, 0xfe, 0x8b,
11998 0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa,
11999 0x0a, 0x3a, 0x49, 0x3b,
12000 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
12001 0xad, 0xfe, 0x01, 0x59,
12002 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a,
12003 0x49, 0x8f, 0xfe, 0xe3,
12004 0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02,
12005 0x4a, 0x3a, 0x49, 0x3b,
12006 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
12007 0x02, 0x4a, 0x08, 0x05,
12008 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62,
12009 0xb7, 0xfe, 0x03, 0xa1,
12010 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
12011 0xfe, 0x86, 0x91, 0x6a,
12012 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
12013 0x61, 0x0c, 0x7f, 0x14,
12014 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62,
12015 0x9b, 0x2e, 0x9c, 0x3c,
12016 0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05,
12017 0xfa, 0x3c, 0x01, 0xef,
12018 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
12019 0xe4, 0x08, 0x05, 0x1f,
12020 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37,
12021 0x03, 0x5e, 0x29, 0x5f,
12022 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe,
12023 0xf4, 0x09, 0x08, 0x05,
12024 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
12025 0x81, 0x50, 0xfe, 0x10,
12026 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe,
12027 0x08, 0x09, 0x12, 0xa6,
12028 0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe,
12029 0x08, 0x09, 0xfe, 0x0c,
12030 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
12031 0x08, 0x05, 0x0a, 0xfe,
12032 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1,
12033 0xf0, 0xe2, 0x15, 0x7e,
12034 0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19,
12035 0x57, 0x3d, 0xfe, 0xed,
12036 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
12037 0x00, 0xff, 0x35, 0xfe,
12038 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18,
12039 0x1e, 0x19, 0x8a, 0x03,
12040 0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65,
12041 0xfe, 0xd1, 0xf0, 0xfe,
12042 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
12043 0x10, 0xfe, 0xce, 0xf0,
12044 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b,
12045 0x10, 0xfe, 0x22, 0x00,
12046 0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00,
12047 0x02, 0x65, 0xfe, 0xd0,
12048 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
12049 0x0b, 0x10, 0x58, 0xfe,
12050 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe,
12051 0x12, 0x00, 0x2c, 0x0f,
12052 0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14,
12053 0x0c, 0xbc, 0x17, 0x34,
12054 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
12055 0x0c, 0x1c, 0x34, 0x94,
12056 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01,
12057 0x4b, 0xfe, 0xdb, 0x10,
12058 0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe,
12059 0x89, 0xf0, 0x24, 0x33,
12060 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
12061 0x33, 0x31, 0xdf, 0xbc,
12062 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49,
12063 0x17, 0xfe, 0x2c, 0x0d,
12064 0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54,
12065 0x12, 0x55, 0xfe, 0x28,
12066 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
12067 0x44, 0xfe, 0x28, 0x00,
12068 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26,
12069 0x0f, 0x64, 0x12, 0x2f,
12070 0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44,
12071 0x0a, 0xfe, 0xb4, 0x10,
12072 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
12073 0xfe, 0x34, 0x46, 0xac,
12074 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a,
12075 0x37, 0x01, 0xf5, 0x01,
12076 0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02,
12077 0xfe, 0x2e, 0x03, 0x08,
12078 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
12079 0x1a, 0xfe, 0x58, 0x12,
12080 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
12081 0xfe, 0x50, 0x0d, 0xfe,
12082 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37,
12083 0xfe, 0xa9, 0x10, 0x10,
12084 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
12085 0xfe, 0x13, 0x00, 0xfe,
12086 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe,
12087 0x24, 0x00, 0x8c, 0xb5,
12088 0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a,
12089 0xfe, 0x9d, 0x41, 0xfe,
12090 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
12091 0xb4, 0x15, 0xfe, 0x31,
12092 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06,
12093 0xec, 0xd0, 0xfc, 0x44,
12094 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47,
12095 0x4b, 0x91, 0xfe, 0x75,
12096 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
12097 0x0e, 0xfe, 0x44, 0x48,
12098 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41,
12099 0xfe, 0x41, 0x58, 0x09,
12100 0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe,
12101 0x2e, 0x03, 0x09, 0x5d,
12102 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
12103 0xce, 0x47, 0xfe, 0xad,
12104 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13,
12105 0x59, 0x13, 0x9f, 0x13,
12106 0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe,
12107 0xe0, 0x0e, 0x0f, 0x06,
12108 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
12109 0x3a, 0x01, 0x56, 0xfe,
12110 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec,
12111 0x20, 0x4f, 0xfe, 0x05,
12112 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe,
12113 0x48, 0xf4, 0x0d, 0xfe,
12114 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
12115 0x15, 0x1a, 0x39, 0xa0,
12116 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff,
12117 0x0c, 0xfe, 0x60, 0x01,
12118 0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25,
12119 0x06, 0x13, 0x2f, 0x12,
12120 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
12121 0x22, 0x9f, 0xb7, 0x13,
12122 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39,
12123 0xa0, 0xb4, 0xfe, 0xd9,
12124 0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04,
12125 0xc3, 0xfe, 0x03, 0xdc,
12126 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
12127 0xfe, 0x00, 0xcc, 0x04,
12128 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13,
12129 0xfe, 0x1c, 0x80, 0x07,
12130 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae,
12131 0xfe, 0x0c, 0x90, 0xfe,
12132 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
12133 0x0a, 0xfe, 0x3c, 0x50,
12134 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4,
12135 0x16, 0x08, 0x05, 0x1b,
12136 0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58,
12137 0xfe, 0x2c, 0x13, 0x01,
12138 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
12139 0x0c, 0xfe, 0x64, 0x01,
12140 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03,
12141 0x80, 0x8d, 0xfe, 0x01,
12142 0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64,
12143 0x22, 0x20, 0xfb, 0x79,
12144 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
12145 0x03, 0xfe, 0xae, 0x00,
12146
12147 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe,
12148 0xb2, 0x00, 0xfe, 0x09,
12149 0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c,
12150 0x45, 0x0f, 0x46, 0x52,
12151 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
12152 0x0f, 0x44, 0x11, 0x0f,
12153 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4,
12154 0x25, 0x11, 0x13, 0x20,
12155 0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14,
12156 0x56, 0xfe, 0xd6, 0xf0,
12157 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
12158 0x18, 0x1c, 0x04, 0x42,
12159 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe,
12160 0xf5, 0x13, 0x04, 0x01,
12161 0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
12162 0x13, 0x32, 0x07, 0x2f,
12163 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
12164 0x41, 0x48, 0xfe, 0x45,
12165 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78,
12166 0x07, 0x11, 0xac, 0x09,
12167 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07,
12168 0x82, 0x4e, 0xfe, 0x14,
12169 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
12170 0xfe, 0x01, 0xec, 0xa2,
12171 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79,
12172 0x2a, 0x01, 0xe3, 0xfe,
12173 0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a,
12174 0xfe, 0x48, 0x12, 0x07,
12175 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
12176 0xfe, 0x32, 0x12, 0x07,
12177 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07,
12178 0x1f, 0xfe, 0x12, 0x12,
12179 0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b,
12180 0x94, 0x4b, 0x04, 0x2d,
12181 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
12182 0x32, 0x07, 0xa6, 0xfe,
12183 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05,
12184 0x5a, 0xfe, 0x72, 0x12,
12185 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62,
12186 0xfe, 0x26, 0x13, 0x03,
12187 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
12188 0x0c, 0x7f, 0x0c, 0x80,
12189 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c,
12190 0x3c, 0xfe, 0x04, 0x55,
12191 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe,
12192 0x91, 0x10, 0x03, 0x3f,
12193 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
12194 0x88, 0x9b, 0x2e, 0x9c,
12195 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
12196 0x56, 0x0c, 0x5e, 0x14,
12197 0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40,
12198 0x03, 0x60, 0x29, 0x61,
12199 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
12200 0x50, 0xfe, 0xc6, 0x50,
12201 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d,
12202 0x29, 0x3e, 0xfe, 0x40,
12203 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72,
12204 0x2d, 0x01, 0x0b, 0x1d,
12205 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
12206 0x72, 0x01, 0xaf, 0x1e,
12207 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe,
12208 0x0a, 0x55, 0x35, 0xfe,
12209 0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51,
12210 0x02, 0x72, 0xfe, 0x19,
12211 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
12212 0x1d, 0xe8, 0x33, 0x31,
12213 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01,
12214 0x0b, 0x1c, 0x34, 0x1d,
12215 0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8,
12216 0x33, 0x31, 0xfe, 0xe8,
12217 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
12218 0x05, 0x1f, 0x35, 0xa9,
12219 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda,
12220 0x14, 0x01, 0xaf, 0x8c,
12221 0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a,
12222 0x03, 0x45, 0x28, 0x35,
12223 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
12224 0x03, 0x5c, 0xc1, 0x0c,
12225 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02,
12226 0x89, 0x01, 0x0b, 0x1c,
12227 0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1,
12228 0xfe, 0x42, 0x58, 0xf1,
12229 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
12230 0xf4, 0x06, 0xea, 0x32,
12231 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d,
12232 0x01, 0x0b, 0x26, 0x89,
12233 0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13,
12234 0x26, 0xfe, 0xd4, 0x13,
12235 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
12236 0x13, 0x1c, 0xfe, 0xd0,
12237 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10,
12238 0x0f, 0x71, 0xff, 0x02,
12239 0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe,
12240 0x00, 0x5c, 0x04, 0x0f,
12241 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
12242 0xfe, 0x00, 0x5c, 0x04,
12243 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff,
12244 0x02, 0x00, 0x57, 0x52,
12245 0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01,
12246 0x87, 0x04, 0xfe, 0x03,
12247 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
12248 0xfe, 0x00, 0x7d, 0xfe,
12249 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e,
12250 0x14, 0x5f, 0x57, 0x3f,
12251 0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83,
12252 0x5a, 0x8d, 0x04, 0x01,
12253 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
12254 0xfe, 0x96, 0x15, 0x33,
12255 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8,
12256 0x0a, 0xfe, 0xc1, 0x59,
12257 0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13,
12258 0x21, 0x69, 0x1a, 0xee,
12259 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
12260 0x30, 0xfe, 0x78, 0x10,
12261 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae,
12262 0x98, 0xfe, 0x30, 0x00,
12263 0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed,
12264 0x98, 0xfe, 0x64, 0x00,
12265 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
12266 0x10, 0x69, 0x06, 0xfe,
12267 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00,
12268 0x18, 0x59, 0x0f, 0x06,
12269 0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe,
12270 0x43, 0xf4, 0x9f, 0xfe,
12271 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
12272 0x9e, 0xfe, 0xf3, 0x10,
12273 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00,
12274 0x17, 0xfe, 0x4d, 0xe4,
12275 0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00,
12276 0x17, 0xfe, 0x4d, 0xe4,
12277 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
12278 0xf4, 0x00, 0xe9, 0x91,
12279 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a,
12280 0x04, 0x16, 0x06, 0x01,
12281 0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01,
12282 0x0b, 0x26, 0xf3, 0x76,
12283 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
12284 0x16, 0x19, 0x01, 0x0b,
12285 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01,
12286 0x0b, 0x26, 0xb1, 0x76,
12287 0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06,
12288 0xfe, 0x48, 0x13, 0xb8,
12289 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
12290 0xec, 0xfe, 0x27, 0x01,
12291 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32,
12292 0x07, 0xfe, 0xe3, 0x00,
12293 0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b,
12294 0x22, 0xd4, 0x07, 0x06,
12295 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
12296 0x07, 0x11, 0xae, 0x09,
12297 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01,
12298 0x0e, 0x8e, 0xfe, 0x80,
12299 0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04,
12300 0x09, 0x48, 0x01, 0x0e,
12301 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
12302 0x80, 0xfe, 0x80, 0x4c,
12303 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c,
12304 0x09, 0x5d, 0x01, 0x87,
12305 0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe,
12306 0x19, 0xde, 0xfe, 0x24,
12307 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
12308 0x17, 0xad, 0x9a, 0x1b,
12309 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde,
12310 0x16, 0xfe, 0xda, 0x10,
12311 0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe,
12312 0x18, 0x58, 0x03, 0xfe,
12313 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
12314 0xf4, 0x06, 0xfe, 0x3c,
12315 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f,
12316 0x97, 0xfe, 0x38, 0x17,
12317 0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c,
12318 0x10, 0x18, 0x11, 0x75,
12319 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
12320 0x2e, 0x97, 0xfe, 0x5a,
12321 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19,
12322 0xfe, 0x98, 0xe7, 0x00,
12323 0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75,
12324 0xfe, 0x30, 0xbc, 0xfe,
12325 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
12326 0xcb, 0x97, 0xfe, 0x92,
12327 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe,
12328 0x42, 0x10, 0xfe, 0x02,
12329 0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe,
12330 0x03, 0xa1, 0xfe, 0x1d,
12331 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
12332 0x9a, 0x5b, 0x41, 0xfe,
12333 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7,
12334 0x11, 0x12, 0xfe, 0xdd,
12335 0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8,
12336 0x17, 0x15, 0x06, 0x39,
12337 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
12338 0xfe, 0x7e, 0x18, 0x1e,
12339 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef,
12340 0x12, 0xfe, 0xe1, 0x10,
12341 0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42,
12342 0x13, 0x42, 0x92, 0x09,
12343 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
12344 0xf0, 0xfe, 0x00, 0xcc,
12345 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01,
12346 0x0e, 0xfe, 0x80, 0x4c,
12347 0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe,
12348 0x24, 0x12, 0xfe, 0x14,
12349 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
12350 0xe7, 0x0a, 0x10, 0xfe,
12351 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92,
12352 0x08, 0x54, 0x1b, 0x37,
12353 0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba,
12354 0x90, 0x3a, 0xce, 0x3b,
12355 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
12356 0x13, 0xa3, 0x04, 0x09,
12357 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49,
12358 0x44, 0x17, 0xfe, 0xe8,
12359 0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09,
12360 0x5d, 0x01, 0xa8, 0x09,
12361 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
12362 0x1c, 0x19, 0x03, 0xfe,
12363 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9,
12364 0x6b, 0xfe, 0x2e, 0x19,
12365 0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4,
12366 0xfe, 0x0b, 0x00, 0x6b,
12367 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
12368 0x08, 0x10, 0x03, 0xfe,
12369 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff,
12370 0x04, 0x68, 0x54, 0xe7,
12371 0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe,
12372 0x1a, 0xf4, 0xfe, 0x00,
12373 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
12374 0x04, 0x07, 0x7e, 0xfe,
12375 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
12376 0x07, 0x1a, 0xfe, 0x5a,
12377 0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66,
12378 0x25, 0x6d, 0xe5, 0x07,
12379 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
12380 0xa9, 0xb8, 0x04, 0x15,
12381 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe,
12382 0x40, 0x5c, 0x04, 0x1c,
12383 0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b,
12384 0xf7, 0xfe, 0x82, 0xf0,
12385 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
1da177e4
LT
12386};
12387
27c868c2
MW
12388static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
12389static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
1da177e4
LT
12390
12391/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
12392static unsigned char _adv_asc38C1600_buf[] = {
12393 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
12394 0x18, 0xe4, 0x01, 0x00,
12395 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00,
12396 0x07, 0x17, 0xc0, 0x5f,
12397 0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7,
12398 0x85, 0xf0, 0x86, 0xf0,
12399 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
12400 0x98, 0x57, 0x01, 0xe6,
12401 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d,
12402 0x38, 0x54, 0x32, 0xf0,
12403 0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4,
12404 0x00, 0xe6, 0xb1, 0xf0,
12405 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
12406 0x06, 0x13, 0x0c, 0x1c,
12407 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12,
12408 0xb9, 0x54, 0x00, 0x80,
12409 0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56,
12410 0x03, 0xe6, 0x01, 0xea,
12411 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
12412 0x04, 0x13, 0xbb, 0x55,
12413 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00,
12414 0xbb, 0x00, 0xc0, 0x00,
12415 0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12,
12416 0x4c, 0x1c, 0x4e, 0x1c,
12417 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
12418 0x24, 0x01, 0x3c, 0x01,
12419 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01,
12420 0x78, 0x01, 0x7c, 0x01,
12421 0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c,
12422 0x6e, 0x1e, 0x02, 0x48,
12423 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
12424 0x03, 0xfc, 0x06, 0x00,
12425 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a,
12426 0x30, 0x1c, 0x38, 0x1c,
12427 0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea,
12428 0x5d, 0xf0, 0xa7, 0xf0,
12429 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
12430 0x33, 0x00, 0x34, 0x00,
12431 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01,
12432 0x79, 0x01, 0x3c, 0x09,
12433 0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13,
12434 0x40, 0x16, 0x50, 0x16,
12435 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
12436 0x05, 0xf0, 0x09, 0xf0,
12437 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00,
12438 0x9c, 0x00, 0xa4, 0x00,
12439 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08,
12440 0xe9, 0x09, 0x5c, 0x0c,
12441 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
12442 0x42, 0x1d, 0x08, 0x44,
12443 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54,
12444 0x83, 0x55, 0x83, 0x59,
12445 0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0,
12446 0x4b, 0xf4, 0x04, 0xf8,
12447 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
12448 0xa8, 0x00, 0xaa, 0x00,
12449 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01,
12450 0x7a, 0x01, 0x82, 0x01,
12451 0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07,
12452 0x68, 0x08, 0x10, 0x0d,
12453 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
12454 0xf3, 0x10, 0x06, 0x12,
12455 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c,
12456 0xf0, 0x35, 0x05, 0xfe,
12457 0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8,
12458 0xfe, 0x88, 0x01, 0xff,
12459 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
12460 0x00, 0xfe, 0x57, 0x24,
12461 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09,
12462 0x00, 0x00, 0xff, 0x08,
12463 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
12464 0xff, 0xff, 0xff, 0x13,
12465 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
12466 0xfe, 0x04, 0xf7, 0xe8,
12467 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d,
12468 0x0d, 0x51, 0x37, 0xfe,
12469 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0,
12470 0xfe, 0xf8, 0x01, 0xfe,
12471 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
12472 0x05, 0xfe, 0x08, 0x0f,
12473 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe,
12474 0x28, 0x1c, 0x03, 0xfe,
12475 0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe,
12476 0x48, 0xf0, 0xfe, 0x90,
12477 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
12478 0x02, 0xfe, 0x46, 0xf0,
12479 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0,
12480 0xfe, 0x4e, 0x02, 0xfe,
12481 0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c,
12482 0x0d, 0xa2, 0x1c, 0x07,
12483 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
12484 0x1c, 0xf5, 0xfe, 0x1e,
12485 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc,
12486 0xde, 0x0a, 0x81, 0x01,
12487 0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a,
12488 0x81, 0x01, 0x5c, 0xfe,
12489 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
12490 0xfe, 0x58, 0x1c, 0x1c,
12491 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02,
12492 0x2b, 0xfe, 0x9e, 0x02,
12493 0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30,
12494 0x00, 0x47, 0xb8, 0x01,
12495 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
12496 0x1a, 0x31, 0xfe, 0x69,
12497 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe,
12498 0x1e, 0x1e, 0x20, 0x2c,
12499 0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a,
12500 0x44, 0x15, 0x56, 0x51,
12501 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
12502 0x01, 0x18, 0x09, 0x00,
12503 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01,
12504 0x18, 0xfe, 0xc8, 0x54,
12505 0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60,
12506 0xfe, 0x02, 0xe8, 0x30,
12507 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
12508 0xfe, 0xe4, 0x01, 0xfe,
12509 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe,
12510 0x26, 0xf0, 0xfe, 0x66,
12511 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe,
12512 0xef, 0x10, 0xfe, 0x9f,
12513 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
12514 0x70, 0x37, 0xfe, 0x48,
12515 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26,
12516 0x21, 0xb9, 0xc7, 0x20,
12517 0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15,
12518 0xe1, 0x2a, 0xeb, 0xfe,
12519 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
12520 0x15, 0xfe, 0xe4, 0x00,
12521 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41,
12522 0xfe, 0x06, 0xf0, 0xfe,
12523 0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29,
12524 0x03, 0x81, 0x1e, 0x1b,
12525 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
12526 0xea, 0xfe, 0x46, 0x1c,
12527 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
12528 0xfe, 0x48, 0x1c, 0x75,
12529 0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a,
12530 0xe1, 0x01, 0x18, 0x77,
12531 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
12532 0x8f, 0xfe, 0x70, 0x02,
12533 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04,
12534 0x16, 0xfe, 0x4a, 0x04,
12535 0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff,
12536 0x02, 0x00, 0x10, 0x01,
12537 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
12538 0xee, 0xfe, 0x4c, 0x44,
12539 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54,
12540 0x7b, 0xec, 0x60, 0x8d,
12541 0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01,
12542 0x0c, 0x06, 0x28, 0xfe,
12543 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
12544 0x13, 0x34, 0xfe, 0x4c,
12545 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54,
12546 0x13, 0x01, 0x0c, 0x06,
12547 0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06,
12548 0x28, 0xf9, 0x1f, 0x7f,
12549 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
12550 0xfe, 0xa4, 0x0e, 0x05,
12551 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe,
12552 0x9c, 0x93, 0x3a, 0x0b,
12553 0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b,
12554 0x7d, 0x1d, 0xfe, 0x46,
12555 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
12556 0xfe, 0x87, 0x83, 0xfe,
12557 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98,
12558 0x13, 0x0f, 0xfe, 0x20,
12559 0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84,
12560 0x12, 0x01, 0x38, 0x06,
12561 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
12562 0x05, 0xd0, 0x54, 0x01,
12563 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe,
12564 0x50, 0x12, 0x5e, 0xff,
12565 0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02,
12566 0x00, 0x10, 0x2f, 0xfe,
12567 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
12568 0x38, 0xfe, 0x4a, 0xf0,
12569 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe,
12570 0x21, 0x00, 0xf1, 0x2e,
12571 0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00,
12572 0x10, 0x2f, 0xfe, 0xd0,
12573 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
12574 0x1c, 0x00, 0x4d, 0x01,
12575 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06,
12576 0x28, 0xfe, 0x24, 0x12,
12577 0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe,
12578 0x0d, 0x00, 0x01, 0x42,
12579 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
12580 0x03, 0xb6, 0x1e, 0xfe,
12581 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17,
12582 0xfe, 0x72, 0x06, 0x0a,
12583 0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56,
12584 0x19, 0x16, 0xfe, 0x68,
12585 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
12586 0x03, 0x9a, 0x1e, 0xfe,
12587 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12,
12588 0x48, 0xfe, 0x92, 0x06,
12589 0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13,
12590 0x58, 0xff, 0x02, 0x00,
12591 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
12592 0xfe, 0xea, 0x06, 0x01,
12593 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16,
12594 0xfe, 0xe0, 0x06, 0x15,
12595 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07,
12596 0x01, 0x84, 0xfe, 0xae,
12597 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
12598 0x1e, 0xfe, 0x1a, 0x12,
12599 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
12600 0x43, 0x48, 0x62, 0x80,
12601 0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24,
12602 0x36, 0xfe, 0x02, 0xf6,
12603 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
12604 0xd0, 0x0d, 0x17, 0xfe,
12605 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20,
12606 0x9e, 0x15, 0x82, 0x01,
12607 0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58,
12608 0x57, 0x10, 0xe6, 0x05,
12609 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
12610 0xfe, 0x9c, 0x32, 0x5f,
12611 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c,
12612 0xfe, 0x0a, 0xf0, 0xfe,
12613 0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08,
12614 0xaf, 0xa0, 0x05, 0x29,
12615 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
12616 0x00, 0x01, 0x08, 0x14,
12617 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08,
12618 0x14, 0x00, 0x05, 0xfe,
12619 0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06,
12620 0x12, 0xfe, 0x30, 0x13,
12621 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
12622 0x01, 0x08, 0x14, 0x00,
12623 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a,
12624 0x78, 0x4f, 0x0f, 0xfe,
12625 0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d,
12626 0x28, 0x48, 0xfe, 0x6c,
12627 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
12628 0x12, 0x53, 0x63, 0x4e,
12629 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe,
12630 0x6c, 0x08, 0xaf, 0xa0,
12631 0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24,
12632 0x05, 0xed, 0xfe, 0x9c,
12633 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
12634 0x1e, 0xfe, 0x99, 0x58,
12635 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a,
12636 0x22, 0x6b, 0x01, 0x0c,
12637 0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e,
12638 0x1e, 0x47, 0x2c, 0x7a,
12639 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
12640 0x01, 0x0c, 0x61, 0x65,
12641 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a,
12642 0x16, 0xfe, 0x08, 0x50,
12643 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10,
12644 0x01, 0xfe, 0xce, 0x1e,
12645 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
12646 0x01, 0xfe, 0xfe, 0x1e,
12647 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a,
12648 0x10, 0x01, 0x0c, 0x06,
12649 0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e,
12650 0x10, 0x6a, 0x22, 0x6b,
12651 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
12652 0xfe, 0x9f, 0x83, 0x33,
12653 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93,
12654 0x3a, 0x0b, 0xfe, 0xc6,
12655 0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d,
12656 0x01, 0xfe, 0xce, 0x1e,
12657 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
12658 0x04, 0xfe, 0xc0, 0x93,
12659 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e,
12660 0x10, 0x4b, 0x22, 0x4c,
12661 0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe,
12662 0x4e, 0x11, 0x2f, 0xfe,
12663 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
12664 0x3c, 0x37, 0x88, 0xf5,
12665 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a,
12666 0xd3, 0xfe, 0x42, 0x0a,
12667 0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0,
12668 0x05, 0x29, 0x01, 0x41,
12669 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
12670 0xfe, 0x14, 0x12, 0x01,
12671 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe,
12672 0x2e, 0x1c, 0x05, 0xfe,
12673 0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41,
12674 0xfe, 0x2c, 0x1c, 0xfe,
12675 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
12676 0x92, 0x10, 0xc4, 0xf6,
12677 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe,
12678 0xe7, 0x10, 0xfe, 0x2b,
12679 0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12,
12680 0xac, 0xfe, 0xd2, 0xf0,
12681 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
12682 0x1b, 0xbf, 0xd4, 0x5b,
12683 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75,
12684 0x5e, 0x32, 0x1f, 0x7f,
12685 0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98,
12686 0x05, 0x70, 0xfe, 0x74,
12687 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
12688 0x0f, 0x4d, 0x01, 0xfe,
12689 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06,
12690 0x0d, 0x2b, 0xfe, 0xe2,
12691 0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24,
12692 0xfe, 0x88, 0x13, 0x21,
12693 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
12694 0x83, 0x83, 0xfe, 0xc9,
12695 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04,
12696 0x91, 0x04, 0xfe, 0x84,
12697 0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93,
12698 0xfe, 0xcb, 0x57, 0x0b,
12699 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
12700 0x6a, 0x3b, 0x6b, 0x10,
12701 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30,
12702 0x20, 0x6e, 0xdb, 0x64,
12703 0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55,
12704 0xfe, 0x04, 0xfa, 0x64,
12705 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
12706 0x10, 0x98, 0x91, 0x6c,
12707 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91,
12708 0x4b, 0x7e, 0x4c, 0x01,
12709 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10,
12710 0x58, 0xfe, 0x91, 0x58,
12711 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
12712 0x1b, 0x40, 0x01, 0x0c,
12713 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f,
12714 0xfe, 0x10, 0x90, 0x04,
12715 0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93,
12716 0x79, 0x0b, 0x0e, 0xfe,
12717 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
12718 0x01, 0x0c, 0x06, 0x0d,
12719 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe,
12720 0x0c, 0x58, 0xfe, 0x8d,
12721 0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99,
12722 0x83, 0x33, 0x0b, 0x0e,
12723 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
12724 0x19, 0xfe, 0x19, 0x41,
12725 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42,
12726 0x19, 0xfe, 0x44, 0x00,
12727 0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda,
12728 0x4c, 0xfe, 0x0c, 0x51,
12729 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
12730 0x76, 0x10, 0xac, 0xfe,
12731 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03,
12732 0xe3, 0x23, 0x07, 0xfe,
12733 0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe,
12734 0xcc, 0x0c, 0x1f, 0x92,
12735 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
12736 0x0c, 0xfe, 0x3e, 0x10,
12737 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70,
12738 0xfe, 0xcb, 0xf0, 0xfe,
12739 0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe,
12740 0xf4, 0x0c, 0x19, 0x94,
12741 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
12742 0xfe, 0xcc, 0xf0, 0xef,
12743 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe,
12744 0x4e, 0x11, 0x2f, 0xfe,
12745 0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b,
12746 0x3c, 0x37, 0x88, 0xf5,
12747 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
12748 0x2f, 0xfe, 0x3e, 0x0d,
12749 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f,
12750 0xd2, 0x9f, 0xd3, 0x9f,
12751 0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4,
12752 0xc5, 0x75, 0xd7, 0x99,
12753 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
12754 0x9c, 0x2f, 0xfe, 0x8c,
12755 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe,
12756 0x42, 0x00, 0x05, 0x70,
12757 0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06,
12758 0x0d, 0xfe, 0x44, 0x13,
12759 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
12760 0xfe, 0xda, 0x0e, 0x0a,
12761 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa,
12762 0x10, 0x01, 0xfe, 0xf4,
12763 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40,
12764 0x15, 0x56, 0x01, 0x85,
12765 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
12766 0xcc, 0x10, 0x01, 0xa7,
12767 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04,
12768 0xfe, 0x99, 0x83, 0xfe,
12769 0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe,
12770 0x43, 0x00, 0xfe, 0xa2,
12771 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
12772 0x00, 0x1d, 0x40, 0x15,
12773 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05,
12774 0xfe, 0x3a, 0x03, 0x01,
12775 0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01,
12776 0x76, 0x06, 0x12, 0xfe,
12777 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
12778 0xfe, 0x9d, 0xf0, 0xfe,
12779 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01,
12780 0x0c, 0x61, 0x12, 0x44,
12781 0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f,
12782 0xfe, 0x2e, 0x10, 0x19,
12783 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
12784 0xfe, 0x41, 0x00, 0xa2,
12785 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b,
12786 0xea, 0x4f, 0xfe, 0x04,
12787 0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05,
12788 0x35, 0xfe, 0x12, 0x1c,
12789 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
12790 0xfe, 0xd4, 0x11, 0x05,
12791 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe,
12792 0xce, 0x45, 0x31, 0x51,
12793 0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03,
12794 0x67, 0xfe, 0x98, 0x56,
12795 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
12796 0x0c, 0x06, 0x28, 0xfe,
12797 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba,
12798 0xfe, 0xfa, 0x14, 0xfe,
12799 0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67,
12800 0xfe, 0xe0, 0x14, 0xfe,
12801 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
12802 0xfe, 0xad, 0x13, 0x05,
12803 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20,
12804 0xe7, 0xfe, 0x08, 0x1c,
12805 0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe,
12806 0x48, 0x55, 0xa5, 0x3b,
12807 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
12808 0xf0, 0x1a, 0x03, 0xfe,
12809 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02,
12810 0xec, 0xe7, 0x53, 0x00,
12811 0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
12812 0x01, 0xfe, 0x62, 0x1b,
12813 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
12814 0xea, 0xe7, 0x53, 0x92,
12815 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03,
12816 0xfe, 0x38, 0x01, 0x23,
12817 0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62,
12818 0x01, 0x01, 0xfe, 0x1e,
12819 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
12820 0x26, 0x02, 0x21, 0x96,
12821 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5,
12822 0xc3, 0xfe, 0xe1, 0x10,
12823 0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf,
12824 0xfe, 0x03, 0xdc, 0xfe,
12825 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
12826 0x00, 0xcc, 0x02, 0xfe,
12827 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13,
12828 0x0f, 0xfe, 0x1c, 0x80,
12829 0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13,
12830 0x0f, 0xfe, 0x1e, 0x80,
12831 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
12832 0x1d, 0x80, 0x04, 0xfe,
12833 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee,
12834 0x1e, 0xac, 0xfe, 0x14,
12835 0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e,
12836 0x1f, 0xfe, 0x30, 0xf4,
12837 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
12838 0x56, 0xfb, 0x01, 0xfe,
12839 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01,
12840 0xfe, 0x00, 0x1d, 0x15,
12841 0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe,
12842 0x22, 0x1b, 0xfe, 0x1e,
12843 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
12844 0x96, 0x90, 0x04, 0xfe,
12845 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66,
12846 0x01, 0x01, 0x0c, 0x06,
12847 0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b,
12848 0x0e, 0x77, 0xfe, 0x01,
12849 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
12850 0x21, 0x2c, 0xfe, 0x00,
12851 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe,
12852 0x06, 0x58, 0x03, 0xfe,
12853 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58,
12854 0x03, 0xfe, 0xb2, 0x00,
12855 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
12856 0x66, 0x10, 0x55, 0x10,
12857 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91,
12858 0x54, 0x2b, 0xfe, 0x88,
12859 0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe,
12860 0x91, 0x54, 0x2b, 0xfe,
12861 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
12862 0x00, 0x40, 0x8d, 0x2c,
12863 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe,
12864 0x12, 0x1c, 0x75, 0xfe,
12865 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c,
12866 0x14, 0xfe, 0x0e, 0x47,
12867 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
12868 0xa7, 0x90, 0x34, 0x60,
12869 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80,
12870 0x09, 0x56, 0xfe, 0x34,
12871 0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48,
12872 0xfe, 0x45, 0x48, 0x01,
12873 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
12874 0x09, 0x1a, 0xa5, 0x0a,
12875 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4,
12876 0xfe, 0x14, 0x56, 0xfe,
12877 0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01,
12878 0xec, 0xb8, 0xfe, 0x9e,
12879 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
12880 0xf4, 0xfe, 0xdd, 0x10,
12881 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48,
12882 0x12, 0x09, 0x0d, 0xfe,
12883 0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4,
12884 0x13, 0x09, 0xfe, 0x23,
12885 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
12886 0x24, 0xfe, 0x12, 0x12,
12887 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08,
12888 0xae, 0x41, 0x02, 0x32,
12889 0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05,
12890 0x35, 0x32, 0x01, 0x43,
12891 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
12892 0x13, 0x01, 0x0c, 0x06,
12893 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe,
12894 0xe5, 0x55, 0xb0, 0xfe,
12895 0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e,
12896 0xfe, 0xb6, 0x0e, 0x10,
12897 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
12898 0x88, 0x20, 0x6e, 0x01,
12899 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5,
12900 0x55, 0xfe, 0x04, 0xfa,
12901 0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d,
12902 0xfe, 0x40, 0x56, 0xfe,
12903 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
12904 0x44, 0x55, 0xfe, 0xe5,
12905 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10,
12906 0x68, 0x22, 0x69, 0x01,
12907 0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b,
12908 0x6b, 0xfe, 0x2c, 0x50,
12909 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
12910 0x50, 0x03, 0x68, 0x3b,
12911 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe,
12912 0x40, 0x50, 0xfe, 0xc2,
12913 0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08,
12914 0x16, 0x3d, 0x27, 0x25,
12915 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
12916 0xa6, 0x23, 0x3f, 0x1b,
12917 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c,
12918 0xfe, 0x0a, 0x55, 0x31,
12919 0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e,
12920 0x51, 0x05, 0x72, 0x01,
12921 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
12922 0x2a, 0x3c, 0x16, 0xc0,
12923 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b,
12924 0xfe, 0x66, 0x15, 0x05,
12925 0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d,
12926 0x2b, 0x3d, 0x01, 0x08,
12927 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
12928 0xb6, 0x1e, 0x83, 0x01,
12929 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46,
12930 0x07, 0x90, 0x3f, 0x01,
12931 0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13,
12932 0x01, 0x43, 0x09, 0x82,
12933 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
12934 0x05, 0x72, 0xfe, 0xc0,
12935 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e,
12936 0x32, 0x01, 0x08, 0x17,
12937 0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16,
12938 0x3d, 0x27, 0x25, 0xbd,
12939 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
12940 0xe8, 0x14, 0x01, 0xa6,
12941 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe,
12942 0x0e, 0x12, 0x01, 0x43,
12943 0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32,
12944 0x01, 0x08, 0x17, 0x73,
12945 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
12946 0x27, 0x25, 0xbd, 0x09,
12947 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe,
12948 0xb6, 0x14, 0x86, 0xa8,
12949 0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09,
12950 0x82, 0x4e, 0x05, 0x72,
12951 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
12952 0xfe, 0xc0, 0x19, 0x05,
12953 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f,
12954 0xcc, 0x01, 0x08, 0x26,
12955 0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe,
12956 0xcc, 0x15, 0x5e, 0x32,
12957 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
12958 0xad, 0x23, 0xfe, 0xff,
12959 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02,
12960 0x00, 0x57, 0x52, 0xad,
12961 0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff,
12962 0x02, 0x00, 0x57, 0x52,
12963 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
12964 0x02, 0x13, 0x58, 0xff,
12965 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01,
12966 0x5c, 0x0a, 0x55, 0x01,
12967 0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a,
12968 0xff, 0x03, 0x00, 0x54,
12969 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
12970 0x7c, 0x3a, 0x0b, 0x0e,
12971 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19,
12972 0xfe, 0x1a, 0xf7, 0x00,
12973 0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c,
12974 0xda, 0x6d, 0x02, 0xfe,
12975 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
12976 0x02, 0x01, 0xc6, 0xfe,
12977 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27,
12978 0x25, 0xbe, 0x01, 0x08,
12979 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59,
12980 0x03, 0x9a, 0x1e, 0xfe,
12981 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
12982 0x48, 0xfe, 0x08, 0x17,
12983 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26,
12984 0x17, 0x4d, 0x13, 0x07,
12985 0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1,
12986 0xff, 0x02, 0x83, 0x55,
12987 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
12988 0x17, 0x1c, 0x63, 0x13,
12989 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64,
12990 0x00, 0xb0, 0xfe, 0x80,
12991 0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10,
12992 0x53, 0x07, 0xfe, 0x60,
12993 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
12994 0x00, 0x1c, 0x95, 0x13,
12995 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3,
12996 0xfe, 0x43, 0xf4, 0x96,
12997 0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43,
12998 0xf4, 0x94, 0xf6, 0x8b,
12999 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
13000 0xda, 0x17, 0x62, 0x49,
13001 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80,
13002 0x71, 0x50, 0x26, 0xfe,
13003 0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3,
13004 0x58, 0x02, 0x50, 0x13,
13005 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
13006 0x25, 0xbe, 0xfe, 0x03,
13007 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9,
13008 0x0a, 0x01, 0x08, 0x16,
13009 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01,
13010 0x01, 0x08, 0x16, 0xa9,
13011 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
13012 0x08, 0x16, 0xa9, 0x27,
13013 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83,
13014 0x01, 0x38, 0x06, 0x24,
13015 0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1,
13016 0x78, 0x03, 0x9a, 0x1e,
13017 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
13018 0xfe, 0x40, 0x5a, 0x23,
13019 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c,
13020 0x80, 0x48, 0xfe, 0xaa,
13021 0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01,
13022 0xfe, 0xac, 0x1d, 0xfe,
13023 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
13024 0x43, 0x48, 0x2d, 0x93,
13025 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4,
13026 0x36, 0xfe, 0x34, 0xf4,
13027 0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe,
13028 0x28, 0x10, 0xfe, 0xc0,
13029 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
13030 0x18, 0x45, 0xfe, 0x1c,
13031 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c,
13032 0x19, 0xfe, 0x04, 0xf4,
13033 0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d,
13034 0x21, 0xfe, 0x7f, 0x01,
13035 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
13036 0x7e, 0x01, 0xfe, 0xc8,
13037 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa,
13038 0x21, 0xfe, 0x81, 0x01,
13039 0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50,
13040 0x13, 0x0d, 0x02, 0x14,
13041 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
13042 0xfe, 0x82, 0x19, 0x14,
13043 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01,
13044 0x08, 0x02, 0x14, 0x07,
13045 0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07,
13046 0x01, 0x08, 0x17, 0xc1,
13047 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
13048 0x08, 0x02, 0x50, 0x02,
13049 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74,
13050 0x14, 0x12, 0x01, 0x08,
13051 0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01,
13052 0x08, 0x17, 0x74, 0xfe,
13053 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
13054 0x74, 0x5f, 0xcc, 0x01,
13055 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4,
13056 0xfe, 0x49, 0xf4, 0x00,
13057 0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff,
13058 0x02, 0x00, 0x10, 0x2f,
13059 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
13060 0x16, 0xfe, 0x64, 0x1a,
13061 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c,
13062 0x61, 0x07, 0x44, 0x02,
13063 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12,
13064 0x13, 0x0a, 0x9d, 0x01,
13065 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
13066 0xfe, 0x80, 0xe7, 0x1a,
13067 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02,
13068 0x0a, 0x5a, 0x01, 0x18,
13069 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe,
13070 0x7e, 0x1e, 0xfe, 0x80,
13071 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
13072 0xfe, 0x80, 0x4c, 0x0a,
13073 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf,
13074 0xfe, 0x19, 0xde, 0xfe,
13075 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe,
13076 0x2a, 0x1c, 0xfa, 0xb3,
13077 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
13078 0xf4, 0x1a, 0xfe, 0xfa,
13079 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24,
13080 0xfe, 0x18, 0x58, 0x03,
13081 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f,
13082 0xfe, 0x30, 0xf4, 0x07,
13083 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
13084 0xf7, 0x24, 0xb1, 0xfe,
13085 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b,
13086 0xfe, 0xba, 0x10, 0x1c,
13087 0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
13088 0x1d, 0xf7, 0x54, 0xb1,
13089 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
13090 0xaf, 0x19, 0xfe, 0x98,
13091 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c,
13092 0x1a, 0x87, 0x8b, 0x0f,
13093 0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58,
13094 0xfe, 0x32, 0x90, 0x04,
13095 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
13096 0x7c, 0x12, 0xfe, 0x0f,
13097 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14,
13098 0x31, 0x02, 0xc9, 0x2b,
13099 0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe,
13100 0x6a, 0xfe, 0x19, 0xfe,
13101 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
13102 0x1b, 0xfe, 0x36, 0x14,
13103 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19,
13104 0xfe, 0x80, 0xe7, 0x1a,
13105 0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a,
13106 0x30, 0xfe, 0x12, 0x45,
13107 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
13108 0x39, 0xf0, 0x75, 0x26,
13109 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03,
13110 0xe3, 0x23, 0x07, 0xfe,
13111 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09,
13112 0x56, 0xfe, 0x3c, 0x13,
13113 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
13114 0x01, 0x18, 0xcb, 0xfe,
13115 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16,
13116 0xfe, 0x00, 0xcc, 0xcb,
13117 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18,
13118 0xfe, 0x80, 0x4c, 0x01,
13119 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
13120 0x12, 0xfe, 0x14, 0x56,
13121 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7,
13122 0x0d, 0x19, 0xfe, 0x15,
13123 0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06,
13124 0x83, 0xfe, 0x18, 0x80,
13125 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
13126 0x90, 0xfe, 0xba, 0x90,
13127 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02,
13128 0x21, 0xb9, 0x88, 0x20,
13129 0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01,
13130 0x18, 0xfe, 0x49, 0x44,
13131 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
13132 0x1a, 0xa4, 0x0a, 0x67,
13133 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4,
13134 0x1d, 0x7b, 0xfe, 0x52,
13135 0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe,
13136 0x4e, 0xe4, 0xdd, 0x7b,
13137 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
13138 0xfe, 0x4e, 0xe4, 0xfe,
13139 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24,
13140 0xfe, 0x08, 0x10, 0x03,
13141 0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04,
13142 0x68, 0x54, 0xfe, 0xf1,
13143 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
13144 0xfe, 0x1a, 0xf4, 0xfe,
13145 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02,
13146 0x09, 0x92, 0xfe, 0x5a,
13147 0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe,
13148 0x5a, 0xf0, 0xfe, 0xc8,
13149 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
13150 0x1a, 0x10, 0x09, 0x0d,
13151 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02,
13152 0x1f, 0x93, 0x01, 0x42,
13153 0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e,
13154 0xfe, 0x14, 0xf0, 0x08,
13155 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
13156 0xfe, 0x82, 0xf0, 0xfe,
13157 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e,
13158 0x02, 0x0f, 0xfe, 0x18,
13159 0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02,
13160 0x80, 0x04, 0xfe, 0x82,
13161 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
13162 0x83, 0x33, 0x0b, 0x0e,
13163 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e,
13164 0x02, 0x0f, 0xfe, 0x04,
13165 0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80,
13166 0x80, 0x04, 0xfe, 0x80,
13167 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
13168 0xfe, 0x99, 0x83, 0xfe,
13169 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86,
13170 0x83, 0xfe, 0xce, 0x47,
13171 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a,
13172 0x0b, 0x0e, 0x02, 0x0f,
13173 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13174 0xfe, 0x08, 0x90, 0x04,
13175 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04,
13176 0xfe, 0x8a, 0x93, 0x79,
13177 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a,
13178 0x0b, 0x0e, 0x02, 0x0f,
13179 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13180 0xfe, 0x3c, 0x90, 0x04,
13181 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80,
13182 0x04, 0xfe, 0x83, 0x83,
13183 0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
1da177e4
LT
13184};
13185
27c868c2
MW
13186static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
13187static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
1da177e4
LT
13188
13189/* a_init.c */
13190/*
13191 * EEPROM Configuration.
13192 *
13193 * All drivers should use this structure to set the default EEPROM
13194 * configuration. The BIOS now uses this structure when it is built.
13195 * Additional structure information can be found in a_condor.h where
13196 * the structure is defined.
13197 *
13198 * The *_Field_IsChar structs are needed to correct for endianness.
13199 * These values are read from the board 16 bits at a time directly
13200 * into the structs. Because some fields are char, the values will be
13201 * in the wrong order. The *_Field_IsChar tells when to flip the
13202 * bytes. Data read and written to PCI memory is automatically swapped
13203 * on big-endian platforms so char fields read as words are actually being
13204 * unswapped on big-endian platforms.
13205 */
78e77d8b 13206static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
27c868c2
MW
13207 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
13208 0x0000, /* cfg_msw */
13209 0xFFFF, /* disc_enable */
13210 0xFFFF, /* wdtr_able */
13211 0xFFFF, /* sdtr_able */
13212 0xFFFF, /* start_motor */
13213 0xFFFF, /* tagqng_able */
13214 0xFFFF, /* bios_scan */
13215 0, /* scam_tolerant */
13216 7, /* adapter_scsi_id */
13217 0, /* bios_boot_delay */
13218 3, /* scsi_reset_delay */
13219 0, /* bios_id_lun */
13220 0, /* termination */
13221 0, /* reserved1 */
13222 0xFFE7, /* bios_ctrl */
13223 0xFFFF, /* ultra_able */
13224 0, /* reserved2 */
13225 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
13226 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13227 0, /* dvc_cntl */
13228 0, /* bug_fix */
13229 0, /* serial_number_word1 */
13230 0, /* serial_number_word2 */
13231 0, /* serial_number_word3 */
13232 0, /* check_sum */
13233 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13234 , /* oem_name[16] */
13235 0, /* dvc_err_code */
13236 0, /* adv_err_code */
13237 0, /* adv_err_addr */
13238 0, /* saved_dvc_err_code */
13239 0, /* saved_adv_err_code */
13240 0, /* saved_adv_err_addr */
13241 0 /* num_of_err */
1da177e4
LT
13242};
13243
78e77d8b 13244static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
27c868c2
MW
13245 0, /* cfg_lsw */
13246 0, /* cfg_msw */
13247 0, /* -disc_enable */
13248 0, /* wdtr_able */
13249 0, /* sdtr_able */
13250 0, /* start_motor */
13251 0, /* tagqng_able */
13252 0, /* bios_scan */
13253 0, /* scam_tolerant */
13254 1, /* adapter_scsi_id */
13255 1, /* bios_boot_delay */
13256 1, /* scsi_reset_delay */
13257 1, /* bios_id_lun */
13258 1, /* termination */
13259 1, /* reserved1 */
13260 0, /* bios_ctrl */
13261 0, /* ultra_able */
13262 0, /* reserved2 */
13263 1, /* max_host_qng */
13264 1, /* max_dvc_qng */
13265 0, /* dvc_cntl */
13266 0, /* bug_fix */
13267 0, /* serial_number_word1 */
13268 0, /* serial_number_word2 */
13269 0, /* serial_number_word3 */
13270 0, /* check_sum */
13271 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13272 , /* oem_name[16] */
13273 0, /* dvc_err_code */
13274 0, /* adv_err_code */
13275 0, /* adv_err_addr */
13276 0, /* saved_dvc_err_code */
13277 0, /* saved_adv_err_code */
13278 0, /* saved_adv_err_addr */
13279 0 /* num_of_err */
1da177e4
LT
13280};
13281
78e77d8b 13282static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
27c868c2
MW
13283 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13284 0x0000, /* 01 cfg_msw */
13285 0xFFFF, /* 02 disc_enable */
13286 0xFFFF, /* 03 wdtr_able */
13287 0x4444, /* 04 sdtr_speed1 */
13288 0xFFFF, /* 05 start_motor */
13289 0xFFFF, /* 06 tagqng_able */
13290 0xFFFF, /* 07 bios_scan */
13291 0, /* 08 scam_tolerant */
13292 7, /* 09 adapter_scsi_id */
13293 0, /* bios_boot_delay */
13294 3, /* 10 scsi_reset_delay */
13295 0, /* bios_id_lun */
13296 0, /* 11 termination_se */
13297 0, /* termination_lvd */
13298 0xFFE7, /* 12 bios_ctrl */
13299 0x4444, /* 13 sdtr_speed2 */
13300 0x4444, /* 14 sdtr_speed3 */
13301 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
13302 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13303 0, /* 16 dvc_cntl */
13304 0x4444, /* 17 sdtr_speed4 */
13305 0, /* 18 serial_number_word1 */
13306 0, /* 19 serial_number_word2 */
13307 0, /* 20 serial_number_word3 */
13308 0, /* 21 check_sum */
13309 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13310 , /* 22-29 oem_name[16] */
13311 0, /* 30 dvc_err_code */
13312 0, /* 31 adv_err_code */
13313 0, /* 32 adv_err_addr */
13314 0, /* 33 saved_dvc_err_code */
13315 0, /* 34 saved_adv_err_code */
13316 0, /* 35 saved_adv_err_addr */
13317 0, /* 36 reserved */
13318 0, /* 37 reserved */
13319 0, /* 38 reserved */
13320 0, /* 39 reserved */
13321 0, /* 40 reserved */
13322 0, /* 41 reserved */
13323 0, /* 42 reserved */
13324 0, /* 43 reserved */
13325 0, /* 44 reserved */
13326 0, /* 45 reserved */
13327 0, /* 46 reserved */
13328 0, /* 47 reserved */
13329 0, /* 48 reserved */
13330 0, /* 49 reserved */
13331 0, /* 50 reserved */
13332 0, /* 51 reserved */
13333 0, /* 52 reserved */
13334 0, /* 53 reserved */
13335 0, /* 54 reserved */
13336 0, /* 55 reserved */
13337 0, /* 56 cisptr_lsw */
13338 0, /* 57 cisprt_msw */
13339 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
13340 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
13341 0, /* 60 reserved */
13342 0, /* 61 reserved */
13343 0, /* 62 reserved */
13344 0 /* 63 reserved */
1da177e4
LT
13345};
13346
78e77d8b 13347static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
27c868c2
MW
13348 0, /* 00 cfg_lsw */
13349 0, /* 01 cfg_msw */
13350 0, /* 02 disc_enable */
13351 0, /* 03 wdtr_able */
13352 0, /* 04 sdtr_speed1 */
13353 0, /* 05 start_motor */
13354 0, /* 06 tagqng_able */
13355 0, /* 07 bios_scan */
13356 0, /* 08 scam_tolerant */
13357 1, /* 09 adapter_scsi_id */
13358 1, /* bios_boot_delay */
13359 1, /* 10 scsi_reset_delay */
13360 1, /* bios_id_lun */
13361 1, /* 11 termination_se */
13362 1, /* termination_lvd */
13363 0, /* 12 bios_ctrl */
13364 0, /* 13 sdtr_speed2 */
13365 0, /* 14 sdtr_speed3 */
13366 1, /* 15 max_host_qng */
13367 1, /* max_dvc_qng */
13368 0, /* 16 dvc_cntl */
13369 0, /* 17 sdtr_speed4 */
13370 0, /* 18 serial_number_word1 */
13371 0, /* 19 serial_number_word2 */
13372 0, /* 20 serial_number_word3 */
13373 0, /* 21 check_sum */
13374 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13375 , /* 22-29 oem_name[16] */
13376 0, /* 30 dvc_err_code */
13377 0, /* 31 adv_err_code */
13378 0, /* 32 adv_err_addr */
13379 0, /* 33 saved_dvc_err_code */
13380 0, /* 34 saved_adv_err_code */
13381 0, /* 35 saved_adv_err_addr */
13382 0, /* 36 reserved */
13383 0, /* 37 reserved */
13384 0, /* 38 reserved */
13385 0, /* 39 reserved */
13386 0, /* 40 reserved */
13387 0, /* 41 reserved */
13388 0, /* 42 reserved */
13389 0, /* 43 reserved */
13390 0, /* 44 reserved */
13391 0, /* 45 reserved */
13392 0, /* 46 reserved */
13393 0, /* 47 reserved */
13394 0, /* 48 reserved */
13395 0, /* 49 reserved */
13396 0, /* 50 reserved */
13397 0, /* 51 reserved */
13398 0, /* 52 reserved */
13399 0, /* 53 reserved */
13400 0, /* 54 reserved */
13401 0, /* 55 reserved */
13402 0, /* 56 cisptr_lsw */
13403 0, /* 57 cisprt_msw */
13404 0, /* 58 subsysvid */
13405 0, /* 59 subsysid */
13406 0, /* 60 reserved */
13407 0, /* 61 reserved */
13408 0, /* 62 reserved */
13409 0 /* 63 reserved */
1da177e4
LT
13410};
13411
78e77d8b 13412static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
27c868c2
MW
13413 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13414 0x0000, /* 01 cfg_msw */
13415 0xFFFF, /* 02 disc_enable */
13416 0xFFFF, /* 03 wdtr_able */
13417 0x5555, /* 04 sdtr_speed1 */
13418 0xFFFF, /* 05 start_motor */
13419 0xFFFF, /* 06 tagqng_able */
13420 0xFFFF, /* 07 bios_scan */
13421 0, /* 08 scam_tolerant */
13422 7, /* 09 adapter_scsi_id */
13423 0, /* bios_boot_delay */
13424 3, /* 10 scsi_reset_delay */
13425 0, /* bios_id_lun */
13426 0, /* 11 termination_se */
13427 0, /* termination_lvd */
13428 0xFFE7, /* 12 bios_ctrl */
13429 0x5555, /* 13 sdtr_speed2 */
13430 0x5555, /* 14 sdtr_speed3 */
13431 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
13432 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13433 0, /* 16 dvc_cntl */
13434 0x5555, /* 17 sdtr_speed4 */
13435 0, /* 18 serial_number_word1 */
13436 0, /* 19 serial_number_word2 */
13437 0, /* 20 serial_number_word3 */
13438 0, /* 21 check_sum */
13439 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13440 , /* 22-29 oem_name[16] */
13441 0, /* 30 dvc_err_code */
13442 0, /* 31 adv_err_code */
13443 0, /* 32 adv_err_addr */
13444 0, /* 33 saved_dvc_err_code */
13445 0, /* 34 saved_adv_err_code */
13446 0, /* 35 saved_adv_err_addr */
13447 0, /* 36 reserved */
13448 0, /* 37 reserved */
13449 0, /* 38 reserved */
13450 0, /* 39 reserved */
13451 0, /* 40 reserved */
13452 0, /* 41 reserved */
13453 0, /* 42 reserved */
13454 0, /* 43 reserved */
13455 0, /* 44 reserved */
13456 0, /* 45 reserved */
13457 0, /* 46 reserved */
13458 0, /* 47 reserved */
13459 0, /* 48 reserved */
13460 0, /* 49 reserved */
13461 0, /* 50 reserved */
13462 0, /* 51 reserved */
13463 0, /* 52 reserved */
13464 0, /* 53 reserved */
13465 0, /* 54 reserved */
13466 0, /* 55 reserved */
13467 0, /* 56 cisptr_lsw */
13468 0, /* 57 cisprt_msw */
13469 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
13470 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
13471 0, /* 60 reserved */
13472 0, /* 61 reserved */
13473 0, /* 62 reserved */
13474 0 /* 63 reserved */
1da177e4
LT
13475};
13476
78e77d8b 13477static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
27c868c2
MW
13478 0, /* 00 cfg_lsw */
13479 0, /* 01 cfg_msw */
13480 0, /* 02 disc_enable */
13481 0, /* 03 wdtr_able */
13482 0, /* 04 sdtr_speed1 */
13483 0, /* 05 start_motor */
13484 0, /* 06 tagqng_able */
13485 0, /* 07 bios_scan */
13486 0, /* 08 scam_tolerant */
13487 1, /* 09 adapter_scsi_id */
13488 1, /* bios_boot_delay */
13489 1, /* 10 scsi_reset_delay */
13490 1, /* bios_id_lun */
13491 1, /* 11 termination_se */
13492 1, /* termination_lvd */
13493 0, /* 12 bios_ctrl */
13494 0, /* 13 sdtr_speed2 */
13495 0, /* 14 sdtr_speed3 */
13496 1, /* 15 max_host_qng */
13497 1, /* max_dvc_qng */
13498 0, /* 16 dvc_cntl */
13499 0, /* 17 sdtr_speed4 */
13500 0, /* 18 serial_number_word1 */
13501 0, /* 19 serial_number_word2 */
13502 0, /* 20 serial_number_word3 */
13503 0, /* 21 check_sum */
13504 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13505 , /* 22-29 oem_name[16] */
13506 0, /* 30 dvc_err_code */
13507 0, /* 31 adv_err_code */
13508 0, /* 32 adv_err_addr */
13509 0, /* 33 saved_dvc_err_code */
13510 0, /* 34 saved_adv_err_code */
13511 0, /* 35 saved_adv_err_addr */
13512 0, /* 36 reserved */
13513 0, /* 37 reserved */
13514 0, /* 38 reserved */
13515 0, /* 39 reserved */
13516 0, /* 40 reserved */
13517 0, /* 41 reserved */
13518 0, /* 42 reserved */
13519 0, /* 43 reserved */
13520 0, /* 44 reserved */
13521 0, /* 45 reserved */
13522 0, /* 46 reserved */
13523 0, /* 47 reserved */
13524 0, /* 48 reserved */
13525 0, /* 49 reserved */
13526 0, /* 50 reserved */
13527 0, /* 51 reserved */
13528 0, /* 52 reserved */
13529 0, /* 53 reserved */
13530 0, /* 54 reserved */
13531 0, /* 55 reserved */
13532 0, /* 56 cisptr_lsw */
13533 0, /* 57 cisprt_msw */
13534 0, /* 58 subsysvid */
13535 0, /* 59 subsysid */
13536 0, /* 60 reserved */
13537 0, /* 61 reserved */
13538 0, /* 62 reserved */
13539 0 /* 63 reserved */
1da177e4
LT
13540};
13541
13542/*
13543 * Initialize the ADV_DVC_VAR structure.
13544 *
13545 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13546 *
13547 * For a non-fatal error return a warning code. If there are no warnings
13548 * then 0 is returned.
13549 */
394dbf3f
MW
13550static int __devinit
13551AdvInitGetConfig(struct pci_dev *pdev, ADV_DVC_VAR *asc_dvc)
1da177e4 13552{
9649af39
MW
13553 unsigned short warn_code = 0;
13554 AdvPortAddr iop_base = asc_dvc->iop_base;
9649af39 13555 u16 cmd;
27c868c2
MW
13556 int status;
13557
27c868c2 13558 asc_dvc->err_code = 0;
1da177e4 13559
27c868c2
MW
13560 /*
13561 * Save the state of the PCI Configuration Command Register
13562 * "Parity Error Response Control" Bit. If the bit is clear (0),
13563 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
13564 * DMA parity errors.
13565 */
13566 asc_dvc->cfg->control_flag = 0;
9649af39
MW
13567 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
13568 if ((cmd & PCI_COMMAND_PARITY) == 0)
27c868c2 13569 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
1da177e4 13570
27c868c2
MW
13571 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
13572 ADV_LIB_VERSION_MINOR;
13573 asc_dvc->cfg->chip_version =
13574 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
13575
13576 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
13577 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
13578 (ushort)ADV_CHIP_ID_BYTE);
13579
13580 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
13581 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
13582 (ushort)ADV_CHIP_ID_WORD);
13583
13584 /*
13585 * Reset the chip to start and allow register writes.
13586 */
13587 if (AdvFindSignature(iop_base) == 0) {
13588 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
13589 return ADV_ERROR;
13590 } else {
13591 /*
13592 * The caller must set 'chip_type' to a valid setting.
13593 */
13594 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
13595 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
13596 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
13597 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
13598 return ADV_ERROR;
13599 }
1da177e4 13600
27c868c2
MW
13601 /*
13602 * Reset Chip.
13603 */
13604 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13605 ADV_CTRL_REG_CMD_RESET);
13606 DvcSleepMilliSecond(100);
13607 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13608 ADV_CTRL_REG_CMD_WR_IO_REG);
13609
13610 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
9649af39 13611 status = AdvInitFrom38C1600EEP(asc_dvc);
27c868c2 13612 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
9649af39 13613 status = AdvInitFrom38C0800EEP(asc_dvc);
27c868c2 13614 } else {
9649af39 13615 status = AdvInitFrom3550EEP(asc_dvc);
27c868c2
MW
13616 }
13617 warn_code |= status;
13618 }
1da177e4 13619
27c868c2 13620 return warn_code;
1da177e4
LT
13621}
13622
13623/*
13624 * Initialize the ASC-3550.
13625 *
13626 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13627 *
13628 * For a non-fatal error return a warning code. If there are no warnings
13629 * then 0 is returned.
13630 *
13631 * Needed after initialization for error recovery.
13632 */
27c868c2 13633static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
1da177e4 13634{
27c868c2
MW
13635 AdvPortAddr iop_base;
13636 ushort warn_code;
13637 ADV_DCNT sum;
13638 int begin_addr;
13639 int end_addr;
13640 ushort code_sum;
13641 int word;
13642 int j;
13643 int adv_asc3550_expanded_size;
13644 ADV_CARR_T *carrp;
13645 ADV_DCNT contig_len;
13646 ADV_SDCNT buf_size;
13647 ADV_PADDR carr_paddr;
13648 int i;
13649 ushort scsi_cfg1;
13650 uchar tid;
13651 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
13652 ushort wdtr_able = 0, sdtr_able, tagqng_able;
13653 uchar max_cmd[ADV_MAX_TID + 1];
13654
13655 /* If there is already an error, don't continue. */
13656 if (asc_dvc->err_code != 0) {
13657 return ADV_ERROR;
13658 }
1da177e4 13659
27c868c2
MW
13660 /*
13661 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
13662 */
13663 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
13664 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
13665 return ADV_ERROR;
13666 }
1da177e4 13667
27c868c2
MW
13668 warn_code = 0;
13669 iop_base = asc_dvc->iop_base;
13670
13671 /*
13672 * Save the RISC memory BIOS region before writing the microcode.
13673 * The BIOS may already be loaded and using its RISC LRAM region
13674 * so its region must be saved and restored.
13675 *
13676 * Note: This code makes the assumption, which is currently true,
13677 * that a chip reset does not clear RISC LRAM.
13678 */
13679 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
13680 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
13681 bios_mem[i]);
13682 }
1da177e4 13683
27c868c2
MW
13684 /*
13685 * Save current per TID negotiated values.
13686 */
13687 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
13688 ushort bios_version, major, minor;
13689
13690 bios_version =
13691 bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
13692 major = (bios_version >> 12) & 0xF;
13693 minor = (bios_version >> 8) & 0xF;
13694 if (major < 3 || (major == 3 && minor == 1)) {
13695 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
13696 AdvReadWordLram(iop_base, 0x120, wdtr_able);
13697 } else {
13698 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
13699 }
13700 }
13701 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
13702 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
13703 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13704 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
13705 max_cmd[tid]);
13706 }
1da177e4 13707
27c868c2
MW
13708 /*
13709 * Load the Microcode
13710 *
13711 * Write the microcode image to RISC memory starting at address 0.
13712 */
13713 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
13714 /* Assume the following compressed format of the microcode buffer:
13715 *
13716 * 254 word (508 byte) table indexed by byte code followed
13717 * by the following byte codes:
13718 *
13719 * 1-Byte Code:
13720 * 00: Emit word 0 in table.
13721 * 01: Emit word 1 in table.
13722 * .
13723 * FD: Emit word 253 in table.
13724 *
13725 * Multi-Byte Code:
13726 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
13727 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
13728 */
13729 word = 0;
13730 for (i = 253 * 2; i < _adv_asc3550_size; i++) {
13731 if (_adv_asc3550_buf[i] == 0xff) {
13732 for (j = 0; j < _adv_asc3550_buf[i + 1]; j++) {
13733 AdvWriteWordAutoIncLram(iop_base, (((ushort)
13734 _adv_asc3550_buf
13735 [i +
13736 3] << 8) |
13737 _adv_asc3550_buf
13738 [i + 2]));
13739 word++;
13740 }
13741 i += 3;
13742 } else if (_adv_asc3550_buf[i] == 0xfe) {
13743 AdvWriteWordAutoIncLram(iop_base, (((ushort)
13744 _adv_asc3550_buf[i +
13745 2]
13746 << 8) |
13747 _adv_asc3550_buf[i +
13748 1]));
13749 i += 2;
13750 word++;
13751 } else {
13752 AdvWriteWordAutoIncLram(iop_base, (((ushort)
13753 _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) | _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
13754 word++;
13755 }
13756 }
1da177e4 13757
27c868c2
MW
13758 /*
13759 * Set 'word' for later use to clear the rest of memory and save
13760 * the expanded mcode size.
13761 */
13762 word *= 2;
13763 adv_asc3550_expanded_size = word;
13764
13765 /*
13766 * Clear the rest of ASC-3550 Internal RAM (8KB).
13767 */
13768 for (; word < ADV_3550_MEMSIZE; word += 2) {
13769 AdvWriteWordAutoIncLram(iop_base, 0);
13770 }
1da177e4 13771
27c868c2
MW
13772 /*
13773 * Verify the microcode checksum.
13774 */
13775 sum = 0;
13776 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
1da177e4 13777
27c868c2
MW
13778 for (word = 0; word < adv_asc3550_expanded_size; word += 2) {
13779 sum += AdvReadWordAutoIncLram(iop_base);
13780 }
1da177e4 13781
27c868c2
MW
13782 if (sum != _adv_asc3550_chksum) {
13783 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
13784 return ADV_ERROR;
13785 }
1da177e4 13786
27c868c2
MW
13787 /*
13788 * Restore the RISC memory BIOS region.
13789 */
13790 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
13791 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
13792 bios_mem[i]);
13793 }
1da177e4 13794
27c868c2
MW
13795 /*
13796 * Calculate and write the microcode code checksum to the microcode
13797 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
13798 */
13799 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
13800 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
13801 code_sum = 0;
13802 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
13803 for (word = begin_addr; word < end_addr; word += 2) {
13804 code_sum += AdvReadWordAutoIncLram(iop_base);
13805 }
13806 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
13807
13808 /*
13809 * Read and save microcode version and date.
13810 */
13811 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
13812 asc_dvc->cfg->mcode_date);
13813 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
13814 asc_dvc->cfg->mcode_version);
13815
13816 /*
13817 * Set the chip type to indicate the ASC3550.
13818 */
13819 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
13820
13821 /*
13822 * If the PCI Configuration Command Register "Parity Error Response
13823 * Control" Bit was clear (0), then set the microcode variable
13824 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
13825 * to ignore DMA parity errors.
13826 */
13827 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
13828 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
13829 word |= CONTROL_FLAG_IGNORE_PERR;
13830 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
13831 }
1da177e4 13832
27c868c2
MW
13833 /*
13834 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
13835 * threshold of 128 bytes. This register is only accessible to the host.
13836 */
13837 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
13838 START_CTL_EMFU | READ_CMD_MRM);
13839
13840 /*
13841 * Microcode operating variables for WDTR, SDTR, and command tag
47d853cc 13842 * queuing will be set in slave_configure() based on what a
27c868c2
MW
13843 * device reports it is capable of in Inquiry byte 7.
13844 *
13845 * If SCSI Bus Resets have been disabled, then directly set
13846 * SDTR and WDTR from the EEPROM configuration. This will allow
13847 * the BIOS and warm boot to work without a SCSI bus hang on
13848 * the Inquiry caused by host and target mismatched DTR values.
13849 * Without the SCSI Bus Reset, before an Inquiry a device can't
13850 * be assumed to be in Asynchronous, Narrow mode.
13851 */
13852 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
13853 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
13854 asc_dvc->wdtr_able);
13855 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
13856 asc_dvc->sdtr_able);
13857 }
1da177e4 13858
27c868c2
MW
13859 /*
13860 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
13861 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
13862 * bitmask. These values determine the maximum SDTR speed negotiated
13863 * with a device.
13864 *
13865 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
13866 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
13867 * without determining here whether the device supports SDTR.
13868 *
13869 * 4-bit speed SDTR speed name
13870 * =========== ===============
13871 * 0000b (0x0) SDTR disabled
13872 * 0001b (0x1) 5 Mhz
13873 * 0010b (0x2) 10 Mhz
13874 * 0011b (0x3) 20 Mhz (Ultra)
13875 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
13876 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
13877 * 0110b (0x6) Undefined
13878 * .
13879 * 1111b (0xF) Undefined
13880 */
13881 word = 0;
13882 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13883 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
13884 /* Set Ultra speed for TID 'tid'. */
13885 word |= (0x3 << (4 * (tid % 4)));
13886 } else {
13887 /* Set Fast speed for TID 'tid'. */
13888 word |= (0x2 << (4 * (tid % 4)));
13889 }
13890 if (tid == 3) { /* Check if done with sdtr_speed1. */
13891 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
13892 word = 0;
13893 } else if (tid == 7) { /* Check if done with sdtr_speed2. */
13894 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
13895 word = 0;
13896 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
13897 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
13898 word = 0;
13899 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
13900 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
13901 /* End of loop. */
13902 }
13903 }
1da177e4 13904
27c868c2
MW
13905 /*
13906 * Set microcode operating variable for the disconnect per TID bitmask.
13907 */
13908 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
13909 asc_dvc->cfg->disc_enable);
13910
13911 /*
13912 * Set SCSI_CFG0 Microcode Default Value.
13913 *
13914 * The microcode will set the SCSI_CFG0 register using this value
13915 * after it is started below.
13916 */
13917 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
13918 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
13919 asc_dvc->chip_scsi_id);
13920
13921 /*
13922 * Determine SCSI_CFG1 Microcode Default Value.
13923 *
13924 * The microcode will set the SCSI_CFG1 register using this value
13925 * after it is started below.
13926 */
13927
13928 /* Read current SCSI_CFG1 Register value. */
13929 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
13930
13931 /*
13932 * If all three connectors are in use, return an error.
13933 */
13934 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
13935 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
13936 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
13937 return ADV_ERROR;
13938 }
1da177e4 13939
27c868c2
MW
13940 /*
13941 * If the internal narrow cable is reversed all of the SCSI_CTRL
13942 * register signals will be set. Check for and return an error if
13943 * this condition is found.
13944 */
13945 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
13946 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
13947 return ADV_ERROR;
13948 }
1da177e4 13949
27c868c2
MW
13950 /*
13951 * If this is a differential board and a single-ended device
13952 * is attached to one of the connectors, return an error.
13953 */
13954 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
13955 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
13956 return ADV_ERROR;
13957 }
1da177e4 13958
27c868c2
MW
13959 /*
13960 * If automatic termination control is enabled, then set the
13961 * termination value based on a table listed in a_condor.h.
13962 *
13963 * If manual termination was specified with an EEPROM setting
13964 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
13965 * is ready to be 'ored' into SCSI_CFG1.
13966 */
13967 if (asc_dvc->cfg->termination == 0) {
13968 /*
13969 * The software always controls termination by setting TERM_CTL_SEL.
13970 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
13971 */
13972 asc_dvc->cfg->termination |= TERM_CTL_SEL;
13973
13974 switch (scsi_cfg1 & CABLE_DETECT) {
13975 /* TERM_CTL_H: on, TERM_CTL_L: on */
13976 case 0x3:
13977 case 0x7:
13978 case 0xB:
13979 case 0xD:
13980 case 0xE:
13981 case 0xF:
13982 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
13983 break;
13984
13985 /* TERM_CTL_H: on, TERM_CTL_L: off */
13986 case 0x1:
13987 case 0x5:
13988 case 0x9:
13989 case 0xA:
13990 case 0xC:
13991 asc_dvc->cfg->termination |= TERM_CTL_H;
13992 break;
13993
13994 /* TERM_CTL_H: off, TERM_CTL_L: off */
13995 case 0x2:
13996 case 0x6:
13997 break;
13998 }
13999 }
1da177e4 14000
27c868c2
MW
14001 /*
14002 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
14003 */
14004 scsi_cfg1 &= ~TERM_CTL;
14005
14006 /*
14007 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
14008 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
14009 * referenced, because the hardware internally inverts
14010 * the Termination High and Low bits if TERM_POL is set.
14011 */
14012 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
14013
14014 /*
14015 * Set SCSI_CFG1 Microcode Default Value
14016 *
14017 * Set filter value and possibly modified termination control
14018 * bits in the Microcode SCSI_CFG1 Register Value.
14019 *
14020 * The microcode will set the SCSI_CFG1 register using this value
14021 * after it is started below.
14022 */
14023 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
14024 FLTR_DISABLE | scsi_cfg1);
14025
14026 /*
14027 * Set MEM_CFG Microcode Default Value
14028 *
14029 * The microcode will set the MEM_CFG register using this value
14030 * after it is started below.
14031 *
14032 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
14033 * are defined.
14034 *
14035 * ASC-3550 has 8KB internal memory.
14036 */
14037 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
14038 BIOS_EN | RAM_SZ_8KB);
14039
14040 /*
14041 * Set SEL_MASK Microcode Default Value
14042 *
14043 * The microcode will set the SEL_MASK register using this value
14044 * after it is started below.
14045 */
14046 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
14047 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
14048
14049 /*
14050 * Build carrier freelist.
14051 *
14052 * Driver must have already allocated memory and set 'carrier_buf'.
14053 */
14054 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
14055
14056 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
14057 asc_dvc->carr_freelist = NULL;
14058 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
14059 buf_size = ADV_CARRIER_BUFSIZE;
14060 } else {
14061 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
14062 }
1da177e4 14063
27c868c2
MW
14064 do {
14065 /*
14066 * Get physical address of the carrier 'carrp'.
14067 */
14068 contig_len = sizeof(ADV_CARR_T);
14069 carr_paddr =
14070 cpu_to_le32(DvcGetPhyAddr
14071 (asc_dvc, NULL, (uchar *)carrp,
14072 (ADV_SDCNT *)&contig_len,
14073 ADV_IS_CARRIER_FLAG));
1da177e4 14074
27c868c2 14075 buf_size -= sizeof(ADV_CARR_T);
1da177e4 14076
27c868c2
MW
14077 /*
14078 * If the current carrier is not physically contiguous, then
14079 * maybe there was a page crossing. Try the next carrier aligned
14080 * start address.
14081 */
14082 if (contig_len < sizeof(ADV_CARR_T)) {
14083 carrp++;
14084 continue;
14085 }
14086
14087 carrp->carr_pa = carr_paddr;
14088 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
1da177e4 14089
27c868c2
MW
14090 /*
14091 * Insert the carrier at the beginning of the freelist.
14092 */
14093 carrp->next_vpa =
14094 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
14095 asc_dvc->carr_freelist = carrp;
1da177e4 14096
27c868c2
MW
14097 carrp++;
14098 }
14099 while (buf_size > 0);
1da177e4 14100
27c868c2
MW
14101 /*
14102 * Set-up the Host->RISC Initiator Command Queue (ICQ).
14103 */
1da177e4 14104
27c868c2
MW
14105 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
14106 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14107 return ADV_ERROR;
14108 }
14109 asc_dvc->carr_freelist = (ADV_CARR_T *)
14110 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
14111
14112 /*
14113 * The first command issued will be placed in the stopper carrier.
14114 */
14115 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14116
14117 /*
14118 * Set RISC ICQ physical address start value.
14119 */
14120 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
14121
14122 /*
14123 * Set-up the RISC->Host Initiator Response Queue (IRQ).
14124 */
14125 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
14126 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14127 return ADV_ERROR;
14128 }
14129 asc_dvc->carr_freelist = (ADV_CARR_T *)
14130 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
14131
14132 /*
14133 * The first command completed by the RISC will be placed in
14134 * the stopper.
14135 *
14136 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
14137 * completed the RISC will set the ASC_RQ_STOPPER bit.
14138 */
14139 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14140
14141 /*
14142 * Set RISC IRQ physical address start value.
14143 */
14144 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
14145 asc_dvc->carr_pending_cnt = 0;
14146
14147 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
14148 (ADV_INTR_ENABLE_HOST_INTR |
14149 ADV_INTR_ENABLE_GLOBAL_INTR));
14150
14151 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
14152 AdvWriteWordRegister(iop_base, IOPW_PC, word);
14153
14154 /* finally, finally, gentlemen, start your engine */
14155 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
14156
14157 /*
14158 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
14159 * Resets should be performed. The RISC has to be running
14160 * to issue a SCSI Bus Reset.
14161 */
14162 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
14163 /*
14164 * If the BIOS Signature is present in memory, restore the
14165 * BIOS Handshake Configuration Table and do not perform
14166 * a SCSI Bus Reset.
14167 */
14168 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
14169 0x55AA) {
14170 /*
14171 * Restore per TID negotiated values.
14172 */
14173 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14174 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14175 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
14176 tagqng_able);
14177 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14178 AdvWriteByteLram(iop_base,
14179 ASC_MC_NUMBER_OF_MAX_CMD + tid,
14180 max_cmd[tid]);
14181 }
14182 } else {
14183 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
14184 warn_code = ASC_WARN_BUSRESET_ERROR;
14185 }
14186 }
14187 }
1da177e4 14188
27c868c2
MW
14189 return warn_code;
14190}
1da177e4 14191
27c868c2
MW
14192/*
14193 * Initialize the ASC-38C0800.
14194 *
14195 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14196 *
14197 * For a non-fatal error return a warning code. If there are no warnings
14198 * then 0 is returned.
14199 *
14200 * Needed after initialization for error recovery.
14201 */
14202static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
14203{
14204 AdvPortAddr iop_base;
14205 ushort warn_code;
14206 ADV_DCNT sum;
14207 int begin_addr;
14208 int end_addr;
14209 ushort code_sum;
14210 int word;
14211 int j;
14212 int adv_asc38C0800_expanded_size;
14213 ADV_CARR_T *carrp;
14214 ADV_DCNT contig_len;
14215 ADV_SDCNT buf_size;
14216 ADV_PADDR carr_paddr;
14217 int i;
14218 ushort scsi_cfg1;
14219 uchar byte;
14220 uchar tid;
14221 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
14222 ushort wdtr_able, sdtr_able, tagqng_able;
14223 uchar max_cmd[ADV_MAX_TID + 1];
14224
14225 /* If there is already an error, don't continue. */
14226 if (asc_dvc->err_code != 0) {
14227 return ADV_ERROR;
14228 }
1da177e4 14229
27c868c2
MW
14230 /*
14231 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
14232 */
14233 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
14234 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
14235 return ADV_ERROR;
14236 }
1da177e4 14237
27c868c2
MW
14238 warn_code = 0;
14239 iop_base = asc_dvc->iop_base;
14240
14241 /*
14242 * Save the RISC memory BIOS region before writing the microcode.
14243 * The BIOS may already be loaded and using its RISC LRAM region
14244 * so its region must be saved and restored.
14245 *
14246 * Note: This code makes the assumption, which is currently true,
14247 * that a chip reset does not clear RISC LRAM.
14248 */
14249 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14250 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14251 bios_mem[i]);
14252 }
1da177e4 14253
27c868c2
MW
14254 /*
14255 * Save current per TID negotiated values.
14256 */
14257 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14258 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14259 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14260 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14261 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14262 max_cmd[tid]);
14263 }
1da177e4 14264
27c868c2
MW
14265 /*
14266 * RAM BIST (RAM Built-In Self Test)
14267 *
14268 * Address : I/O base + offset 0x38h register (byte).
14269 * Function: Bit 7-6(RW) : RAM mode
14270 * Normal Mode : 0x00
14271 * Pre-test Mode : 0x40
14272 * RAM Test Mode : 0x80
14273 * Bit 5 : unused
14274 * Bit 4(RO) : Done bit
14275 * Bit 3-0(RO) : Status
14276 * Host Error : 0x08
14277 * Int_RAM Error : 0x04
14278 * RISC Error : 0x02
14279 * SCSI Error : 0x01
14280 * No Error : 0x00
14281 *
14282 * Note: RAM BIST code should be put right here, before loading the
14283 * microcode and after saving the RISC memory BIOS region.
14284 */
14285
14286 /*
14287 * LRAM Pre-test
14288 *
14289 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
14290 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
14291 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
14292 * to NORMAL_MODE, return an error too.
14293 */
14294 for (i = 0; i < 2; i++) {
14295 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
14296 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14297 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14298 if ((byte & RAM_TEST_DONE) == 0
14299 || (byte & 0x0F) != PRE_TEST_VALUE) {
14300 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14301 return ADV_ERROR;
14302 }
14303
14304 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14305 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14306 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
14307 != NORMAL_VALUE) {
14308 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14309 return ADV_ERROR;
14310 }
14311 }
1da177e4 14312
27c868c2
MW
14313 /*
14314 * LRAM Test - It takes about 1.5 ms to run through the test.
14315 *
14316 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
14317 * If Done bit not set or Status not 0, save register byte, set the
14318 * err_code, and return an error.
14319 */
14320 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
14321 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
14322
14323 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14324 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
14325 /* Get here if Done bit not set or Status not 0. */
14326 asc_dvc->bist_err_code = byte; /* for BIOS display message */
14327 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
14328 return ADV_ERROR;
14329 }
1da177e4 14330
27c868c2
MW
14331 /* We need to reset back to normal mode after LRAM test passes. */
14332 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14333
14334 /*
14335 * Load the Microcode
14336 *
14337 * Write the microcode image to RISC memory starting at address 0.
14338 *
14339 */
14340 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14341
14342 /* Assume the following compressed format of the microcode buffer:
14343 *
14344 * 254 word (508 byte) table indexed by byte code followed
14345 * by the following byte codes:
14346 *
14347 * 1-Byte Code:
14348 * 00: Emit word 0 in table.
14349 * 01: Emit word 1 in table.
14350 * .
14351 * FD: Emit word 253 in table.
14352 *
14353 * Multi-Byte Code:
14354 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14355 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14356 */
14357 word = 0;
14358 for (i = 253 * 2; i < _adv_asc38C0800_size; i++) {
14359 if (_adv_asc38C0800_buf[i] == 0xff) {
14360 for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++) {
14361 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14362 _adv_asc38C0800_buf
14363 [i +
14364 3] << 8) |
14365 _adv_asc38C0800_buf
14366 [i + 2]));
14367 word++;
14368 }
14369 i += 3;
14370 } else if (_adv_asc38C0800_buf[i] == 0xfe) {
14371 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14372 _adv_asc38C0800_buf
14373 [i +
14374 2] << 8) |
14375 _adv_asc38C0800_buf[i
14376 +
14377 1]));
14378 i += 2;
14379 word++;
14380 } else {
14381 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14382 _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) | _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
14383 word++;
14384 }
14385 }
1da177e4 14386
27c868c2
MW
14387 /*
14388 * Set 'word' for later use to clear the rest of memory and save
14389 * the expanded mcode size.
14390 */
14391 word *= 2;
14392 adv_asc38C0800_expanded_size = word;
14393
14394 /*
14395 * Clear the rest of ASC-38C0800 Internal RAM (16KB).
14396 */
14397 for (; word < ADV_38C0800_MEMSIZE; word += 2) {
14398 AdvWriteWordAutoIncLram(iop_base, 0);
14399 }
1da177e4 14400
27c868c2
MW
14401 /*
14402 * Verify the microcode checksum.
14403 */
14404 sum = 0;
14405 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
1da177e4 14406
27c868c2
MW
14407 for (word = 0; word < adv_asc38C0800_expanded_size; word += 2) {
14408 sum += AdvReadWordAutoIncLram(iop_base);
14409 }
14410 ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
1da177e4 14411
27c868c2
MW
14412 ASC_DBG2(1,
14413 "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
14414 (ulong)sum, (ulong)_adv_asc38C0800_chksum);
1da177e4 14415
27c868c2
MW
14416 if (sum != _adv_asc38C0800_chksum) {
14417 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14418 return ADV_ERROR;
14419 }
1da177e4 14420
27c868c2
MW
14421 /*
14422 * Restore the RISC memory BIOS region.
14423 */
14424 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14425 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14426 bios_mem[i]);
14427 }
1da177e4 14428
27c868c2
MW
14429 /*
14430 * Calculate and write the microcode code checksum to the microcode
14431 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14432 */
14433 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14434 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14435 code_sum = 0;
14436 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14437 for (word = begin_addr; word < end_addr; word += 2) {
14438 code_sum += AdvReadWordAutoIncLram(iop_base);
14439 }
14440 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14441
14442 /*
14443 * Read microcode version and date.
14444 */
14445 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
14446 asc_dvc->cfg->mcode_date);
14447 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
14448 asc_dvc->cfg->mcode_version);
14449
14450 /*
14451 * Set the chip type to indicate the ASC38C0800.
14452 */
14453 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
14454
14455 /*
14456 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
14457 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
14458 * cable detection and then we are able to read C_DET[3:0].
14459 *
14460 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
14461 * Microcode Default Value' section below.
14462 */
14463 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14464 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
14465 scsi_cfg1 | DIS_TERM_DRV);
14466
14467 /*
14468 * If the PCI Configuration Command Register "Parity Error Response
14469 * Control" Bit was clear (0), then set the microcode variable
14470 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14471 * to ignore DMA parity errors.
14472 */
14473 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
14474 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14475 word |= CONTROL_FLAG_IGNORE_PERR;
14476 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14477 }
1da177e4 14478
27c868c2
MW
14479 /*
14480 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
14481 * bits for the default FIFO threshold.
14482 *
14483 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
14484 *
14485 * For DMA Errata #4 set the BC_THRESH_ENB bit.
14486 */
14487 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14488 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
14489 READ_CMD_MRM);
14490
14491 /*
14492 * Microcode operating variables for WDTR, SDTR, and command tag
47d853cc 14493 * queuing will be set in slave_configure() based on what a
27c868c2
MW
14494 * device reports it is capable of in Inquiry byte 7.
14495 *
14496 * If SCSI Bus Resets have been disabled, then directly set
14497 * SDTR and WDTR from the EEPROM configuration. This will allow
14498 * the BIOS and warm boot to work without a SCSI bus hang on
14499 * the Inquiry caused by host and target mismatched DTR values.
14500 * Without the SCSI Bus Reset, before an Inquiry a device can't
14501 * be assumed to be in Asynchronous, Narrow mode.
14502 */
14503 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
14504 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
14505 asc_dvc->wdtr_able);
14506 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
14507 asc_dvc->sdtr_able);
14508 }
1da177e4 14509
27c868c2
MW
14510 /*
14511 * Set microcode operating variables for DISC and SDTR_SPEED1,
14512 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
14513 * configuration values.
14514 *
14515 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14516 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14517 * without determining here whether the device supports SDTR.
14518 */
14519 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
14520 asc_dvc->cfg->disc_enable);
14521 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
14522 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
14523 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
14524 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
14525
14526 /*
14527 * Set SCSI_CFG0 Microcode Default Value.
14528 *
14529 * The microcode will set the SCSI_CFG0 register using this value
14530 * after it is started below.
14531 */
14532 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14533 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14534 asc_dvc->chip_scsi_id);
14535
14536 /*
14537 * Determine SCSI_CFG1 Microcode Default Value.
14538 *
14539 * The microcode will set the SCSI_CFG1 register using this value
14540 * after it is started below.
14541 */
14542
14543 /* Read current SCSI_CFG1 Register value. */
14544 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14545
14546 /*
14547 * If the internal narrow cable is reversed all of the SCSI_CTRL
14548 * register signals will be set. Check for and return an error if
14549 * this condition is found.
14550 */
14551 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
14552 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14553 return ADV_ERROR;
14554 }
1da177e4 14555
27c868c2
MW
14556 /*
14557 * All kind of combinations of devices attached to one of four connectors
14558 * are acceptable except HVD device attached. For example, LVD device can
14559 * be attached to SE connector while SE device attached to LVD connector.
14560 * If LVD device attached to SE connector, it only runs up to Ultra speed.
14561 *
14562 * If an HVD device is attached to one of LVD connectors, return an error.
14563 * However, there is no way to detect HVD device attached to SE connectors.
14564 */
14565 if (scsi_cfg1 & HVD) {
14566 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
14567 return ADV_ERROR;
14568 }
1da177e4 14569
27c868c2
MW
14570 /*
14571 * If either SE or LVD automatic termination control is enabled, then
14572 * set the termination value based on a table listed in a_condor.h.
14573 *
14574 * If manual termination was specified with an EEPROM setting then
14575 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
14576 * be 'ored' into SCSI_CFG1.
14577 */
14578 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
14579 /* SE automatic termination control is enabled. */
14580 switch (scsi_cfg1 & C_DET_SE) {
14581 /* TERM_SE_HI: on, TERM_SE_LO: on */
14582 case 0x1:
14583 case 0x2:
14584 case 0x3:
14585 asc_dvc->cfg->termination |= TERM_SE;
14586 break;
14587
14588 /* TERM_SE_HI: on, TERM_SE_LO: off */
14589 case 0x0:
14590 asc_dvc->cfg->termination |= TERM_SE_HI;
14591 break;
14592 }
14593 }
14594
14595 if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
14596 /* LVD automatic termination control is enabled. */
14597 switch (scsi_cfg1 & C_DET_LVD) {
14598 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
14599 case 0x4:
14600 case 0x8:
14601 case 0xC:
14602 asc_dvc->cfg->termination |= TERM_LVD;
14603 break;
14604
14605 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
14606 case 0x0:
14607 break;
14608 }
14609 }
14610
14611 /*
14612 * Clear any set TERM_SE and TERM_LVD bits.
14613 */
14614 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
14615
14616 /*
14617 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
14618 */
14619 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
14620
14621 /*
14622 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
14623 * and set possibly modified termination control bits in the Microcode
14624 * SCSI_CFG1 Register Value.
14625 */
14626 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
14627
14628 /*
14629 * Set SCSI_CFG1 Microcode Default Value
14630 *
14631 * Set possibly modified termination control and reset DIS_TERM_DRV
14632 * bits in the Microcode SCSI_CFG1 Register Value.
14633 *
14634 * The microcode will set the SCSI_CFG1 register using this value
14635 * after it is started below.
14636 */
14637 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
14638
14639 /*
14640 * Set MEM_CFG Microcode Default Value
14641 *
14642 * The microcode will set the MEM_CFG register using this value
14643 * after it is started below.
14644 *
14645 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
14646 * are defined.
14647 *
14648 * ASC-38C0800 has 16KB internal memory.
14649 */
14650 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
14651 BIOS_EN | RAM_SZ_16KB);
14652
14653 /*
14654 * Set SEL_MASK Microcode Default Value
14655 *
14656 * The microcode will set the SEL_MASK register using this value
14657 * after it is started below.
14658 */
14659 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
14660 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
14661
14662 /*
14663 * Build the carrier freelist.
14664 *
14665 * Driver must have already allocated memory and set 'carrier_buf'.
14666 */
14667 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
14668
14669 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
14670 asc_dvc->carr_freelist = NULL;
14671 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
14672 buf_size = ADV_CARRIER_BUFSIZE;
14673 } else {
14674 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
14675 }
14676
14677 do {
14678 /*
14679 * Get physical address for the carrier 'carrp'.
14680 */
14681 contig_len = sizeof(ADV_CARR_T);
14682 carr_paddr =
14683 cpu_to_le32(DvcGetPhyAddr
14684 (asc_dvc, NULL, (uchar *)carrp,
14685 (ADV_SDCNT *)&contig_len,
14686 ADV_IS_CARRIER_FLAG));
1da177e4 14687
27c868c2
MW
14688 buf_size -= sizeof(ADV_CARR_T);
14689
14690 /*
14691 * If the current carrier is not physically contiguous, then
14692 * maybe there was a page crossing. Try the next carrier aligned
14693 * start address.
14694 */
14695 if (contig_len < sizeof(ADV_CARR_T)) {
14696 carrp++;
14697 continue;
14698 }
14699
14700 carrp->carr_pa = carr_paddr;
14701 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
14702
14703 /*
14704 * Insert the carrier at the beginning of the freelist.
14705 */
14706 carrp->next_vpa =
14707 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
14708 asc_dvc->carr_freelist = carrp;
14709
14710 carrp++;
14711 }
14712 while (buf_size > 0);
14713
14714 /*
14715 * Set-up the Host->RISC Initiator Command Queue (ICQ).
14716 */
14717
14718 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
14719 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14720 return ADV_ERROR;
14721 }
14722 asc_dvc->carr_freelist = (ADV_CARR_T *)
14723 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
14724
14725 /*
14726 * The first command issued will be placed in the stopper carrier.
14727 */
14728 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14729
14730 /*
14731 * Set RISC ICQ physical address start value.
14732 * carr_pa is LE, must be native before write
14733 */
14734 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
14735
14736 /*
14737 * Set-up the RISC->Host Initiator Response Queue (IRQ).
14738 */
14739 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
14740 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14741 return ADV_ERROR;
14742 }
14743 asc_dvc->carr_freelist = (ADV_CARR_T *)
14744 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
14745
14746 /*
14747 * The first command completed by the RISC will be placed in
14748 * the stopper.
14749 *
14750 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
14751 * completed the RISC will set the ASC_RQ_STOPPER bit.
14752 */
14753 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14754
14755 /*
14756 * Set RISC IRQ physical address start value.
14757 *
14758 * carr_pa is LE, must be native before write *
14759 */
14760 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
14761 asc_dvc->carr_pending_cnt = 0;
14762
14763 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
14764 (ADV_INTR_ENABLE_HOST_INTR |
14765 ADV_INTR_ENABLE_GLOBAL_INTR));
14766
14767 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
14768 AdvWriteWordRegister(iop_base, IOPW_PC, word);
14769
14770 /* finally, finally, gentlemen, start your engine */
14771 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
14772
14773 /*
14774 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
14775 * Resets should be performed. The RISC has to be running
14776 * to issue a SCSI Bus Reset.
14777 */
14778 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
14779 /*
14780 * If the BIOS Signature is present in memory, restore the
14781 * BIOS Handshake Configuration Table and do not perform
14782 * a SCSI Bus Reset.
14783 */
14784 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
14785 0x55AA) {
14786 /*
14787 * Restore per TID negotiated values.
14788 */
14789 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14790 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14791 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
14792 tagqng_able);
14793 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14794 AdvWriteByteLram(iop_base,
14795 ASC_MC_NUMBER_OF_MAX_CMD + tid,
14796 max_cmd[tid]);
14797 }
14798 } else {
14799 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
14800 warn_code = ASC_WARN_BUSRESET_ERROR;
14801 }
14802 }
14803 }
14804
14805 return warn_code;
1da177e4
LT
14806}
14807
14808/*
27c868c2 14809 * Initialize the ASC-38C1600.
1da177e4 14810 *
27c868c2 14811 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
1da177e4
LT
14812 *
14813 * For a non-fatal error return a warning code. If there are no warnings
14814 * then 0 is returned.
14815 *
14816 * Needed after initialization for error recovery.
14817 */
27c868c2 14818static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
1da177e4 14819{
27c868c2
MW
14820 AdvPortAddr iop_base;
14821 ushort warn_code;
14822 ADV_DCNT sum;
14823 int begin_addr;
14824 int end_addr;
14825 ushort code_sum;
14826 long word;
14827 int j;
14828 int adv_asc38C1600_expanded_size;
14829 ADV_CARR_T *carrp;
14830 ADV_DCNT contig_len;
14831 ADV_SDCNT buf_size;
14832 ADV_PADDR carr_paddr;
14833 int i;
14834 ushort scsi_cfg1;
14835 uchar byte;
14836 uchar tid;
14837 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
14838 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
14839 uchar max_cmd[ASC_MAX_TID + 1];
14840
14841 /* If there is already an error, don't continue. */
14842 if (asc_dvc->err_code != 0) {
14843 return ADV_ERROR;
14844 }
1da177e4 14845
27c868c2
MW
14846 /*
14847 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
14848 */
14849 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
14850 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
14851 return ADV_ERROR;
14852 }
1da177e4 14853
27c868c2
MW
14854 warn_code = 0;
14855 iop_base = asc_dvc->iop_base;
14856
14857 /*
14858 * Save the RISC memory BIOS region before writing the microcode.
14859 * The BIOS may already be loaded and using its RISC LRAM region
14860 * so its region must be saved and restored.
14861 *
14862 * Note: This code makes the assumption, which is currently true,
14863 * that a chip reset does not clear RISC LRAM.
14864 */
14865 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14866 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14867 bios_mem[i]);
14868 }
1da177e4 14869
27c868c2
MW
14870 /*
14871 * Save current per TID negotiated values.
14872 */
14873 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14874 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14875 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
14876 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14877 for (tid = 0; tid <= ASC_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 (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 /*
14960 * Assume the following compressed format of the microcode buffer:
14961 *
14962 * 254 word (508 byte) table indexed by byte code followed
14963 * by the following byte codes:
14964 *
14965 * 1-Byte Code:
14966 * 00: Emit word 0 in table.
14967 * 01: Emit word 1 in table.
14968 * .
14969 * FD: Emit word 253 in table.
14970 *
14971 * Multi-Byte Code:
14972 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14973 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14974 */
14975 word = 0;
14976 for (i = 253 * 2; i < _adv_asc38C1600_size; i++) {
14977 if (_adv_asc38C1600_buf[i] == 0xff) {
14978 for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++) {
14979 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14980 _adv_asc38C1600_buf
14981 [i +
14982 3] << 8) |
14983 _adv_asc38C1600_buf
14984 [i + 2]));
14985 word++;
14986 }
14987 i += 3;
14988 } else if (_adv_asc38C1600_buf[i] == 0xfe) {
14989 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14990 _adv_asc38C1600_buf
14991 [i +
14992 2] << 8) |
14993 _adv_asc38C1600_buf[i
14994 +
14995 1]));
14996 i += 2;
14997 word++;
14998 } else {
14999 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15000 _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) | _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
15001 word++;
15002 }
15003 }
1da177e4 15004
27c868c2
MW
15005 /*
15006 * Set 'word' for later use to clear the rest of memory and save
15007 * the expanded mcode size.
15008 */
15009 word *= 2;
15010 adv_asc38C1600_expanded_size = word;
15011
15012 /*
15013 * Clear the rest of ASC-38C1600 Internal RAM (32KB).
15014 */
15015 for (; word < ADV_38C1600_MEMSIZE; word += 2) {
15016 AdvWriteWordAutoIncLram(iop_base, 0);
15017 }
1da177e4 15018
27c868c2
MW
15019 /*
15020 * Verify the microcode checksum.
15021 */
15022 sum = 0;
15023 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
1da177e4 15024
27c868c2
MW
15025 for (word = 0; word < adv_asc38C1600_expanded_size; word += 2) {
15026 sum += AdvReadWordAutoIncLram(iop_base);
15027 }
1da177e4 15028
27c868c2
MW
15029 if (sum != _adv_asc38C1600_chksum) {
15030 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15031 return ADV_ERROR;
15032 }
1da177e4 15033
27c868c2
MW
15034 /*
15035 * Restore the RISC memory BIOS region.
15036 */
15037 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15038 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15039 bios_mem[i]);
15040 }
1da177e4 15041
27c868c2
MW
15042 /*
15043 * Calculate and write the microcode code checksum to the microcode
15044 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15045 */
15046 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15047 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15048 code_sum = 0;
15049 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15050 for (word = begin_addr; word < end_addr; word += 2) {
15051 code_sum += AdvReadWordAutoIncLram(iop_base);
15052 }
15053 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15054
15055 /*
15056 * Read microcode version and date.
15057 */
15058 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
15059 asc_dvc->cfg->mcode_date);
15060 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
15061 asc_dvc->cfg->mcode_version);
15062
15063 /*
15064 * Set the chip type to indicate the ASC38C1600.
15065 */
15066 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
15067
15068 /*
15069 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15070 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15071 * cable detection and then we are able to read C_DET[3:0].
15072 *
15073 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15074 * Microcode Default Value' section below.
15075 */
15076 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15077 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
15078 scsi_cfg1 | DIS_TERM_DRV);
15079
15080 /*
15081 * If the PCI Configuration Command Register "Parity Error Response
15082 * Control" Bit was clear (0), then set the microcode variable
15083 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15084 * to ignore DMA parity errors.
15085 */
15086 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
15087 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15088 word |= CONTROL_FLAG_IGNORE_PERR;
15089 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15090 }
1da177e4 15091
27c868c2
MW
15092 /*
15093 * If the BIOS control flag AIPP (Asynchronous Information
15094 * Phase Protection) disable bit is not set, then set the firmware
15095 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
15096 * AIPP checking and encoding.
15097 */
15098 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
15099 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15100 word |= CONTROL_FLAG_ENABLE_AIPP;
15101 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15102 }
1da177e4 15103
27c868c2
MW
15104 /*
15105 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
15106 * and START_CTL_TH [3:2].
15107 */
15108 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15109 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
15110
15111 /*
15112 * Microcode operating variables for WDTR, SDTR, and command tag
47d853cc 15113 * queuing will be set in slave_configure() based on what a
27c868c2
MW
15114 * device reports it is capable of in Inquiry byte 7.
15115 *
15116 * If SCSI Bus Resets have been disabled, then directly set
15117 * SDTR and WDTR from the EEPROM configuration. This will allow
15118 * the BIOS and warm boot to work without a SCSI bus hang on
15119 * the Inquiry caused by host and target mismatched DTR values.
15120 * Without the SCSI Bus Reset, before an Inquiry a device can't
15121 * be assumed to be in Asynchronous, Narrow mode.
15122 */
15123 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
15124 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
15125 asc_dvc->wdtr_able);
15126 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
15127 asc_dvc->sdtr_able);
15128 }
1da177e4 15129
27c868c2
MW
15130 /*
15131 * Set microcode operating variables for DISC and SDTR_SPEED1,
15132 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15133 * configuration values.
15134 *
15135 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15136 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15137 * without determining here whether the device supports SDTR.
15138 */
15139 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
15140 asc_dvc->cfg->disc_enable);
15141 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15142 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15143 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15144 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15145
15146 /*
15147 * Set SCSI_CFG0 Microcode Default Value.
15148 *
15149 * The microcode will set the SCSI_CFG0 register using this value
15150 * after it is started below.
15151 */
15152 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15153 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15154 asc_dvc->chip_scsi_id);
15155
15156 /*
15157 * Calculate SCSI_CFG1 Microcode Default Value.
15158 *
15159 * The microcode will set the SCSI_CFG1 register using this value
15160 * after it is started below.
15161 *
15162 * Each ASC-38C1600 function has only two cable detect bits.
15163 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
15164 */
15165 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15166
15167 /*
15168 * If the cable is reversed all of the SCSI_CTRL register signals
15169 * will be set. Check for and return an error if this condition is
15170 * found.
15171 */
15172 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
15173 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15174 return ADV_ERROR;
15175 }
1da177e4 15176
27c868c2
MW
15177 /*
15178 * Each ASC-38C1600 function has two connectors. Only an HVD device
15179 * can not be connected to either connector. An LVD device or SE device
15180 * may be connected to either connecor. If an SE device is connected,
15181 * then at most Ultra speed (20 Mhz) can be used on both connectors.
15182 *
15183 * If an HVD device is attached, return an error.
15184 */
15185 if (scsi_cfg1 & HVD) {
15186 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15187 return ADV_ERROR;
15188 }
1da177e4 15189
27c868c2
MW
15190 /*
15191 * Each function in the ASC-38C1600 uses only the SE cable detect and
15192 * termination because there are two connectors for each function. Each
15193 * function may use either LVD or SE mode. Corresponding the SE automatic
15194 * termination control EEPROM bits are used for each function. Each
15195 * function has its own EEPROM. If SE automatic control is enabled for
15196 * the function, then set the termination value based on a table listed
15197 * in a_condor.h.
15198 *
15199 * If manual termination is specified in the EEPROM for the function,
15200 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
15201 * ready to be 'ored' into SCSI_CFG1.
15202 */
15203 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
15204 /* SE automatic termination control is enabled. */
15205 switch (scsi_cfg1 & C_DET_SE) {
15206 /* TERM_SE_HI: on, TERM_SE_LO: on */
15207 case 0x1:
15208 case 0x2:
15209 case 0x3:
15210 asc_dvc->cfg->termination |= TERM_SE;
15211 break;
15212
15213 case 0x0:
15214 if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0) {
15215 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
15216 } else {
15217 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
15218 asc_dvc->cfg->termination |= TERM_SE_HI;
15219 }
15220 break;
15221 }
15222 }
1da177e4 15223
27c868c2
MW
15224 /*
15225 * Clear any set TERM_SE bits.
15226 */
15227 scsi_cfg1 &= ~TERM_SE;
15228
15229 /*
15230 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
15231 */
15232 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
15233
15234 /*
15235 * Clear Big Endian and Terminator Polarity bits and set possibly
15236 * modified termination control bits in the Microcode SCSI_CFG1
15237 * Register Value.
15238 *
15239 * Big Endian bit is not used even on big endian machines.
15240 */
15241 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
15242
15243 /*
15244 * Set SCSI_CFG1 Microcode Default Value
15245 *
15246 * Set possibly modified termination control bits in the Microcode
15247 * SCSI_CFG1 Register Value.
15248 *
15249 * The microcode will set the SCSI_CFG1 register using this value
15250 * after it is started below.
15251 */
15252 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15253
15254 /*
15255 * Set MEM_CFG Microcode Default Value
15256 *
15257 * The microcode will set the MEM_CFG register using this value
15258 * after it is started below.
15259 *
15260 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15261 * are defined.
15262 *
15263 * ASC-38C1600 has 32KB internal memory.
15264 *
15265 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
15266 * out a special 16K Adv Library and Microcode version. After the issue
15267 * resolved, we should turn back to the 32K support. Both a_condor.h and
15268 * mcode.sas files also need to be updated.
15269 *
15270 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15271 * BIOS_EN | RAM_SZ_32KB);
15272 */
15273 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15274 BIOS_EN | RAM_SZ_16KB);
15275
15276 /*
15277 * Set SEL_MASK Microcode Default Value
15278 *
15279 * The microcode will set the SEL_MASK register using this value
15280 * after it is started below.
15281 */
15282 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15283 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15284
15285 /*
15286 * Build the carrier freelist.
15287 *
15288 * Driver must have already allocated memory and set 'carrier_buf'.
15289 */
15290
15291 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15292
15293 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15294 asc_dvc->carr_freelist = NULL;
15295 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
15296 buf_size = ADV_CARRIER_BUFSIZE;
15297 } else {
15298 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15299 }
1da177e4 15300
27c868c2
MW
15301 do {
15302 /*
15303 * Get physical address for the carrier 'carrp'.
15304 */
15305 contig_len = sizeof(ADV_CARR_T);
15306 carr_paddr =
15307 cpu_to_le32(DvcGetPhyAddr
15308 (asc_dvc, NULL, (uchar *)carrp,
15309 (ADV_SDCNT *)&contig_len,
15310 ADV_IS_CARRIER_FLAG));
1da177e4 15311
27c868c2 15312 buf_size -= sizeof(ADV_CARR_T);
1da177e4 15313
27c868c2
MW
15314 /*
15315 * If the current carrier is not physically contiguous, then
15316 * maybe there was a page crossing. Try the next carrier aligned
15317 * start address.
15318 */
15319 if (contig_len < sizeof(ADV_CARR_T)) {
15320 carrp++;
15321 continue;
15322 }
15323
15324 carrp->carr_pa = carr_paddr;
15325 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
1da177e4 15326
27c868c2
MW
15327 /*
15328 * Insert the carrier at the beginning of the freelist.
15329 */
15330 carrp->next_vpa =
15331 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15332 asc_dvc->carr_freelist = carrp;
1da177e4 15333
27c868c2
MW
15334 carrp++;
15335 }
15336 while (buf_size > 0);
15337
15338 /*
15339 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15340 */
15341 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
15342 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15343 return ADV_ERROR;
15344 }
15345 asc_dvc->carr_freelist = (ADV_CARR_T *)
15346 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15347
15348 /*
15349 * The first command issued will be placed in the stopper carrier.
15350 */
15351 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15352
15353 /*
15354 * Set RISC ICQ physical address start value. Initialize the
15355 * COMMA register to the same value otherwise the RISC will
15356 * prematurely detect a command is available.
15357 */
15358 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15359 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
15360 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
15361
15362 /*
15363 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15364 */
15365 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
15366 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15367 return ADV_ERROR;
15368 }
15369 asc_dvc->carr_freelist = (ADV_CARR_T *)
15370 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15371
15372 /*
15373 * The first command completed by the RISC will be placed in
15374 * the stopper.
15375 *
15376 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15377 * completed the RISC will set the ASC_RQ_STOPPER bit.
15378 */
15379 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15380
15381 /*
15382 * Set RISC IRQ physical address start value.
15383 */
15384 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15385 asc_dvc->carr_pending_cnt = 0;
15386
15387 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15388 (ADV_INTR_ENABLE_HOST_INTR |
15389 ADV_INTR_ENABLE_GLOBAL_INTR));
15390 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15391 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15392
15393 /* finally, finally, gentlemen, start your engine */
15394 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15395
15396 /*
15397 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15398 * Resets should be performed. The RISC has to be running
15399 * to issue a SCSI Bus Reset.
15400 */
15401 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
15402 /*
15403 * If the BIOS Signature is present in memory, restore the
15404 * per TID microcode operating variables.
15405 */
15406 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
15407 0x55AA) {
15408 /*
15409 * Restore per TID negotiated values.
15410 */
15411 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15412 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15413 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15414 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
15415 tagqng_able);
15416 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15417 AdvWriteByteLram(iop_base,
15418 ASC_MC_NUMBER_OF_MAX_CMD + tid,
15419 max_cmd[tid]);
15420 }
15421 } else {
15422 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
15423 warn_code = ASC_WARN_BUSRESET_ERROR;
15424 }
15425 }
15426 }
1da177e4 15427
27c868c2
MW
15428 return warn_code;
15429}
1da177e4 15430
27c868c2
MW
15431/*
15432 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
15433 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
15434 * all of this is done.
15435 *
15436 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15437 *
15438 * For a non-fatal error return a warning code. If there are no warnings
15439 * then 0 is returned.
15440 *
15441 * Note: Chip is stopped on entry.
15442 */
78e77d8b 15443static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
27c868c2
MW
15444{
15445 AdvPortAddr iop_base;
15446 ushort warn_code;
15447 ADVEEP_3550_CONFIG eep_config;
15448 int i;
1da177e4 15449
27c868c2 15450 iop_base = asc_dvc->iop_base;
1da177e4 15451
27c868c2 15452 warn_code = 0;
1da177e4 15453
27c868c2
MW
15454 /*
15455 * Read the board's EEPROM configuration.
15456 *
15457 * Set default values if a bad checksum is found.
15458 */
15459 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
15460 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 15461
27c868c2
MW
15462 /*
15463 * Set EEPROM default values.
15464 */
15465 for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++) {
15466 *((uchar *)&eep_config + i) =
15467 *((uchar *)&Default_3550_EEPROM_Config + i);
15468 }
1da177e4 15469
27c868c2
MW
15470 /*
15471 * Assume the 6 byte board serial number that was read
15472 * from EEPROM is correct even if the EEPROM checksum
15473 * failed.
15474 */
15475 eep_config.serial_number_word3 =
15476 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 15477
27c868c2
MW
15478 eep_config.serial_number_word2 =
15479 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
1da177e4 15480
27c868c2
MW
15481 eep_config.serial_number_word1 =
15482 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 15483
27c868c2
MW
15484 AdvSet3550EEPConfig(iop_base, &eep_config);
15485 }
15486 /*
15487 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
15488 * EEPROM configuration that was read.
15489 *
15490 * This is the mapping of EEPROM fields to Adv Library fields.
15491 */
15492 asc_dvc->wdtr_able = eep_config.wdtr_able;
15493 asc_dvc->sdtr_able = eep_config.sdtr_able;
15494 asc_dvc->ultra_able = eep_config.ultra_able;
15495 asc_dvc->tagqng_able = eep_config.tagqng_able;
15496 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
15497 asc_dvc->max_host_qng = eep_config.max_host_qng;
15498 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15499 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
15500 asc_dvc->start_motor = eep_config.start_motor;
15501 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
15502 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
15503 asc_dvc->no_scam = eep_config.scam_tolerant;
15504 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
15505 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
15506 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
15507
15508 /*
15509 * Set the host maximum queuing (max. 253, min. 16) and the per device
15510 * maximum queuing (max. 63, min. 4).
15511 */
15512 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
15513 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15514 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
15515 /* If the value is zero, assume it is uninitialized. */
15516 if (eep_config.max_host_qng == 0) {
15517 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15518 } else {
15519 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
15520 }
15521 }
1da177e4 15522
27c868c2
MW
15523 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
15524 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15525 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
15526 /* If the value is zero, assume it is uninitialized. */
15527 if (eep_config.max_dvc_qng == 0) {
15528 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15529 } else {
15530 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
15531 }
15532 }
1da177e4 15533
27c868c2
MW
15534 /*
15535 * If 'max_dvc_qng' is greater than 'max_host_qng', then
15536 * set 'max_dvc_qng' to 'max_host_qng'.
15537 */
15538 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
15539 eep_config.max_dvc_qng = eep_config.max_host_qng;
15540 }
1da177e4 15541
27c868c2
MW
15542 /*
15543 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
15544 * values based on possibly adjusted EEPROM values.
15545 */
15546 asc_dvc->max_host_qng = eep_config.max_host_qng;
15547 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15548
15549 /*
15550 * If the EEPROM 'termination' field is set to automatic (0), then set
15551 * the ADV_DVC_CFG 'termination' field to automatic also.
15552 *
15553 * If the termination is specified with a non-zero 'termination'
15554 * value check that a legal value is set and set the ADV_DVC_CFG
15555 * 'termination' field appropriately.
15556 */
15557 if (eep_config.termination == 0) {
15558 asc_dvc->cfg->termination = 0; /* auto termination */
15559 } else {
15560 /* Enable manual control with low off / high off. */
15561 if (eep_config.termination == 1) {
15562 asc_dvc->cfg->termination = TERM_CTL_SEL;
15563
15564 /* Enable manual control with low off / high on. */
15565 } else if (eep_config.termination == 2) {
15566 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
15567
15568 /* Enable manual control with low on / high on. */
15569 } else if (eep_config.termination == 3) {
15570 asc_dvc->cfg->termination =
15571 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
15572 } else {
15573 /*
15574 * The EEPROM 'termination' field contains a bad value. Use
15575 * automatic termination instead.
15576 */
15577 asc_dvc->cfg->termination = 0;
15578 warn_code |= ASC_WARN_EEPROM_TERMINATION;
15579 }
15580 }
1da177e4 15581
27c868c2
MW
15582 return warn_code;
15583}
1da177e4 15584
27c868c2
MW
15585/*
15586 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
15587 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
15588 * all of this is done.
15589 *
15590 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15591 *
15592 * For a non-fatal error return a warning code. If there are no warnings
15593 * then 0 is returned.
15594 *
15595 * Note: Chip is stopped on entry.
15596 */
78e77d8b 15597static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
27c868c2
MW
15598{
15599 AdvPortAddr iop_base;
15600 ushort warn_code;
15601 ADVEEP_38C0800_CONFIG eep_config;
15602 int i;
15603 uchar tid, termination;
15604 ushort sdtr_speed = 0;
15605
15606 iop_base = asc_dvc->iop_base;
15607
15608 warn_code = 0;
15609
15610 /*
15611 * Read the board's EEPROM configuration.
15612 *
15613 * Set default values if a bad checksum is found.
15614 */
15615 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
15616 eep_config.check_sum) {
15617 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 15618
27c868c2
MW
15619 /*
15620 * Set EEPROM default values.
15621 */
15622 for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++) {
15623 *((uchar *)&eep_config + i) =
15624 *((uchar *)&Default_38C0800_EEPROM_Config + i);
15625 }
1da177e4 15626
27c868c2
MW
15627 /*
15628 * Assume the 6 byte board serial number that was read
15629 * from EEPROM is correct even if the EEPROM checksum
15630 * failed.
15631 */
15632 eep_config.serial_number_word3 =
15633 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 15634
27c868c2
MW
15635 eep_config.serial_number_word2 =
15636 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
1da177e4 15637
27c868c2
MW
15638 eep_config.serial_number_word1 =
15639 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 15640
27c868c2
MW
15641 AdvSet38C0800EEPConfig(iop_base, &eep_config);
15642 }
15643 /*
15644 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
15645 * EEPROM configuration that was read.
15646 *
15647 * This is the mapping of EEPROM fields to Adv Library fields.
15648 */
15649 asc_dvc->wdtr_able = eep_config.wdtr_able;
15650 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
15651 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
15652 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
15653 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
15654 asc_dvc->tagqng_able = eep_config.tagqng_able;
15655 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
15656 asc_dvc->max_host_qng = eep_config.max_host_qng;
15657 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15658 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
15659 asc_dvc->start_motor = eep_config.start_motor;
15660 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
15661 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
15662 asc_dvc->no_scam = eep_config.scam_tolerant;
15663 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
15664 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
15665 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
15666
15667 /*
15668 * For every Target ID if any of its 'sdtr_speed[1234]' bits
15669 * are set, then set an 'sdtr_able' bit for it.
15670 */
15671 asc_dvc->sdtr_able = 0;
15672 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
15673 if (tid == 0) {
15674 sdtr_speed = asc_dvc->sdtr_speed1;
15675 } else if (tid == 4) {
15676 sdtr_speed = asc_dvc->sdtr_speed2;
15677 } else if (tid == 8) {
15678 sdtr_speed = asc_dvc->sdtr_speed3;
15679 } else if (tid == 12) {
15680 sdtr_speed = asc_dvc->sdtr_speed4;
15681 }
15682 if (sdtr_speed & ADV_MAX_TID) {
15683 asc_dvc->sdtr_able |= (1 << tid);
15684 }
15685 sdtr_speed >>= 4;
15686 }
1da177e4 15687
27c868c2
MW
15688 /*
15689 * Set the host maximum queuing (max. 253, min. 16) and the per device
15690 * maximum queuing (max. 63, min. 4).
15691 */
15692 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
15693 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15694 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
15695 /* If the value is zero, assume it is uninitialized. */
15696 if (eep_config.max_host_qng == 0) {
15697 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15698 } else {
15699 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
15700 }
15701 }
1da177e4 15702
27c868c2
MW
15703 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
15704 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15705 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
15706 /* If the value is zero, assume it is uninitialized. */
15707 if (eep_config.max_dvc_qng == 0) {
15708 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15709 } else {
15710 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
15711 }
15712 }
1da177e4 15713
27c868c2
MW
15714 /*
15715 * If 'max_dvc_qng' is greater than 'max_host_qng', then
15716 * set 'max_dvc_qng' to 'max_host_qng'.
15717 */
15718 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
15719 eep_config.max_dvc_qng = eep_config.max_host_qng;
15720 }
1da177e4 15721
27c868c2
MW
15722 /*
15723 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
15724 * values based on possibly adjusted EEPROM values.
15725 */
15726 asc_dvc->max_host_qng = eep_config.max_host_qng;
15727 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15728
15729 /*
15730 * If the EEPROM 'termination' field is set to automatic (0), then set
15731 * the ADV_DVC_CFG 'termination' field to automatic also.
15732 *
15733 * If the termination is specified with a non-zero 'termination'
15734 * value check that a legal value is set and set the ADV_DVC_CFG
15735 * 'termination' field appropriately.
15736 */
15737 if (eep_config.termination_se == 0) {
15738 termination = 0; /* auto termination for SE */
15739 } else {
15740 /* Enable manual control with low off / high off. */
15741 if (eep_config.termination_se == 1) {
15742 termination = 0;
15743
15744 /* Enable manual control with low off / high on. */
15745 } else if (eep_config.termination_se == 2) {
15746 termination = TERM_SE_HI;
15747
15748 /* Enable manual control with low on / high on. */
15749 } else if (eep_config.termination_se == 3) {
15750 termination = TERM_SE;
15751 } else {
15752 /*
15753 * The EEPROM 'termination_se' field contains a bad value.
15754 * Use automatic termination instead.
15755 */
15756 termination = 0;
15757 warn_code |= ASC_WARN_EEPROM_TERMINATION;
15758 }
15759 }
1da177e4 15760
27c868c2
MW
15761 if (eep_config.termination_lvd == 0) {
15762 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
15763 } else {
15764 /* Enable manual control with low off / high off. */
15765 if (eep_config.termination_lvd == 1) {
15766 asc_dvc->cfg->termination = termination;
15767
15768 /* Enable manual control with low off / high on. */
15769 } else if (eep_config.termination_lvd == 2) {
15770 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
15771
15772 /* Enable manual control with low on / high on. */
15773 } else if (eep_config.termination_lvd == 3) {
15774 asc_dvc->cfg->termination = termination | TERM_LVD;
15775 } else {
15776 /*
15777 * The EEPROM 'termination_lvd' field contains a bad value.
15778 * Use automatic termination instead.
15779 */
15780 asc_dvc->cfg->termination = termination;
15781 warn_code |= ASC_WARN_EEPROM_TERMINATION;
15782 }
15783 }
1da177e4 15784
27c868c2 15785 return warn_code;
1da177e4
LT
15786}
15787
15788/*
27c868c2
MW
15789 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
15790 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
15791 * all of this is done.
1da177e4
LT
15792 *
15793 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
15794 *
15795 * For a non-fatal error return a warning code. If there are no warnings
15796 * then 0 is returned.
15797 *
27c868c2 15798 * Note: Chip is stopped on entry.
1da177e4 15799 */
78e77d8b 15800static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
1da177e4 15801{
27c868c2
MW
15802 AdvPortAddr iop_base;
15803 ushort warn_code;
15804 ADVEEP_38C1600_CONFIG eep_config;
15805 int i;
15806 uchar tid, termination;
15807 ushort sdtr_speed = 0;
15808
15809 iop_base = asc_dvc->iop_base;
15810
15811 warn_code = 0;
15812
15813 /*
15814 * Read the board's EEPROM configuration.
15815 *
15816 * Set default values if a bad checksum is found.
15817 */
15818 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
15819 eep_config.check_sum) {
15820 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 15821
27c868c2
MW
15822 /*
15823 * Set EEPROM default values.
15824 */
15825 for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++) {
15826 if (i == 1
15827 && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) !=
15828 0) {
15829 /*
15830 * Set Function 1 EEPROM Word 0 MSB
15831 *
15832 * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11)
15833 * EEPROM bits.
15834 *
15835 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and
15836 * old Mac system booting problem. The Expansion ROM must
15837 * be disabled in Function 1 for these systems.
15838 *
15839 */
15840 *((uchar *)&eep_config + i) =
15841 ((*
15842 ((uchar *)&Default_38C1600_EEPROM_Config
15843 +
15844 i)) &
15845 (~
15846 (((ADV_EEPROM_BIOS_ENABLE |
15847 ADV_EEPROM_INTAB) >> 8) & 0xFF)));
15848
15849 /*
15850 * Set the INTAB (bit 11) if the GPIO 0 input indicates
15851 * the Function 1 interrupt line is wired to INTA.
15852 *
15853 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
15854 * 1 - Function 1 interrupt line wired to INT A.
15855 * 0 - Function 1 interrupt line wired to INT B.
15856 *
15857 * Note: Adapter boards always have Function 0 wired to INTA.
15858 * Put all 5 GPIO bits in input mode and then read
15859 * their input values.
15860 */
15861 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL,
15862 0);
15863 if (AdvReadByteRegister
15864 (iop_base, IOPB_GPIO_DATA) & 0x01) {
15865 /* Function 1 interrupt wired to INTA; Set EEPROM bit. */
15866 *((uchar *)&eep_config + i) |=
15867 ((ADV_EEPROM_INTAB >> 8) & 0xFF);
15868 }
15869 } else {
15870 *((uchar *)&eep_config + i) =
15871 *((uchar *)&Default_38C1600_EEPROM_Config
15872 + i);
15873 }
15874 }
1da177e4 15875
27c868c2
MW
15876 /*
15877 * Assume the 6 byte board serial number that was read
15878 * from EEPROM is correct even if the EEPROM checksum
15879 * failed.
15880 */
15881 eep_config.serial_number_word3 =
15882 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 15883
27c868c2
MW
15884 eep_config.serial_number_word2 =
15885 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
1da177e4 15886
27c868c2
MW
15887 eep_config.serial_number_word1 =
15888 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 15889
27c868c2
MW
15890 AdvSet38C1600EEPConfig(iop_base, &eep_config);
15891 }
1da177e4 15892
27c868c2
MW
15893 /*
15894 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
15895 * EEPROM configuration that was read.
15896 *
15897 * This is the mapping of EEPROM fields to Adv Library fields.
15898 */
15899 asc_dvc->wdtr_able = eep_config.wdtr_able;
15900 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
15901 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
15902 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
15903 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
15904 asc_dvc->ppr_able = 0;
15905 asc_dvc->tagqng_able = eep_config.tagqng_able;
15906 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
15907 asc_dvc->max_host_qng = eep_config.max_host_qng;
15908 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15909 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
15910 asc_dvc->start_motor = eep_config.start_motor;
15911 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
15912 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
15913 asc_dvc->no_scam = eep_config.scam_tolerant;
15914
15915 /*
15916 * For every Target ID if any of its 'sdtr_speed[1234]' bits
15917 * are set, then set an 'sdtr_able' bit for it.
15918 */
15919 asc_dvc->sdtr_able = 0;
15920 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15921 if (tid == 0) {
15922 sdtr_speed = asc_dvc->sdtr_speed1;
15923 } else if (tid == 4) {
15924 sdtr_speed = asc_dvc->sdtr_speed2;
15925 } else if (tid == 8) {
15926 sdtr_speed = asc_dvc->sdtr_speed3;
15927 } else if (tid == 12) {
15928 sdtr_speed = asc_dvc->sdtr_speed4;
15929 }
15930 if (sdtr_speed & ASC_MAX_TID) {
15931 asc_dvc->sdtr_able |= (1 << tid);
15932 }
15933 sdtr_speed >>= 4;
15934 }
1da177e4 15935
27c868c2
MW
15936 /*
15937 * Set the host maximum queuing (max. 253, min. 16) and the per device
15938 * maximum queuing (max. 63, min. 4).
15939 */
15940 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
15941 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15942 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
15943 /* If the value is zero, assume it is uninitialized. */
15944 if (eep_config.max_host_qng == 0) {
15945 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15946 } else {
15947 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
15948 }
15949 }
1da177e4 15950
27c868c2
MW
15951 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
15952 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15953 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
15954 /* If the value is zero, assume it is uninitialized. */
15955 if (eep_config.max_dvc_qng == 0) {
15956 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15957 } else {
15958 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
15959 }
15960 }
1da177e4 15961
27c868c2
MW
15962 /*
15963 * If 'max_dvc_qng' is greater than 'max_host_qng', then
15964 * set 'max_dvc_qng' to 'max_host_qng'.
15965 */
15966 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
15967 eep_config.max_dvc_qng = eep_config.max_host_qng;
15968 }
1da177e4 15969
27c868c2
MW
15970 /*
15971 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
15972 * values based on possibly adjusted EEPROM values.
15973 */
15974 asc_dvc->max_host_qng = eep_config.max_host_qng;
15975 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15976
15977 /*
15978 * If the EEPROM 'termination' field is set to automatic (0), then set
15979 * the ASC_DVC_CFG 'termination' field to automatic also.
15980 *
15981 * If the termination is specified with a non-zero 'termination'
15982 * value check that a legal value is set and set the ASC_DVC_CFG
15983 * 'termination' field appropriately.
15984 */
15985 if (eep_config.termination_se == 0) {
15986 termination = 0; /* auto termination for SE */
15987 } else {
15988 /* Enable manual control with low off / high off. */
15989 if (eep_config.termination_se == 1) {
15990 termination = 0;
15991
15992 /* Enable manual control with low off / high on. */
15993 } else if (eep_config.termination_se == 2) {
15994 termination = TERM_SE_HI;
15995
15996 /* Enable manual control with low on / high on. */
15997 } else if (eep_config.termination_se == 3) {
15998 termination = TERM_SE;
15999 } else {
16000 /*
16001 * The EEPROM 'termination_se' field contains a bad value.
16002 * Use automatic termination instead.
16003 */
16004 termination = 0;
16005 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16006 }
16007 }
1da177e4 16008
27c868c2
MW
16009 if (eep_config.termination_lvd == 0) {
16010 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
16011 } else {
16012 /* Enable manual control with low off / high off. */
16013 if (eep_config.termination_lvd == 1) {
16014 asc_dvc->cfg->termination = termination;
16015
16016 /* Enable manual control with low off / high on. */
16017 } else if (eep_config.termination_lvd == 2) {
16018 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16019
16020 /* Enable manual control with low on / high on. */
16021 } else if (eep_config.termination_lvd == 3) {
16022 asc_dvc->cfg->termination = termination | TERM_LVD;
16023 } else {
16024 /*
16025 * The EEPROM 'termination_lvd' field contains a bad value.
16026 * Use automatic termination instead.
16027 */
16028 asc_dvc->cfg->termination = termination;
16029 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16030 }
16031 }
1da177e4 16032
27c868c2 16033 return warn_code;
1da177e4
LT
16034}
16035
16036/*
16037 * Read EEPROM configuration into the specified buffer.
16038 *
16039 * Return a checksum based on the EEPROM configuration read.
16040 */
78e77d8b 16041static ushort __devinit
1da177e4
LT
16042AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16043{
27c868c2
MW
16044 ushort wval, chksum;
16045 ushort *wbuf;
16046 int eep_addr;
16047 ushort *charfields;
16048
16049 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16050 wbuf = (ushort *)cfg_buf;
16051 chksum = 0;
16052
16053 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16054 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16055 wval = AdvReadEEPWord(iop_base, eep_addr);
16056 chksum += wval; /* Checksum is calculated from word values. */
16057 if (*charfields++) {
16058 *wbuf = le16_to_cpu(wval);
16059 } else {
16060 *wbuf = wval;
16061 }
16062 }
16063 /* Read checksum word. */
16064 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16065 wbuf++;
16066 charfields++;
16067
16068 /* Read rest of EEPROM not covered by the checksum. */
16069 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16070 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16071 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16072 if (*charfields++) {
16073 *wbuf = le16_to_cpu(*wbuf);
16074 }
16075 }
16076 return chksum;
1da177e4
LT
16077}
16078
16079/*
16080 * Read EEPROM configuration into the specified buffer.
16081 *
16082 * Return a checksum based on the EEPROM configuration read.
16083 */
78e77d8b 16084static ushort __devinit
27c868c2 16085AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
1da177e4 16086{
27c868c2
MW
16087 ushort wval, chksum;
16088 ushort *wbuf;
16089 int eep_addr;
16090 ushort *charfields;
16091
16092 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16093 wbuf = (ushort *)cfg_buf;
16094 chksum = 0;
16095
16096 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16097 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16098 wval = AdvReadEEPWord(iop_base, eep_addr);
16099 chksum += wval; /* Checksum is calculated from word values. */
16100 if (*charfields++) {
16101 *wbuf = le16_to_cpu(wval);
16102 } else {
16103 *wbuf = wval;
16104 }
16105 }
16106 /* Read checksum word. */
16107 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16108 wbuf++;
16109 charfields++;
16110
16111 /* Read rest of EEPROM not covered by the checksum. */
16112 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16113 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16114 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16115 if (*charfields++) {
16116 *wbuf = le16_to_cpu(*wbuf);
16117 }
16118 }
16119 return chksum;
1da177e4
LT
16120}
16121
16122/*
16123 * Read EEPROM configuration into the specified buffer.
16124 *
16125 * Return a checksum based on the EEPROM configuration read.
16126 */
78e77d8b 16127static ushort __devinit
27c868c2 16128AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
1da177e4 16129{
27c868c2
MW
16130 ushort wval, chksum;
16131 ushort *wbuf;
16132 int eep_addr;
16133 ushort *charfields;
16134
16135 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16136 wbuf = (ushort *)cfg_buf;
16137 chksum = 0;
16138
16139 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16140 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16141 wval = AdvReadEEPWord(iop_base, eep_addr);
16142 chksum += wval; /* Checksum is calculated from word values. */
16143 if (*charfields++) {
16144 *wbuf = le16_to_cpu(wval);
16145 } else {
16146 *wbuf = wval;
16147 }
16148 }
16149 /* Read checksum word. */
16150 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16151 wbuf++;
16152 charfields++;
16153
16154 /* Read rest of EEPROM not covered by the checksum. */
16155 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16156 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16157 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16158 if (*charfields++) {
16159 *wbuf = le16_to_cpu(*wbuf);
16160 }
16161 }
16162 return chksum;
1da177e4
LT
16163}
16164
16165/*
16166 * Read the EEPROM from specified location
16167 */
78e77d8b 16168static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
1da177e4 16169{
27c868c2
MW
16170 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16171 ASC_EEP_CMD_READ | eep_word_addr);
16172 AdvWaitEEPCmd(iop_base);
16173 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
1da177e4
LT
16174}
16175
16176/*
16177 * Wait for EEPROM command to complete
16178 */
78e77d8b 16179static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
1da177e4 16180{
27c868c2
MW
16181 int eep_delay_ms;
16182
16183 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
16184 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
16185 ASC_EEP_CMD_DONE) {
16186 break;
16187 }
16188 DvcSleepMilliSecond(1);
16189 }
16190 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
16191 0) {
16192 ASC_ASSERT(0);
16193 }
16194 return;
1da177e4
LT
16195}
16196
16197/*
16198 * Write the EEPROM from 'cfg_buf'.
16199 */
78e77d8b 16200void __devinit
1da177e4
LT
16201AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16202{
27c868c2
MW
16203 ushort *wbuf;
16204 ushort addr, chksum;
16205 ushort *charfields;
16206
16207 wbuf = (ushort *)cfg_buf;
16208 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16209 chksum = 0;
16210
16211 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16212 AdvWaitEEPCmd(iop_base);
16213
16214 /*
16215 * Write EEPROM from word 0 to word 20.
16216 */
16217 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16218 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16219 ushort word;
16220
16221 if (*charfields++) {
16222 word = cpu_to_le16(*wbuf);
16223 } else {
16224 word = *wbuf;
16225 }
16226 chksum += *wbuf; /* Checksum is calculated from word values. */
16227 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16228 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16229 ASC_EEP_CMD_WRITE | addr);
16230 AdvWaitEEPCmd(iop_base);
16231 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16232 }
1da177e4 16233
27c868c2
MW
16234 /*
16235 * Write EEPROM checksum at word 21.
16236 */
16237 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16238 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16239 AdvWaitEEPCmd(iop_base);
16240 wbuf++;
16241 charfields++;
16242
16243 /*
16244 * Write EEPROM OEM name at words 22 to 29.
16245 */
16246 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16247 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16248 ushort word;
16249
16250 if (*charfields++) {
16251 word = cpu_to_le16(*wbuf);
16252 } else {
16253 word = *wbuf;
16254 }
16255 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16256 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16257 ASC_EEP_CMD_WRITE | addr);
16258 AdvWaitEEPCmd(iop_base);
16259 }
16260 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16261 AdvWaitEEPCmd(iop_base);
16262 return;
1da177e4
LT
16263}
16264
16265/*
16266 * Write the EEPROM from 'cfg_buf'.
16267 */
78e77d8b 16268void __devinit
27c868c2 16269AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
1da177e4 16270{
27c868c2
MW
16271 ushort *wbuf;
16272 ushort *charfields;
16273 ushort addr, chksum;
16274
16275 wbuf = (ushort *)cfg_buf;
16276 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16277 chksum = 0;
16278
16279 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16280 AdvWaitEEPCmd(iop_base);
16281
16282 /*
16283 * Write EEPROM from word 0 to word 20.
16284 */
16285 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16286 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16287 ushort word;
16288
16289 if (*charfields++) {
16290 word = cpu_to_le16(*wbuf);
16291 } else {
16292 word = *wbuf;
16293 }
16294 chksum += *wbuf; /* Checksum is calculated from word values. */
16295 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16296 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16297 ASC_EEP_CMD_WRITE | addr);
16298 AdvWaitEEPCmd(iop_base);
16299 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16300 }
1da177e4 16301
27c868c2
MW
16302 /*
16303 * Write EEPROM checksum at word 21.
16304 */
16305 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16306 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16307 AdvWaitEEPCmd(iop_base);
16308 wbuf++;
16309 charfields++;
16310
16311 /*
16312 * Write EEPROM OEM name at words 22 to 29.
16313 */
16314 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16315 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16316 ushort word;
16317
16318 if (*charfields++) {
16319 word = cpu_to_le16(*wbuf);
16320 } else {
16321 word = *wbuf;
16322 }
16323 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16324 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16325 ASC_EEP_CMD_WRITE | addr);
16326 AdvWaitEEPCmd(iop_base);
16327 }
16328 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16329 AdvWaitEEPCmd(iop_base);
16330 return;
1da177e4
LT
16331}
16332
16333/*
16334 * Write the EEPROM from 'cfg_buf'.
16335 */
78e77d8b 16336void __devinit
27c868c2 16337AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
1da177e4 16338{
27c868c2
MW
16339 ushort *wbuf;
16340 ushort *charfields;
16341 ushort addr, chksum;
16342
16343 wbuf = (ushort *)cfg_buf;
16344 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16345 chksum = 0;
16346
16347 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16348 AdvWaitEEPCmd(iop_base);
16349
16350 /*
16351 * Write EEPROM from word 0 to word 20.
16352 */
16353 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16354 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16355 ushort word;
16356
16357 if (*charfields++) {
16358 word = cpu_to_le16(*wbuf);
16359 } else {
16360 word = *wbuf;
16361 }
16362 chksum += *wbuf; /* Checksum is calculated from word values. */
16363 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16364 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16365 ASC_EEP_CMD_WRITE | addr);
16366 AdvWaitEEPCmd(iop_base);
16367 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16368 }
1da177e4 16369
27c868c2
MW
16370 /*
16371 * Write EEPROM checksum at word 21.
16372 */
16373 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16374 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16375 AdvWaitEEPCmd(iop_base);
16376 wbuf++;
16377 charfields++;
16378
16379 /*
16380 * Write EEPROM OEM name at words 22 to 29.
16381 */
16382 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16383 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16384 ushort word;
16385
16386 if (*charfields++) {
16387 word = cpu_to_le16(*wbuf);
16388 } else {
16389 word = *wbuf;
16390 }
16391 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16392 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16393 ASC_EEP_CMD_WRITE | addr);
16394 AdvWaitEEPCmd(iop_base);
16395 }
16396 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16397 AdvWaitEEPCmd(iop_base);
16398 return;
1da177e4
LT
16399}
16400
16401/* a_advlib.c */
16402/*
16403 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
16404 *
16405 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
16406 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
16407 * RISC to notify it a new command is ready to be executed.
16408 *
16409 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
16410 * set to SCSI_MAX_RETRY.
16411 *
16412 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
16413 * for DMA addresses or math operations are byte swapped to little-endian
16414 * order.
16415 *
16416 * Return:
16417 * ADV_SUCCESS(1) - The request was successfully queued.
16418 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
16419 * request completes.
16420 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
16421 * host IC error.
16422 */
27c868c2 16423static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
1da177e4 16424{
27c868c2
MW
16425 ulong last_int_level;
16426 AdvPortAddr iop_base;
16427 ADV_DCNT req_size;
16428 ADV_PADDR req_paddr;
16429 ADV_CARR_T *new_carrp;
16430
16431 ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
16432
16433 /*
16434 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
16435 */
16436 if (scsiq->target_id > ADV_MAX_TID) {
16437 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
16438 scsiq->done_status = QD_WITH_ERROR;
16439 return ADV_ERROR;
16440 }
1da177e4 16441
27c868c2 16442 iop_base = asc_dvc->iop_base;
1da177e4 16443
27c868c2 16444 last_int_level = DvcEnterCritical();
1da177e4 16445
27c868c2
MW
16446 /*
16447 * Allocate a carrier ensuring at least one carrier always
16448 * remains on the freelist and initialize fields.
16449 */
16450 if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
16451 DvcLeaveCritical(last_int_level);
16452 return ADV_BUSY;
16453 }
16454 asc_dvc->carr_freelist = (ADV_CARR_T *)
16455 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
16456 asc_dvc->carr_pending_cnt++;
16457
16458 /*
16459 * Set the carrier to be a stopper by setting 'next_vpa'
16460 * to the stopper value. The current stopper will be changed
16461 * below to point to the new stopper.
16462 */
16463 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16464
16465 /*
16466 * Clear the ADV_SCSI_REQ_Q done flag.
16467 */
16468 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
16469
16470 req_size = sizeof(ADV_SCSI_REQ_Q);
16471 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
16472 (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
16473
16474 ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
16475 ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
16476
16477 /* Wait for assertion before making little-endian */
16478 req_paddr = cpu_to_le32(req_paddr);
16479
16480 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
16481 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
16482 scsiq->scsiq_rptr = req_paddr;
16483
16484 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
16485 /*
16486 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
16487 * order during initialization.
16488 */
16489 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
16490
16491 /*
16492 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
16493 * the microcode. The newly allocated stopper will become the new
16494 * stopper.
16495 */
16496 asc_dvc->icq_sp->areq_vpa = req_paddr;
16497
16498 /*
16499 * Set the 'next_vpa' pointer for the old stopper to be the
16500 * physical address of the new stopper. The RISC can only
16501 * follow physical addresses.
16502 */
16503 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
16504
16505 /*
16506 * Set the host adapter stopper pointer to point to the new carrier.
16507 */
16508 asc_dvc->icq_sp = new_carrp;
16509
16510 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
16511 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
16512 /*
16513 * Tickle the RISC to tell it to read its Command Queue Head pointer.
16514 */
16515 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
16516 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
16517 /*
16518 * Clear the tickle value. In the ASC-3550 the RISC flag
16519 * command 'clr_tickle_a' does not work unless the host
16520 * value is cleared.
16521 */
16522 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
16523 ADV_TICKLE_NOP);
16524 }
16525 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16526 /*
16527 * Notify the RISC a carrier is ready by writing the physical
16528 * address of the new carrier stopper to the COMMA register.
16529 */
16530 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
16531 le32_to_cpu(new_carrp->carr_pa));
16532 }
1da177e4 16533
27c868c2 16534 DvcLeaveCritical(last_int_level);
1da177e4 16535
27c868c2 16536 return ADV_SUCCESS;
1da177e4
LT
16537}
16538
16539/*
16540 * Reset SCSI Bus and purge all outstanding requests.
16541 *
16542 * Return Value:
16543 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
16544 * ADV_FALSE(0) - Microcode command failed.
16545 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
16546 * may be hung which requires driver recovery.
16547 */
27c868c2 16548static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
1da177e4 16549{
27c868c2
MW
16550 int status;
16551
16552 /*
16553 * Send the SCSI Bus Reset idle start idle command which asserts
16554 * the SCSI Bus Reset signal.
16555 */
16556 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
16557 if (status != ADV_TRUE) {
16558 return status;
16559 }
1da177e4 16560
27c868c2
MW
16561 /*
16562 * Delay for the specified SCSI Bus Reset hold time.
16563 *
16564 * The hold time delay is done on the host because the RISC has no
16565 * microsecond accurate timer.
16566 */
16567 DvcDelayMicroSecond(asc_dvc, (ushort)ASC_SCSI_RESET_HOLD_TIME_US);
16568
16569 /*
16570 * Send the SCSI Bus Reset end idle command which de-asserts
16571 * the SCSI Bus Reset signal and purges any pending requests.
16572 */
16573 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
16574 if (status != ADV_TRUE) {
16575 return status;
16576 }
16577
16578 DvcSleepMilliSecond((ADV_DCNT)asc_dvc->scsi_reset_wait * 1000);
1da177e4 16579
27c868c2 16580 return status;
1da177e4
LT
16581}
16582
16583/*
16584 * Reset chip and SCSI Bus.
16585 *
16586 * Return Value:
16587 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
16588 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
16589 */
27c868c2 16590static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
1da177e4 16591{
27c868c2
MW
16592 int status;
16593 ushort wdtr_able, sdtr_able, tagqng_able;
16594 ushort ppr_able = 0;
16595 uchar tid, max_cmd[ADV_MAX_TID + 1];
16596 AdvPortAddr iop_base;
16597 ushort bios_sig;
16598
16599 iop_base = asc_dvc->iop_base;
16600
16601 /*
16602 * Save current per TID negotiated values.
16603 */
16604 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16605 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16606 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16607 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16608 }
16609 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16610 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
16611 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16612 max_cmd[tid]);
16613 }
1da177e4 16614
27c868c2
MW
16615 /*
16616 * Force the AdvInitAsc3550/38C0800Driver() function to
16617 * perform a SCSI Bus Reset by clearing the BIOS signature word.
16618 * The initialization functions assumes a SCSI Bus Reset is not
16619 * needed if the BIOS signature word is present.
16620 */
16621 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
16622 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
16623
16624 /*
16625 * Stop chip and reset it.
16626 */
16627 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
16628 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
16629 DvcSleepMilliSecond(100);
16630 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
16631 ADV_CTRL_REG_CMD_WR_IO_REG);
16632
16633 /*
16634 * Reset Adv Library error code, if any, and try
16635 * re-initializing the chip.
16636 */
16637 asc_dvc->err_code = 0;
16638 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16639 status = AdvInitAsc38C1600Driver(asc_dvc);
16640 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
16641 status = AdvInitAsc38C0800Driver(asc_dvc);
16642 } else {
16643 status = AdvInitAsc3550Driver(asc_dvc);
16644 }
1da177e4 16645
27c868c2
MW
16646 /* Translate initialization return value to status value. */
16647 if (status == 0) {
16648 status = ADV_TRUE;
16649 } else {
16650 status = ADV_FALSE;
16651 }
1da177e4 16652
27c868c2
MW
16653 /*
16654 * Restore the BIOS signature word.
16655 */
16656 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
16657
16658 /*
16659 * Restore per TID negotiated values.
16660 */
16661 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16662 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16663 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16664 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16665 }
16666 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16667 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
16668 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16669 max_cmd[tid]);
16670 }
1da177e4 16671
27c868c2 16672 return status;
1da177e4
LT
16673}
16674
16675/*
16676 * Adv Library Interrupt Service Routine
16677 *
16678 * This function is called by a driver's interrupt service routine.
16679 * The function disables and re-enables interrupts.
16680 *
16681 * When a microcode idle command is completed, the ADV_DVC_VAR
16682 * 'idle_cmd_done' field is set to ADV_TRUE.
16683 *
16684 * Note: AdvISR() can be called when interrupts are disabled or even
16685 * when there is no hardware interrupt condition present. It will
16686 * always check for completed idle commands and microcode requests.
16687 * This is an important feature that shouldn't be changed because it
16688 * allows commands to be completed from polling mode loops.
16689 *
16690 * Return:
16691 * ADV_TRUE(1) - interrupt was pending
16692 * ADV_FALSE(0) - no interrupt was pending
16693 */
27c868c2 16694static int AdvISR(ADV_DVC_VAR *asc_dvc)
1da177e4 16695{
27c868c2
MW
16696 AdvPortAddr iop_base;
16697 uchar int_stat;
16698 ushort target_bit;
16699 ADV_CARR_T *free_carrp;
16700 ADV_VADDR irq_next_vpa;
16701 int flags;
16702 ADV_SCSI_REQ_Q *scsiq;
1da177e4 16703
27c868c2 16704 flags = DvcEnterCritical();
1da177e4 16705
27c868c2
MW
16706 iop_base = asc_dvc->iop_base;
16707
16708 /* Reading the register clears the interrupt. */
16709 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
16710
16711 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
16712 ADV_INTR_STATUS_INTRC)) == 0) {
16713 DvcLeaveCritical(flags);
16714 return ADV_FALSE;
16715 }
16716
16717 /*
16718 * Notify the driver of an asynchronous microcode condition by
895d6b4c 16719 * calling the adv_async_callback function. The function
27c868c2
MW
16720 * is passed the microcode ASC_MC_INTRB_CODE byte value.
16721 */
16722 if (int_stat & ADV_INTR_STATUS_INTRB) {
16723 uchar intrb_code;
16724
16725 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
16726
16727 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
16728 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
16729 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
16730 asc_dvc->carr_pending_cnt != 0) {
16731 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
16732 ADV_TICKLE_A);
16733 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
16734 AdvWriteByteRegister(iop_base,
16735 IOPB_TICKLE,
16736 ADV_TICKLE_NOP);
16737 }
16738 }
16739 }
16740
895d6b4c 16741 adv_async_callback(asc_dvc, intrb_code);
27c868c2
MW
16742 }
16743
16744 /*
16745 * Check if the IRQ stopper carrier contains a completed request.
16746 */
16747 while (((irq_next_vpa =
16748 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
16749 /*
16750 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
16751 * The RISC will have set 'areq_vpa' to a virtual address.
16752 *
16753 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
16754 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
16755 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
16756 * in AdvExeScsiQueue().
16757 */
16758 scsiq = (ADV_SCSI_REQ_Q *)
16759 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
16760
16761 /*
16762 * Request finished with good status and the queue was not
16763 * DMAed to host memory by the firmware. Set all status fields
16764 * to indicate good status.
16765 */
16766 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
16767 scsiq->done_status = QD_NO_ERROR;
16768 scsiq->host_status = scsiq->scsi_status = 0;
16769 scsiq->data_cnt = 0L;
16770 }
16771
16772 /*
16773 * Advance the stopper pointer to the next carrier
16774 * ignoring the lower four bits. Free the previous
16775 * stopper carrier.
16776 */
16777 free_carrp = asc_dvc->irq_sp;
16778 asc_dvc->irq_sp = (ADV_CARR_T *)
16779 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
16780
16781 free_carrp->next_vpa =
16782 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
16783 asc_dvc->carr_freelist = free_carrp;
16784 asc_dvc->carr_pending_cnt--;
16785
16786 ASC_ASSERT(scsiq != NULL);
16787 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
16788
16789 /*
16790 * Clear request microcode control flag.
16791 */
16792 scsiq->cntl = 0;
16793
27c868c2
MW
16794 /*
16795 * Notify the driver of the completed request by passing
16796 * the ADV_SCSI_REQ_Q pointer to its callback function.
16797 */
16798 scsiq->a_flag |= ADV_SCSIQ_DONE;
895d6b4c 16799 adv_isr_callback(asc_dvc, scsiq);
27c868c2
MW
16800 /*
16801 * Note: After the driver callback function is called, 'scsiq'
16802 * can no longer be referenced.
16803 *
16804 * Fall through and continue processing other completed
16805 * requests...
16806 */
16807
16808 /*
16809 * Disable interrupts again in case the driver inadvertently
16810 * enabled interrupts in its callback function.
16811 *
16812 * The DvcEnterCritical() return value is ignored, because
16813 * the 'flags' saved when AdvISR() was first entered will be
16814 * used to restore the interrupt flag on exit.
16815 */
16816 (void)DvcEnterCritical();
16817 }
16818 DvcLeaveCritical(flags);
16819 return ADV_TRUE;
1da177e4
LT
16820}
16821
16822/*
16823 * Send an idle command to the chip and wait for completion.
16824 *
16825 * Command completion is polled for once per microsecond.
16826 *
16827 * The function can be called from anywhere including an interrupt handler.
16828 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
16829 * functions to prevent reentrancy.
16830 *
16831 * Return Values:
16832 * ADV_TRUE - command completed successfully
16833 * ADV_FALSE - command failed
16834 * ADV_ERROR - command timed out
16835 */
27c868c2 16836static int
1da177e4 16837AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
27c868c2 16838 ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
1da177e4 16839{
27c868c2
MW
16840 ulong last_int_level;
16841 int result;
16842 ADV_DCNT i, j;
16843 AdvPortAddr iop_base;
16844
16845 last_int_level = DvcEnterCritical();
16846
16847 iop_base = asc_dvc->iop_base;
16848
16849 /*
16850 * Clear the idle command status which is set by the microcode
16851 * to a non-zero value to indicate when the command is completed.
16852 * The non-zero result is one of the IDLE_CMD_STATUS_* values
16853 * defined in a_advlib.h.
16854 */
16855 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
16856
16857 /*
16858 * Write the idle command value after the idle command parameter
16859 * has been written to avoid a race condition. If the order is not
16860 * followed, the microcode may process the idle command before the
16861 * parameters have been written to LRAM.
16862 */
16863 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
16864 cpu_to_le32(idle_cmd_parameter));
16865 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
16866
16867 /*
16868 * Tickle the RISC to tell it to process the idle command.
16869 */
16870 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
16871 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
16872 /*
16873 * Clear the tickle value. In the ASC-3550 the RISC flag
16874 * command 'clr_tickle_b' does not work unless the host
16875 * value is cleared.
16876 */
16877 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
16878 }
1da177e4 16879
27c868c2
MW
16880 /* Wait for up to 100 millisecond for the idle command to timeout. */
16881 for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
16882 /* Poll once each microsecond for command completion. */
16883 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
16884 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
16885 result);
16886 if (result != 0) {
16887 DvcLeaveCritical(last_int_level);
16888 return result;
16889 }
16890 DvcDelayMicroSecond(asc_dvc, (ushort)1);
16891 }
16892 }
1da177e4 16893
27c868c2
MW
16894 ASC_ASSERT(0); /* The idle command should never timeout. */
16895 DvcLeaveCritical(last_int_level);
16896 return ADV_ERROR;
1da177e4
LT
16897}
16898
b2c16f58
MW
16899static int __devinit
16900advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
16901{
16902 int req_cnt = 0;
16903 adv_req_t *reqp = NULL;
16904 int sg_cnt = 0;
16905 adv_sgblk_t *sgp;
16906 int warn_code, err_code;
16907
16908 /*
16909 * Allocate buffer carrier structures. The total size
16910 * is about 4 KB, so allocate all at once.
16911 */
16912 boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
16913 ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp);
16914
16915 if (!boardp->carrp)
16916 goto kmalloc_failed;
16917
16918 /*
16919 * Allocate up to 'max_host_qng' request structures for the Wide
16920 * board. The total size is about 16 KB, so allocate all at once.
16921 * If the allocation fails decrement and try again.
16922 */
16923 for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
16924 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
16925
16926 ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, "
16927 "bytes %lu\n", reqp, req_cnt,
16928 (ulong)sizeof(adv_req_t) * req_cnt);
16929
16930 if (reqp)
16931 break;
16932 }
16933
16934 if (!reqp)
16935 goto kmalloc_failed;
16936
16937 boardp->orig_reqp = reqp;
16938
16939 /*
16940 * Allocate up to ADV_TOT_SG_BLOCK request structures for
16941 * the Wide board. Each structure is about 136 bytes.
16942 */
16943 boardp->adv_sgblkp = NULL;
16944 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
16945 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
16946
16947 if (!sgp)
16948 break;
16949
16950 sgp->next_sgblkp = boardp->adv_sgblkp;
16951 boardp->adv_sgblkp = sgp;
16952
16953 }
16954
16955 ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n",
16956 sg_cnt, sizeof(adv_sgblk_t),
16957 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
16958
16959 if (!boardp->adv_sgblkp)
16960 goto kmalloc_failed;
16961
16962 adv_dvc_varp->carrier_buf = boardp->carrp;
16963
16964 /*
16965 * Point 'adv_reqp' to the request structures and
16966 * link them together.
16967 */
16968 req_cnt--;
16969 reqp[req_cnt].next_reqp = NULL;
16970 for (; req_cnt > 0; req_cnt--) {
16971 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
16972 }
16973 boardp->adv_reqp = &reqp[0];
16974
16975 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
16976 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n");
16977 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
16978 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
16979 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()"
16980 "\n");
16981 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
16982 } else {
16983 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()"
16984 "\n");
16985 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
16986 }
16987 err_code = adv_dvc_varp->err_code;
16988
16989 if (warn_code || err_code) {
16990 ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
16991 " error 0x%x\n", boardp->id, warn_code, err_code);
16992 }
16993
16994 goto exit;
16995
16996 kmalloc_failed:
16997 ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
16998 "failed\n", boardp->id);
16999 err_code = ADV_ERROR;
17000 exit:
17001 return err_code;
17002}
17003
17004static void advansys_wide_free_mem(asc_board_t *boardp)
17005{
17006 kfree(boardp->carrp);
17007 boardp->carrp = NULL;
17008 kfree(boardp->orig_reqp);
17009 boardp->orig_reqp = boardp->adv_reqp = NULL;
17010 while (boardp->adv_sgblkp) {
17011 adv_sgblk_t *sgp = boardp->adv_sgblkp;
17012 boardp->adv_sgblkp = sgp->next_sgblkp;
17013 kfree(sgp);
17014 }
17015}
17016
27c868c2
MW
17017static struct Scsi_Host *__devinit
17018advansys_board_found(int iop, struct device *dev, int bus_type)
17019{
17020 struct Scsi_Host *shost;
17021 struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL;
17022 asc_board_t *boardp;
17023 ASC_DVC_VAR *asc_dvc_varp = NULL;
17024 ADV_DVC_VAR *adv_dvc_varp = NULL;
074c8fe4 17025 int share_irq;
27c868c2
MW
17026 int warn_code, err_code;
17027 int ret;
17028
17029 /*
27c868c2
MW
17030 * Register the adapter, get its configuration, and
17031 * initialize it.
17032 */
8dfb5379
MW
17033 ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n");
17034 shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t));
27c868c2
MW
17035 if (!shost)
17036 return NULL;
17037
27c868c2
MW
17038 /* Initialize private per board data */
17039 boardp = ASC_BOARDP(shost);
17040 memset(boardp, 0, sizeof(asc_board_t));
78e77d8b 17041 boardp->id = asc_board_count++;
27c868c2 17042 spin_lock_init(&boardp->lock);
394dbf3f 17043 boardp->dev = dev;
27c868c2
MW
17044
17045 /*
17046 * Handle both narrow and wide boards.
17047 *
17048 * If a Wide board was detected, set the board structure
17049 * wide board flag. Set-up the board structure based on
17050 * the board type.
17051 */
17052#ifdef CONFIG_PCI
17053 if (bus_type == ASC_IS_PCI &&
17054 (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
17055 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
17056 pdev->device == PCI_DEVICE_ID_38C1600_REV1)) {
17057 boardp->flags |= ASC_IS_WIDE_BOARD;
17058 }
17059#endif /* CONFIG_PCI */
17060
17061 if (ASC_NARROW_BOARD(boardp)) {
17062 ASC_DBG(1, "advansys_board_found: narrow board\n");
17063 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
17064 asc_dvc_varp->bus_type = bus_type;
17065 asc_dvc_varp->drv_ptr = boardp;
17066 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
17067 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
17068 asc_dvc_varp->iop_base = iop;
27c868c2 17069 } else {
57ba5fe9 17070#ifdef CONFIG_PCI
27c868c2
MW
17071 ASC_DBG(1, "advansys_board_found: wide board\n");
17072 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
17073 adv_dvc_varp->drv_ptr = boardp;
17074 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
27c868c2
MW
17075 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
17076 ASC_DBG(1, "advansys_board_found: ASC-3550\n");
17077 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
17078 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
17079 ASC_DBG(1, "advansys_board_found: ASC-38C0800\n");
17080 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
17081 } else {
17082 ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
17083 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
17084 }
27c868c2 17085
57ba5fe9
MW
17086 boardp->asc_n_io_port = pci_resource_len(pdev, 1);
17087 boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1),
17088 boardp->asc_n_io_port);
17089 if (!boardp->ioremap_addr) {
27c868c2
MW
17090 ASC_PRINT3
17091 ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
57ba5fe9
MW
17092 boardp->id, pci_resource_start(pdev, 1),
17093 boardp->asc_n_io_port);
b2c16f58 17094 goto err_shost;
27c868c2 17095 }
57ba5fe9 17096 adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr
71f36115 17097 ASC_DBG1(1, "advansys_board_found: iop_base: 0x%lx\n",
27c868c2 17098 adv_dvc_varp->iop_base);
27c868c2
MW
17099
17100 /*
17101 * Even though it isn't used to access wide boards, other
17102 * than for the debug line below, save I/O Port address so
17103 * that it can be reported.
17104 */
17105 boardp->ioport = iop;
17106
57ba5fe9
MW
17107 ASC_DBG2(1, "advansys_board_found: iopb_chip_id_1 0x%x, "
17108 "iopw_chip_id_0 0x%x\n", (ushort)inp(iop + 1),
17109 (ushort)inpw(iop));
17110#endif /* CONFIG_PCI */
27c868c2
MW
17111 }
17112
17113#ifdef CONFIG_PROC_FS
17114 /*
17115 * Allocate buffer for printing information from
17116 * /proc/scsi/advansys/[0...].
17117 */
b2c16f58
MW
17118 boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
17119 if (!boardp->prtbuf) {
17120 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
17121 "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
17122 goto err_unmap;
27c868c2
MW
17123 }
17124#endif /* CONFIG_PROC_FS */
17125
17126 if (ASC_NARROW_BOARD(boardp)) {
27c868c2
MW
17127 /*
17128 * Set the board bus type and PCI IRQ before
17129 * calling AscInitGetConfig().
17130 */
17131 switch (asc_dvc_varp->bus_type) {
17132#ifdef CONFIG_ISA
17133 case ASC_IS_ISA:
17134 shost->unchecked_isa_dma = TRUE;
074c8fe4 17135 share_irq = 0;
27c868c2
MW
17136 break;
17137 case ASC_IS_VL:
17138 shost->unchecked_isa_dma = FALSE;
074c8fe4 17139 share_irq = 0;
27c868c2
MW
17140 break;
17141 case ASC_IS_EISA:
17142 shost->unchecked_isa_dma = FALSE;
074c8fe4 17143 share_irq = IRQF_SHARED;
27c868c2
MW
17144 break;
17145#endif /* CONFIG_ISA */
17146#ifdef CONFIG_PCI
17147 case ASC_IS_PCI:
17148 shost->irq = asc_dvc_varp->irq_no = pdev->irq;
17149 asc_dvc_varp->cfg->pci_slot_info =
17150 ASC_PCI_MKID(pdev->bus->number,
17151 PCI_SLOT(pdev->devfn),
17152 PCI_FUNC(pdev->devfn));
17153 shost->unchecked_isa_dma = FALSE;
074c8fe4 17154 share_irq = IRQF_SHARED;
27c868c2
MW
17155 break;
17156#endif /* CONFIG_PCI */
17157 default:
17158 ASC_PRINT2
17159 ("advansys_board_found: board %d: unknown adapter type: %d\n",
17160 boardp->id, asc_dvc_varp->bus_type);
17161 shost->unchecked_isa_dma = TRUE;
074c8fe4 17162 share_irq = 0;
27c868c2
MW
17163 break;
17164 }
17165 } else {
27c868c2
MW
17166 /*
17167 * For Wide boards set PCI information before calling
17168 * AdvInitGetConfig().
17169 */
17170#ifdef CONFIG_PCI
17171 shost->irq = adv_dvc_varp->irq_no = pdev->irq;
17172 adv_dvc_varp->cfg->pci_slot_info =
17173 ASC_PCI_MKID(pdev->bus->number,
17174 PCI_SLOT(pdev->devfn),
17175 PCI_FUNC(pdev->devfn));
17176 shost->unchecked_isa_dma = FALSE;
074c8fe4 17177 share_irq = IRQF_SHARED;
27c868c2
MW
17178#endif /* CONFIG_PCI */
17179 }
17180
17181 /*
17182 * Read the board configuration.
17183 */
17184 if (ASC_NARROW_BOARD(boardp)) {
17185 /*
17186 * NOTE: AscInitGetConfig() may change the board's
17187 * bus_type value. The bus_type value should no
17188 * longer be used. If the bus_type field must be
17189 * referenced only use the bit-wise AND operator "&".
17190 */
17191 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
17192 switch (ret = AscInitGetConfig(asc_dvc_varp)) {
17193 case 0: /* No error */
17194 break;
17195 case ASC_WARN_IO_PORT_ROTATE:
17196 ASC_PRINT1
17197 ("AscInitGetConfig: board %d: I/O port address modified\n",
17198 boardp->id);
17199 break;
17200 case ASC_WARN_AUTO_CONFIG:
17201 ASC_PRINT1
17202 ("AscInitGetConfig: board %d: I/O port increment switch enabled\n",
17203 boardp->id);
17204 break;
17205 case ASC_WARN_EEPROM_CHKSUM:
17206 ASC_PRINT1
17207 ("AscInitGetConfig: board %d: EEPROM checksum error\n",
17208 boardp->id);
17209 break;
17210 case ASC_WARN_IRQ_MODIFIED:
17211 ASC_PRINT1
17212 ("AscInitGetConfig: board %d: IRQ modified\n",
17213 boardp->id);
17214 break;
17215 case ASC_WARN_CMD_QNG_CONFLICT:
17216 ASC_PRINT1
17217 ("AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
17218 boardp->id);
17219 break;
17220 default:
17221 ASC_PRINT2
17222 ("AscInitGetConfig: board %d: unknown warning: 0x%x\n",
17223 boardp->id, ret);
17224 break;
17225 }
17226 if ((err_code = asc_dvc_varp->err_code) != 0) {
17227 ASC_PRINT3
17228 ("AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
17229 boardp->id,
17230 asc_dvc_varp->init_state, asc_dvc_varp->err_code);
17231 }
17232 } else {
17233 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
394dbf3f
MW
17234
17235 ret = AdvInitGetConfig(pdev, adv_dvc_varp);
17236 if (ret != 0) {
27c868c2
MW
17237 ASC_PRINT2
17238 ("AdvInitGetConfig: board %d: warning: 0x%x\n",
17239 boardp->id, ret);
17240 }
17241 if ((err_code = adv_dvc_varp->err_code) != 0) {
17242 ASC_PRINT2
17243 ("AdvInitGetConfig: board %d error: err_code 0x%x\n",
17244 boardp->id, adv_dvc_varp->err_code);
17245 }
17246 }
17247
b2c16f58
MW
17248 if (err_code != 0)
17249 goto err_free_proc;
27c868c2
MW
17250
17251 /*
17252 * Save the EEPROM configuration so that it can be displayed
17253 * from /proc/scsi/advansys/[0...].
17254 */
17255 if (ASC_NARROW_BOARD(boardp)) {
17256
17257 ASCEEP_CONFIG *ep;
17258
17259 /*
17260 * Set the adapter's target id bit in the 'init_tidmask' field.
17261 */
17262 boardp->init_tidmask |=
17263 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
17264
17265 /*
17266 * Save EEPROM settings for the board.
17267 */
17268 ep = &boardp->eep_config.asc_eep;
17269
17270 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
17271 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
17272 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
17273 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
17274 ep->start_motor = asc_dvc_varp->start_motor;
17275 ep->cntl = asc_dvc_varp->dvc_cntl;
17276 ep->no_scam = asc_dvc_varp->no_scam;
17277 ep->max_total_qng = asc_dvc_varp->max_total_qng;
17278 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
17279 /* 'max_tag_qng' is set to the same value for every device. */
17280 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
17281 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
17282 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
17283 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
17284 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
17285 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
17286 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
17287
17288 /*
17289 * Modify board configuration.
17290 */
17291 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
394dbf3f 17292 switch (ret = AscInitSetConfig(pdev, asc_dvc_varp)) {
27c868c2
MW
17293 case 0: /* No error. */
17294 break;
17295 case ASC_WARN_IO_PORT_ROTATE:
17296 ASC_PRINT1
17297 ("AscInitSetConfig: board %d: I/O port address modified\n",
17298 boardp->id);
17299 break;
17300 case ASC_WARN_AUTO_CONFIG:
17301 ASC_PRINT1
17302 ("AscInitSetConfig: board %d: I/O port increment switch enabled\n",
17303 boardp->id);
17304 break;
17305 case ASC_WARN_EEPROM_CHKSUM:
17306 ASC_PRINT1
17307 ("AscInitSetConfig: board %d: EEPROM checksum error\n",
17308 boardp->id);
17309 break;
17310 case ASC_WARN_IRQ_MODIFIED:
17311 ASC_PRINT1
17312 ("AscInitSetConfig: board %d: IRQ modified\n",
17313 boardp->id);
17314 break;
17315 case ASC_WARN_CMD_QNG_CONFLICT:
17316 ASC_PRINT1
17317 ("AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
17318 boardp->id);
17319 break;
17320 default:
17321 ASC_PRINT2
17322 ("AscInitSetConfig: board %d: unknown warning: 0x%x\n",
17323 boardp->id, ret);
17324 break;
17325 }
17326 if (asc_dvc_varp->err_code != 0) {
17327 ASC_PRINT3
17328 ("AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
17329 boardp->id,
17330 asc_dvc_varp->init_state, asc_dvc_varp->err_code);
b2c16f58 17331 goto err_free_proc;
27c868c2
MW
17332 }
17333
17334 /*
17335 * Finish initializing the 'Scsi_Host' structure.
17336 */
17337 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
17338 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
17339 shost->irq = asc_dvc_varp->irq_no;
17340 }
17341 } else {
17342 ADVEEP_3550_CONFIG *ep_3550;
17343 ADVEEP_38C0800_CONFIG *ep_38C0800;
17344 ADVEEP_38C1600_CONFIG *ep_38C1600;
17345
17346 /*
17347 * Save Wide EEP Configuration Information.
17348 */
17349 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17350 ep_3550 = &boardp->eep_config.adv_3550_eep;
17351
17352 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
17353 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
17354 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17355 ep_3550->termination = adv_dvc_varp->cfg->termination;
17356 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
17357 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
17358 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
17359 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
17360 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
17361 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
17362 ep_3550->start_motor = adv_dvc_varp->start_motor;
17363 ep_3550->scsi_reset_delay =
17364 adv_dvc_varp->scsi_reset_wait;
17365 ep_3550->serial_number_word1 =
17366 adv_dvc_varp->cfg->serial1;
17367 ep_3550->serial_number_word2 =
17368 adv_dvc_varp->cfg->serial2;
17369 ep_3550->serial_number_word3 =
17370 adv_dvc_varp->cfg->serial3;
17371 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17372 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
17373
17374 ep_38C0800->adapter_scsi_id =
17375 adv_dvc_varp->chip_scsi_id;
17376 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
17377 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17378 ep_38C0800->termination_lvd =
17379 adv_dvc_varp->cfg->termination;
17380 ep_38C0800->disc_enable =
17381 adv_dvc_varp->cfg->disc_enable;
17382 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
17383 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
17384 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
17385 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
17386 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
17387 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
17388 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
17389 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
17390 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
17391 ep_38C0800->scsi_reset_delay =
17392 adv_dvc_varp->scsi_reset_wait;
17393 ep_38C0800->serial_number_word1 =
17394 adv_dvc_varp->cfg->serial1;
17395 ep_38C0800->serial_number_word2 =
17396 adv_dvc_varp->cfg->serial2;
17397 ep_38C0800->serial_number_word3 =
17398 adv_dvc_varp->cfg->serial3;
17399 } else {
17400 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
17401
17402 ep_38C1600->adapter_scsi_id =
17403 adv_dvc_varp->chip_scsi_id;
17404 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
17405 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17406 ep_38C1600->termination_lvd =
17407 adv_dvc_varp->cfg->termination;
17408 ep_38C1600->disc_enable =
17409 adv_dvc_varp->cfg->disc_enable;
17410 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
17411 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
17412 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
17413 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
17414 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
17415 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
17416 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
17417 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
17418 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
17419 ep_38C1600->scsi_reset_delay =
17420 adv_dvc_varp->scsi_reset_wait;
17421 ep_38C1600->serial_number_word1 =
17422 adv_dvc_varp->cfg->serial1;
17423 ep_38C1600->serial_number_word2 =
17424 adv_dvc_varp->cfg->serial2;
17425 ep_38C1600->serial_number_word3 =
17426 adv_dvc_varp->cfg->serial3;
17427 }
17428
17429 /*
17430 * Set the adapter's target id bit in the 'init_tidmask' field.
17431 */
17432 boardp->init_tidmask |=
17433 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
27c868c2
MW
17434 }
17435
17436 /*
17437 * Channels are numbered beginning with 0. For AdvanSys one host
17438 * structure supports one channel. Multi-channel boards have a
17439 * separate host structure for each channel.
17440 */
17441 shost->max_channel = 0;
17442 if (ASC_NARROW_BOARD(boardp)) {
17443 shost->max_id = ASC_MAX_TID + 1;
17444 shost->max_lun = ASC_MAX_LUN + 1;
17445
17446 shost->io_port = asc_dvc_varp->iop_base;
17447 boardp->asc_n_io_port = ASC_IOADR_GAP;
17448 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
17449
17450 /* Set maximum number of queues the adapter can handle. */
17451 shost->can_queue = asc_dvc_varp->max_total_qng;
17452 } else {
17453 shost->max_id = ADV_MAX_TID + 1;
17454 shost->max_lun = ADV_MAX_LUN + 1;
17455
17456 /*
17457 * Save the I/O Port address and length even though
17458 * I/O ports are not used to access Wide boards.
17459 * Instead the Wide boards are accessed with
17460 * PCI Memory Mapped I/O.
17461 */
17462 shost->io_port = iop;
27c868c2
MW
17463
17464 shost->this_id = adv_dvc_varp->chip_scsi_id;
17465
17466 /* Set maximum number of queues the adapter can handle. */
17467 shost->can_queue = adv_dvc_varp->max_host_qng;
17468 }
17469
27c868c2
MW
17470 /*
17471 * Following v1.3.89, 'cmd_per_lun' is no longer needed
17472 * and should be set to zero.
17473 *
17474 * But because of a bug introduced in v1.3.89 if the driver is
17475 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
17476 * SCSI function 'allocate_device' will panic. To allow the driver
17477 * to work as a module in these kernels set 'cmd_per_lun' to 1.
17478 *
17479 * Note: This is wrong. cmd_per_lun should be set to the depth
17480 * you want on untagged devices always.
17481 #ifdef MODULE
17482 */
17483 shost->cmd_per_lun = 1;
17484/* #else
17485 shost->cmd_per_lun = 0;
17486#endif */
17487
17488 /*
17489 * Set the maximum number of scatter-gather elements the
17490 * adapter can handle.
17491 */
17492 if (ASC_NARROW_BOARD(boardp)) {
17493 /*
17494 * Allow two commands with 'sg_tablesize' scatter-gather
17495 * elements to be executed simultaneously. This value is
17496 * the theoretical hardware limit. It may be decreased
17497 * below.
17498 */
17499 shost->sg_tablesize =
17500 (((asc_dvc_varp->max_total_qng - 2) / 2) *
17501 ASC_SG_LIST_PER_Q) + 1;
17502 } else {
17503 shost->sg_tablesize = ADV_MAX_SG_LIST;
17504 }
17505
17506 /*
17507 * The value of 'sg_tablesize' can not exceed the SCSI
17508 * mid-level driver definition of SG_ALL. SG_ALL also
17509 * must not be exceeded, because it is used to define the
17510 * size of the scatter-gather table in 'struct asc_sg_head'.
17511 */
17512 if (shost->sg_tablesize > SG_ALL) {
17513 shost->sg_tablesize = SG_ALL;
17514 }
17515
17516 ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize);
17517
17518 /* BIOS start address. */
17519 if (ASC_NARROW_BOARD(boardp)) {
b2c16f58
MW
17520 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
17521 asc_dvc_varp->bus_type);
27c868c2
MW
17522 } else {
17523 /*
17524 * Fill-in BIOS board variables. The Wide BIOS saves
17525 * information in LRAM that is used by the driver.
17526 */
17527 AdvReadWordLram(adv_dvc_varp->iop_base,
17528 BIOS_SIGNATURE, boardp->bios_signature);
17529 AdvReadWordLram(adv_dvc_varp->iop_base,
17530 BIOS_VERSION, boardp->bios_version);
17531 AdvReadWordLram(adv_dvc_varp->iop_base,
17532 BIOS_CODESEG, boardp->bios_codeseg);
17533 AdvReadWordLram(adv_dvc_varp->iop_base,
17534 BIOS_CODELEN, boardp->bios_codelen);
17535
17536 ASC_DBG2(1,
17537 "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n",
17538 boardp->bios_signature, boardp->bios_version);
17539
17540 ASC_DBG2(1,
17541 "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n",
17542 boardp->bios_codeseg, boardp->bios_codelen);
17543
17544 /*
17545 * If the BIOS saved a valid signature, then fill in
17546 * the BIOS code segment base address.
17547 */
17548 if (boardp->bios_signature == 0x55AA) {
17549 /*
17550 * Convert x86 realmode code segment to a linear
17551 * address by shifting left 4.
17552 */
17553 shost->base = ((ulong)boardp->bios_codeseg << 4);
17554 } else {
17555 shost->base = 0;
17556 }
17557 }
17558
17559 /*
17560 * Register Board Resources - I/O Port, DMA, IRQ
17561 */
17562
27c868c2
MW
17563 /* Register DMA Channel for Narrow boards. */
17564 shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
17565#ifdef CONFIG_ISA
17566 if (ASC_NARROW_BOARD(boardp)) {
17567 /* Register DMA channel for ISA bus. */
17568 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
17569 shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
b2c16f58
MW
17570 ret = request_dma(shost->dma_channel, "advansys");
17571 if (ret) {
27c868c2
MW
17572 ASC_PRINT3
17573 ("advansys_board_found: board %d: request_dma() %d failed %d\n",
17574 boardp->id, shost->dma_channel, ret);
71f36115 17575 goto err_free_proc;
27c868c2
MW
17576 }
17577 AscEnableIsaDma(shost->dma_channel);
17578 }
17579 }
17580#endif /* CONFIG_ISA */
17581
17582 /* Register IRQ Number. */
17583 ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq);
074c8fe4
MW
17584
17585 ret = request_irq(shost->irq, advansys_interrupt, share_irq,
17586 "advansys", shost);
17587
17588 if (ret) {
27c868c2
MW
17589 if (ret == -EBUSY) {
17590 ASC_PRINT2
17591 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
17592 boardp->id, shost->irq);
17593 } else if (ret == -EINVAL) {
17594 ASC_PRINT2
17595 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
17596 boardp->id, shost->irq);
17597 } else {
17598 ASC_PRINT3
17599 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
17600 boardp->id, shost->irq, ret);
17601 }
b2c16f58 17602 goto err_free_dma;
27c868c2
MW
17603 }
17604
17605 /*
17606 * Initialize board RISC chip and enable interrupts.
17607 */
17608 if (ASC_NARROW_BOARD(boardp)) {
17609 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
17610 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
17611 err_code = asc_dvc_varp->err_code;
17612
17613 if (warn_code || err_code) {
17614 ASC_PRINT4
17615 ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
17616 boardp->id,
17617 asc_dvc_varp->init_state, warn_code, err_code);
17618 }
17619 } else {
b2c16f58 17620 err_code = advansys_wide_init_chip(boardp, adv_dvc_varp);
27c868c2
MW
17621 }
17622
b2c16f58
MW
17623 if (err_code != 0)
17624 goto err_free_wide_mem;
17625
27c868c2
MW
17626 ASC_DBG_PRT_SCSI_HOST(2, shost);
17627
8dfb5379
MW
17628 ret = scsi_add_host(shost, dev);
17629 if (ret)
17630 goto err_free_wide_mem;
17631
17632 scsi_scan_host(shost);
27c868c2 17633 return shost;
b2c16f58
MW
17634
17635 err_free_wide_mem:
17636 advansys_wide_free_mem(boardp);
17637 free_irq(shost->irq, shost);
17638 err_free_dma:
17639 if (shost->dma_channel != NO_ISA_DMA)
17640 free_dma(shost->dma_channel);
b2c16f58
MW
17641 err_free_proc:
17642 kfree(boardp->prtbuf);
17643 err_unmap:
17644 if (boardp->ioremap_addr)
17645 iounmap(boardp->ioremap_addr);
17646 err_shost:
8dfb5379 17647 scsi_host_put(shost);
b2c16f58 17648 return NULL;
27c868c2
MW
17649}
17650
27c868c2
MW
17651/*
17652 * advansys_release()
17653 *
17654 * Release resources allocated for a single AdvanSys adapter.
17655 */
17656static int advansys_release(struct Scsi_Host *shost)
17657{
17658 asc_board_t *boardp;
17659
17660 ASC_DBG(1, "advansys_release: begin\n");
8dfb5379 17661 scsi_remove_host(shost);
27c868c2 17662 boardp = ASC_BOARDP(shost);
074c8fe4 17663 free_irq(shost->irq, shost);
27c868c2
MW
17664 if (shost->dma_channel != NO_ISA_DMA) {
17665 ASC_DBG(1, "advansys_release: free_dma()\n");
17666 free_dma(shost->dma_channel);
17667 }
27c868c2 17668 if (ASC_WIDE_BOARD(boardp)) {
27c868c2 17669 iounmap(boardp->ioremap_addr);
b2c16f58 17670 advansys_wide_free_mem(boardp);
27c868c2 17671 }
27c868c2 17672 kfree(boardp->prtbuf);
8dfb5379 17673 scsi_host_put(shost);
27c868c2
MW
17674 ASC_DBG(1, "advansys_release: end\n");
17675 return 0;
17676}
17677
c304ec94
MW
17678static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
17679 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
17680 0x0210, 0x0230, 0x0250, 0x0330
17681};
17682
17683static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
17684{
17685 PortAddr iop_base = _asc_def_iop_base[id];
17686 struct Scsi_Host *shost;
17687
17688 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
71f36115
MW
17689 ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n",
17690 iop_base);
c304ec94
MW
17691 return -ENODEV;
17692 }
17693 ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base);
c304ec94
MW
17694 if (!AscFindSignature(iop_base))
17695 goto nodev;
17696 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
17697 goto nodev;
17698
17699 shost = advansys_board_found(iop_base, dev, ASC_IS_ISA);
c304ec94
MW
17700 if (!shost)
17701 goto nodev;
17702
17703 dev_set_drvdata(dev, shost);
17704 return 0;
17705
17706 nodev:
71f36115 17707 release_region(iop_base, ASC_IOADR_GAP);
c304ec94
MW
17708 return -ENODEV;
17709}
17710
17711static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
17712{
71f36115 17713 int ioport = _asc_def_iop_base[id];
c304ec94 17714 advansys_release(dev_get_drvdata(dev));
71f36115 17715 release_region(ioport, ASC_IOADR_GAP);
c304ec94
MW
17716 return 0;
17717}
17718
17719static struct isa_driver advansys_isa_driver = {
17720 .probe = advansys_isa_probe,
17721 .remove = __devexit_p(advansys_isa_remove),
17722 .driver = {
17723 .owner = THIS_MODULE,
17724 .name = "advansys",
17725 },
17726};
17727
17728static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
17729{
17730 PortAddr iop_base = _asc_def_iop_base[id];
17731 struct Scsi_Host *shost;
17732
17733 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
71f36115
MW
17734 ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n",
17735 iop_base);
c304ec94
MW
17736 return -ENODEV;
17737 }
17738 ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base);
c304ec94
MW
17739 if (!AscFindSignature(iop_base))
17740 goto nodev;
17741 /*
17742 * I don't think this condition can actually happen, but the old
17743 * driver did it, and the chances of finding a VLB setup in 2007
17744 * to do testing with is slight to none.
17745 */
17746 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
17747 goto nodev;
17748
17749 shost = advansys_board_found(iop_base, dev, ASC_IS_VL);
c304ec94
MW
17750 if (!shost)
17751 goto nodev;
17752
17753 dev_set_drvdata(dev, shost);
17754 return 0;
17755
17756 nodev:
71f36115 17757 release_region(iop_base, ASC_IOADR_GAP);
c304ec94
MW
17758 return -ENODEV;
17759}
17760
17761static struct isa_driver advansys_vlb_driver = {
17762 .probe = advansys_vlb_probe,
17763 .remove = __devexit_p(advansys_isa_remove),
17764 .driver = {
17765 .owner = THIS_MODULE,
17766 .name = "advansys",
17767 },
17768};
17769
b09e05a7
MW
17770static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
17771 { "ABP7401" },
17772 { "ABP7501" },
17773 { "" }
17774};
17775
17776MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
17777
17778/*
17779 * EISA is a little more tricky than PCI; each EISA device may have two
17780 * channels, and this driver is written to make each channel its own Scsi_Host
17781 */
17782struct eisa_scsi_data {
17783 struct Scsi_Host *host[2];
17784};
17785
17786static int __devinit advansys_eisa_probe(struct device *dev)
17787{
17788 int i, ioport;
17789 int err;
17790 struct eisa_device *edev = to_eisa_device(dev);
17791 struct eisa_scsi_data *data;
17792
17793 err = -ENOMEM;
17794 data = kzalloc(sizeof(*data), GFP_KERNEL);
17795 if (!data)
17796 goto fail;
17797 ioport = edev->base_addr + 0xc30;
17798
17799 err = -ENODEV;
17800 for (i = 0; i < 2; i++, ioport += 0x20) {
71f36115
MW
17801 if (!request_region(ioport, ASC_IOADR_GAP, "advansys")) {
17802 printk(KERN_WARNING "Region %x-%x busy\n", ioport,
17803 ioport + ASC_IOADR_GAP - 1);
17804 continue;
17805 }
17806 if (!AscFindSignature(ioport)) {
17807 release_region(ioport, ASC_IOADR_GAP);
b09e05a7 17808 continue;
71f36115
MW
17809 }
17810
b09e05a7
MW
17811 /*
17812 * I don't know why we need to do this for EISA chips, but
17813 * not for any others. It looks to be equivalent to
17814 * AscGetChipCfgMsw, but I may have overlooked something,
17815 * so I'm not converting it until I get an EISA board to
17816 * test with.
17817 */
17818 inw(ioport + 4);
17819 data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA);
71f36115 17820 if (data->host[i]) {
b09e05a7 17821 err = 0;
71f36115
MW
17822 } else {
17823 release_region(ioport, ASC_IOADR_GAP);
17824 }
b09e05a7
MW
17825 }
17826
17827 if (err) {
17828 kfree(data);
17829 } else {
17830 dev_set_drvdata(dev, data);
17831 }
17832
17833 fail:
17834 return err;
17835}
17836
17837static __devexit int advansys_eisa_remove(struct device *dev)
17838{
17839 int i;
17840 struct eisa_scsi_data *data = dev_get_drvdata(dev);
17841
17842 for (i = 0; i < 2; i++) {
71f36115 17843 int ioport;
b09e05a7
MW
17844 struct Scsi_Host *shost = data->host[i];
17845 if (!shost)
17846 continue;
71f36115 17847 ioport = shost->io_port;
b09e05a7 17848 advansys_release(shost);
71f36115 17849 release_region(ioport, ASC_IOADR_GAP);
b09e05a7
MW
17850 }
17851
17852 kfree(data);
17853 return 0;
17854}
17855
17856static struct eisa_driver advansys_eisa_driver = {
17857 .id_table = advansys_eisa_table,
17858 .driver = {
17859 .name = "advansys",
17860 .probe = advansys_eisa_probe,
17861 .remove = __devexit_p(advansys_eisa_remove),
17862 }
17863};
17864
2672ea86
DJ
17865/* PCI Devices supported by this driver */
17866static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
27c868c2
MW
17867 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
17868 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17869 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
17870 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17871 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
17872 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17873 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
17874 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17875 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
17876 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17877 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
17878 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
17879 {}
2672ea86 17880};
27c868c2 17881
2672ea86 17882MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
78e77d8b 17883
9649af39
MW
17884static void __devinit advansys_set_latency(struct pci_dev *pdev)
17885{
17886 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
17887 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
17888 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
17889 } else {
17890 u8 latency;
17891 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
17892 if (latency < 0x20)
17893 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
17894 }
17895}
17896
78e77d8b
MW
17897static int __devinit
17898advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
17899{
17900 int err, ioport;
17901 struct Scsi_Host *shost;
17902
17903 err = pci_enable_device(pdev);
17904 if (err)
17905 goto fail;
71f36115
MW
17906 err = pci_request_regions(pdev, "advansys");
17907 if (err)
17908 goto disable_device;
9649af39
MW
17909 pci_set_master(pdev);
17910 advansys_set_latency(pdev);
78e77d8b
MW
17911
17912 if (pci_resource_len(pdev, 0) == 0)
17913 goto nodev;
17914
17915 ioport = pci_resource_start(pdev, 0);
17916 shost = advansys_board_found(ioport, &pdev->dev, ASC_IS_PCI);
17917
17918 if (!shost)
17919 goto nodev;
17920
17921 pci_set_drvdata(pdev, shost);
17922 return 0;
17923
17924 nodev:
17925 err = -ENODEV;
71f36115
MW
17926 pci_release_regions(pdev);
17927 disable_device:
78e77d8b
MW
17928 pci_disable_device(pdev);
17929 fail:
17930 return err;
17931}
17932
17933static void __devexit advansys_pci_remove(struct pci_dev *pdev)
17934{
17935 advansys_release(pci_get_drvdata(pdev));
71f36115 17936 pci_release_regions(pdev);
78e77d8b
MW
17937 pci_disable_device(pdev);
17938}
17939
17940static struct pci_driver advansys_pci_driver = {
17941 .name = "advansys",
17942 .id_table = advansys_pci_tbl,
17943 .probe = advansys_pci_probe,
17944 .remove = __devexit_p(advansys_pci_remove),
17945};
8c6af9e1 17946
8dfb5379
MW
17947static int __init advansys_init(void)
17948{
c304ec94 17949 int error;
b09e05a7 17950
c304ec94
MW
17951 error = isa_register_driver(&advansys_isa_driver,
17952 ASC_IOADR_TABLE_MAX_IX);
78e77d8b
MW
17953 if (error)
17954 goto fail;
8dfb5379 17955
c304ec94
MW
17956 error = isa_register_driver(&advansys_vlb_driver,
17957 ASC_IOADR_TABLE_MAX_IX);
17958 if (error)
17959 goto unregister_isa;
17960
17961 error = eisa_driver_register(&advansys_eisa_driver);
17962 if (error)
17963 goto unregister_vlb;
17964
b09e05a7
MW
17965 error = pci_register_driver(&advansys_pci_driver);
17966 if (error)
17967 goto unregister_eisa;
17968
8dfb5379 17969 return 0;
78e77d8b 17970
b09e05a7
MW
17971 unregister_eisa:
17972 eisa_driver_unregister(&advansys_eisa_driver);
c304ec94
MW
17973 unregister_vlb:
17974 isa_unregister_driver(&advansys_vlb_driver);
17975 unregister_isa:
17976 isa_unregister_driver(&advansys_isa_driver);
78e77d8b 17977 fail:
78e77d8b 17978 return error;
8dfb5379
MW
17979}
17980
17981static void __exit advansys_exit(void)
17982{
78e77d8b 17983 pci_unregister_driver(&advansys_pci_driver);
b09e05a7 17984 eisa_driver_unregister(&advansys_eisa_driver);
c304ec94
MW
17985 isa_unregister_driver(&advansys_vlb_driver);
17986 isa_unregister_driver(&advansys_isa_driver);
8dfb5379
MW
17987}
17988
17989module_init(advansys_init);
17990module_exit(advansys_exit);
17991
8c6af9e1 17992MODULE_LICENSE("GPL");
This page took 1.294534 seconds and 5 git commands to generate.